@currents/cmd 2.1.0 → 2.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1,12 +1,12 @@
1
- "use strict";var Or=Object.create;var K=Object.defineProperty;var Sr=Object.getOwnPropertyDescriptor;var yr=Object.getOwnPropertyNames;var Nr=Object.getPrototypeOf,Lr=Object.prototype.hasOwnProperty;var Bt=(t,e)=>{for(var r in e)K(t,r,{get:e[r],enumerable:!0})},Pt=(t,e,r,n)=>{if(e&&typeof e=="object"||typeof e=="function")for(let o of yr(e))!Lr.call(t,o)&&o!==r&&K(t,o,{get:()=>e[o],enumerable:!(n=Sr(e,o))||n.enumerable});return t};var u=(t,e,r)=>(r=t!=null?Or(Nr(t)):{},Pt(e||!t||!t.__esModule?K(r,"default",{value:t,enumerable:!0}):r,t)),xr=t=>Pt(K({},"__esModule",{value:!0}),t);var uo={};Bt(uo,{handleCurrentsReport:()=>hr});module.exports=xr(uo);var wt=require("debug"),Br=u(require("fs-extra")),a=(0,wt.debug)("currents"),Pr=null;function Mt(t){Pr=t}var J={};Bt(J,{getNanoid:()=>wr,userFacingNanoid:()=>Et});var lt=require("nanoid"),bt="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz",wr=(t=16)=>(0,lt.customAlphabet)(bt,t)(),Et=(0,lt.customAlphabet)(bt,12);var d=require("lodash");function vt(t){return t.replace(/^([a-z][a-z0-9+.-]*:\/\/)[^/?#\s]*@/i,"$1")}var Y=a.extend("ci"),Mr=(t,e)=>(0,d.set)(t,(0,d.camelCase)(e),process.env[e]),_=t=>(0,d.transform)(t,Mr,{}),br=()=>process.env.TF_BUILD&&process.env.AZURE_HTTP_USER_AGENT,vr=()=>(0,d.some)(process.env,(t,e)=>/^CODEBUILD_/.test(e)),Fr=()=>process.env.bamboo_buildNumber,Gr=()=>(0,d.some)(process.env,(t,e)=>/^CONCOURSE_/.test(e)),kr=()=>process.env.GITLAB_CI||process.env.CI_SERVER_NAME&&/^GitLab/.test(process.env.CI_SERVER_NAME),Hr=()=>!!(process.env.BUILD_ID&&process.env.PROJECT_ID&&process.env.PROJECT_NUMBER||process.env.GCP_PROJECT||process.env.GCLOUD_PROJECT||process.env.GOOGLE_CLOUD_PROJECT),jr=()=>process.env.JENKINS_URL||process.env.JENKINS_HOME||process.env.JENKINS_VERSION||process.env.HUDSON_URL||process.env.HUDSON_HOME,Kr={appveyor:"APPVEYOR",azure:br,awsCodeBuild:vr,bamboo:Fr,bitbucket:"BITBUCKET_BUILD_NUMBER",buildkite:"BUILDKITE",circle:"CIRCLECI",concourse:Gr,codeFresh:"CF_BUILD_ID",drone:"DRONE",githubActions:"GITHUB_ACTIONS",gitlab:kr,goCD:"GO_JOB_NAME",jenkins:jr,googleCloud:Hr,semaphore:"SEMAPHORE",teamcity:"TEAMCITY_VERSION",travis:"TRAVIS",netlify:"NETLIFY"};function Jr(){let{env:t}=process;return(0,d.findKey)(Kr,e=>{if((0,d.isString)(e))return t[e];if((0,d.isFunction)(e))return e()})}var Ft=()=>({appveyor:_(["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:_(["AGENT_BUILDDIRECTORY","AGENT_ID","AGENT_JOBNAME","AGENT_JOBSTATUS","AGENT_MACHINENAME","AGENT_NAME","AGENT_OS","AGENT_OSARCHITECTURE","BUILD_BUILDID","BUILD_BUILDNUMBER","BUILD_BUILDURI","BUILD_CONTAINERID","BUILD_CRONSCHEDULE_DISPLAYNAME","BUILD_DEFINITIONNAME","BUILD_DEFINITIONVERSION","BUILD_QUEUEDBY","BUILD_QUEUEDBYID","BUILD_REASON","BUILD_REPOSITORY_ID","BUILD_REPOSITORY_NAME","BUILD_REPOSITORY_PROVIDER","BUILD_REPOSITORY_URI","BUILD_REQUESTEDFOR","BUILD_REQUESTEDFOREMAIL","BUILD_REQUESTEDFORID","BUILD_SOURCEBRANCH","BUILD_SOURCEBRANCHNAME","BUILD_SOURCESDIRECTORY","BUILD_SOURCEVERSION","BUILD_SOURCEVERSIONAUTHOR","BUILD_SOURCEVERSIONMESSAGE","BUILD_STAGINGDIRECTORY","BUILD_TRIGGEREDBY_BUILDID","BUILD_TRIGGEREDBY_BUILDNUMBER","BUILD_TRIGGEREDBY_DEFINITIONID","BUILD_TRIGGEREDBY_DEFINITIONNAME","BUILD_TRIGGEREDBY_PROJECTID","COMMON_TESTRESULTSDIRECTORY","PIPELINE_WORKSPACE","SYSTEM_COLLECTIONID","SYSTEM_COLLECTIONURI","SYSTEM_DEFAULTWORKINGDIRECTORY","SYSTEM_DEFINITIONID","SYSTEM_HOSTTYPE","SYSTEM_JOBATTEMPT","SYSTEM_JOBDISPLAYNAME","SYSTEM_JOBID","SYSTEM_JOBNAME","SYSTEM_PHASEATTEMPT","SYSTEM_PHASEDISPLAYNAME","SYSTEM_PHASENAME","SYSTEM_PLANID","SYSTEM_PULLREQUEST_ISFORK","SYSTEM_PULLREQUEST_PULLREQUESTID","SYSTEM_PULLREQUEST_PULLREQUESTNUMBER","SYSTEM_PULLREQUEST_SOURCEREPOSITORYURI","SYSTEM_PULLREQUEST_SOURCEBRANCH","SYSTEM_PULLREQUEST_SOURCECOMMITID","SYSTEM_PULLREQUEST_TARGETBRANCH","SYSTEM_PULLREQUEST_TARGETBRANCHNAME","SYSTEM_STAGEATTEMPT","SYSTEM_STAGEDISPLAYNAME","SYSTEM_STAGENAME","SYSTEM_TEAMFOUNDATIONCOLLECTIONURI","SYSTEM_TEAMPROJECT","SYSTEM_TEAMPROJECTID","SYSTEM_TIMELINEID"]),awsCodeBuild:_(["AWS_DEFAULT_REGION","AWS_REGION","CODEBUILD_BATCH_BUILD_IDENTIFIER","CODEBUILD_BUILD_ARN","CODEBUILD_BUILD_ID","CODEBUILD_BUILD_IMAGE","CODEBUILD_BUILD_NUMBER","CODEBUILD_BUILD_SUCCEEDING","CODEBUILD_BUILD_URL","CODEBUILD_INITIATOR","CODEBUILD_PROJECT_ARN","CODEBUILD_PUBLIC_BUILD_URL","CODEBUILD_RESOLVED_SOURCE_VERSION","CODEBUILD_SOURCE_REPO_URL","CODEBUILD_SOURCE_VERSION","CODEBUILD_SRC_DIR","CODEBUILD_START_TIME","CODEBUILD_WEBHOOK_ACTOR_ACCOUNT_ID","CODEBUILD_WEBHOOK_BASE_REF","CODEBUILD_WEBHOOK_EVENT","CODEBUILD_WEBHOOK_HEAD_REF","CODEBUILD_WEBHOOK_MERGE_COMMIT","CODEBUILD_WEBHOOK_PREV_COMMIT","CODEBUILD_WEBHOOK_TRIGGER","CODEBUILD_WEBHOOK_LABEL","CODEBUILD_WEBHOOK_RUN_ID","CODEBUILD_WEBHOOK_JOB_ID","CODEBUILD_WEBHOOK_WORKFLOW_NAME","CODEBUILD_RUNNER_OWNER","CODEBUILD_RUNNER_REPO","CODEBUILD_RUNNER_REPO_DOMAIN","CODEBUILD_RUNNER_WITH_BUILDSPEC"]),bamboo:_(["bamboo_buildNumber","bamboo_buildResultsUrl","bamboo_planRepository_repositoryUrl","bamboo_buildKey"]),bitbucket:_(["CI","BITBUCKET_WORKSPACE","BITBUCKET_REPO_SLUG","BITBUCKET_REPO_UUID","BITBUCKET_REPO_FULL_NAME","BITBUCKET_REPO_IS_PRIVATE","BITBUCKET_REPO_OWNER","BITBUCKET_REPO_OWNER_UUID","BITBUCKET_PROJECT_KEY","BITBUCKET_PROJECT_UUID","BITBUCKET_BUILD_NUMBER","BITBUCKET_PIPELINE_UUID","BITBUCKET_STEP_UUID","BITBUCKET_STEP_RUN_NUMBER","BITBUCKET_STEP_TRIGGERER_UUID","BITBUCKET_PARALLEL_STEP","BITBUCKET_PARALLEL_STEP_COUNT","BITBUCKET_CLONE_DIR","BITBUCKET_COMMIT","BITBUCKET_BRANCH","BITBUCKET_TAG","BITBUCKET_BOOKMARK","BITBUCKET_GIT_HTTP_ORIGIN","BITBUCKET_GIT_SSH_ORIGIN","BITBUCKET_PR_ID","BITBUCKET_PR_DESTINATION_BRANCH","BITBUCKET_PR_DESTINATION_COMMIT","BITBUCKET_DEPLOYMENT_ENVIRONMENT","BITBUCKET_DEPLOYMENT_ENVIRONMENT_UUID","BITBUCKET_EXIT_CODE"]),buildkite:_(["BUILDKITE_ORGANIZATION_SLUG","BUILDKITE_PIPELINE_ID","BUILDKITE_PIPELINE_NAME","BUILDKITE_PIPELINE_SLUG","BUILDKITE_PIPELINE_DEFAULT_BRANCH","BUILDKITE_REPO","BUILDKITE_SOURCE","BUILDKITE_BRANCH","BUILDKITE_TAG","BUILDKITE_COMMIT","BUILDKITE_MESSAGE","BUILDKITE_BUILD_AUTHOR","BUILDKITE_BUILD_AUTHOR_EMAIL","BUILDKITE_JOB_ID","BUILDKITE_BUILD_ID","BUILDKITE_BUILD_URL","BUILDKITE_BUILD_NUMBER","BUILDKITE_LABEL","BUILDKITE_COMMAND","BUILDKITE_STEP_ID","BUILDKITE_STEP_KEY","BUILDKITE_PARALLEL_JOB","BUILDKITE_PARALLEL_JOB_COUNT","BUILDKITE_RETRY_COUNT","BUILDKITE_COMPUTE_TYPE","BUILDKITE_CLUSTER_NAME","BUILDKITE_PULL_REQUEST","BUILDKITE_PULL_REQUEST_REPO","BUILDKITE_PULL_REQUEST_BASE_BRANCH","BUILDKITE_PULL_REQUEST_DRAFT","BUILDKITE_PULL_REQUEST_LABELS","BUILDKITE_MERGE_QUEUE_BASE_BRANCH","BUILDKITE_MERGE_QUEUE_BASE_COMMIT","BUILDKITE_REBUILT_FROM_BUILD_ID","BUILDKITE_REBUILT_FROM_BUILD_NUMBER","BUILDKITE_TRIGGERED_FROM_BUILD_ID","BUILDKITE_TRIGGERED_FROM_BUILD_NUMBER","BUILDKITE_TRIGGERED_FROM_BUILD_PIPELINE_SLUG"]),circle:_(["CI","CIRCLECI","CIRCLE_BRANCH","CIRCLE_BUILD_NUM","CIRCLE_BUILD_URL","CIRCLE_PREVIOUS_BUILD_NUM","CIRCLE_JOB","CIRCLE_WORKFLOW_ID","CIRCLE_WORKFLOW_JOB_ID","CIRCLE_WORKFLOW_WORKSPACE_ID","CIRCLE_PIPELINE_ID","CIRCLE_ORGANIZATION_ID","CIRCLE_PROJECT_ID","CIRCLE_PROJECT_REPONAME","CIRCLE_PROJECT_USERNAME","CIRCLE_REPOSITORY_URL","CIRCLE_WORKING_DIRECTORY","CIRCLE_SHA1","CIRCLE_TAG","CIRCLE_USERNAME","CIRCLE_NODE_INDEX","CIRCLE_NODE_TOTAL","CIRCLE_PR_NUMBER","CIRCLE_PR_REPONAME","CIRCLE_PR_USERNAME","CIRCLE_PULL_REQUEST","CIRCLE_PULL_REQUESTS","CI_PULL_REQUEST"]),concourse:_(["BUILD_ID","BUILD_NAME","BUILD_JOB_NAME","BUILD_PIPELINE_NAME","BUILD_TEAM_NAME","ATC_EXTERNAL_URL"]),codeFresh:_(["CF_BUILD_ID","CF_BUILD_URL","CF_CURRENT_ATTEMPT","CF_STEP_NAME","CF_PIPELINE_NAME","CF_PIPELINE_TRIGGER_ID","CF_PULL_REQUEST_ID","CF_PULL_REQUEST_IS_FORK","CF_PULL_REQUEST_NUMBER","CF_PULL_REQUEST_TARGET"]),drone:_(["DRONE_BUILD_LINK","DRONE_BUILD_NUMBER","DRONE_PULL_REQUEST"]),githubActions:_(["CI","GITHUB_ACTIONS","GITHUB_WORKFLOW","GITHUB_WORKFLOW_REF","GITHUB_WORKFLOW_SHA","GITHUB_ACTION","GITHUB_ACTION_PATH","GITHUB_ACTION_REPOSITORY","GITHUB_JOB","GITHUB_EVENT_NAME","GITHUB_EVENT_PATH","GITHUB_RUN_ID","GITHUB_RUN_NUMBER","GITHUB_RUN_ATTEMPT","GITHUB_REPOSITORY","GITHUB_REPOSITORY_ID","GITHUB_REPOSITORY_OWNER","GITHUB_REPOSITORY_OWNER_ID","GITHUB_REF","GITHUB_REF_NAME","GITHUB_REF_TYPE","GITHUB_REF_PROTECTED","GITHUB_BASE_REF","GITHUB_HEAD_REF","GITHUB_SHA","GITHUB_ACTOR","GITHUB_ACTOR_ID","GITHUB_TRIGGERING_ACTOR","GITHUB_SERVER_URL","GITHUB_API_URL","GITHUB_GRAPHQL_URL","GITHUB_WORKSPACE","GITHUB_RETENTION_DAYS","RUNNER_OS","RUNNER_ARCH","RUNNER_NAME","RUNNER_ENVIRONMENT","RUNNER_DEBUG"]),gitlab:_(["CI_PIPELINE_ID","CI_PIPELINE_URL","CI_BUILD_ID","CI_JOB_ID","CI_JOB_URL","CI_JOB_NAME","CI_NODE_INDEX","CI_NODE_TOTAL","GITLAB_HOST","CI_PROJECT_ID","CI_PROJECT_URL","CI_REPOSITORY_URL","CI_ENVIRONMENT_URL","CI_DEFAULT_BRANCH","RUN_ATTEMPT","CI_MERGE_REQUEST_IID","CI_MERGE_REQUEST_PROJECT_URL","CI_MERGE_REQUEST_TITLE","CI_MERGE_REQUEST_SOURCE_BRANCH_NAME","CI_MERGE_REQUEST_TARGET_BRANCH_NAME","CI_OPEN_MERGE_REQUESTS"]),goCD:_(["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:_(["BUILD_ID","PROJECT_ID","REPO_NAME","BRANCH_NAME","TAG_NAME","COMMIT_SHA","SHORT_SHA"]),jenkins:_(["BRANCH_NAME","BUILD_DISPLAY_NAME","BUILD_ID","BUILD_NUMBER","BUILD_TAG","BUILD_URL","CHANGE_AUTHOR","CHANGE_AUTHOR_DISPLAY_NAME","CHANGE_AUTHOR_EMAIL","CHANGE_BRANCH","CHANGE_FORK","CHANGE_ID","CHANGE_TARGET","CHANGE_TITLE","CHANGE_URL","CI","EXECUTOR_NUMBER","JAVA_HOME","JENKINS_HOME","JENKINS_URL","JOB_BASE_NAME","JOB_NAME","JOB_URL","NODE_LABELS","NODE_NAME","RUN_ARTIFACTS_DISPLAY_URL","RUN_CHANGES_DISPLAY_URL","TAG_NAME","WORKSPACE","WORKSPACE_TMP","GIT_AUTHOR_EMAIL","GIT_AUTHOR_NAME","GIT_BRANCH","GIT_COMMIT","GIT_COMMITTER_EMAIL","GIT_COMMITTER_NAME","GIT_LOCAL_BRANCH","GIT_PREVIOUS_COMMIT","GIT_PREVIOUS_SUCCESSFUL_COMMIT","GIT_URL","ghprbActualCommit","ghprbGhRepository","ghprbPullId","ghprbPullLink","ghprbSourceBranch","ghprbTargetBranch","ghprbTriggerAuthorLogin"]),semaphore:_(["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","SEMAPHORE_JOB_NAME","SEMAPHORE_JOB_UUID","SEMAPHORE_PIPELINE_ID","SEMAPHORE_PLATFORM","SEMAPHORE_PROJECT_DIR","SEMAPHORE_PROJECT_HASH_ID","SEMAPHORE_PROJECT_ID","SEMAPHORE_PROJECT_NAME","SEMAPHORE_PROJECT_UUID","SEMAPHORE_REPO_SLUG","SEMAPHORE_TRIGGER_SOURCE","SEMAPHORE_WORKFLOW_ID","PULL_REQUEST_NUMBER"]),teamcity:null,travis:_(["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"]),netlify:_(["BUILD_ID","CONTEXT","URL","DEPLOY_URL","DEPLOY_PRIME_URL","DEPLOY_ID"])}),Yr=t=>{let e=Gt();return e?(0,d.chain)(t()).get(e).value():{}};function $r(){return(0,d.chain)(Ft()).omitBy(d.isNull).keys().value()}function Vr(t){return t&&$r().includes(t)}function Gt(){let t=Jr();return Y("detected CI provider name: %s",t),t||null}function Wr(){let t=Yr(Ft);return(0,d.mapValues)(t,e=>(0,d.isString)(e)?vt(e):e)}function kt(t){let e=Wr(),r=Gt(),n=qr(t,r);return Y("detected CI provider: %s",r),Y("detected CI params: %O",e),Y("detected CI build ID: %o",n),{params:e,provider:r,ciBuildId:n}}function qr(t,e){return t?{source:"user",value:t}:Vr(e)?{source:"server",value:null}:{source:"random",value:`auto:${Et()}`}}var Ht=require("@currents/commit-info"),jt=require("lodash");var Qr=a.extend("git"),Xr=async()=>{let t=await(0,Ht.commitInfo)();return Qr("commit: %O",t),{branch:t.branch,remoteOrigin:t.remote,authorEmail:t.email,authorName:t.author,message:t.message,sha:t.sha,ghaEventData:t.ghaEventData??null}},Kt=(0,jt.memoize)(Xr);var Jt=u(require("getos")),Yt=require("lodash"),A=require("os"),$t=require("util"),zr=async()=>{if((0,A.platform)()==="linux")try{let t=await(0,$t.promisify)(Jt.default)();return"dist"in t&&"release"in t?[t.dist,t.release].join(" - "):(0,A.release)()}catch{return(0,A.release)()}return(0,A.release)()},Zr=async()=>{let t=await zr();return{osName:(0,A.platform)(),osVersion:t,osCpus:[],osMemory:{free:(0,A.freemem)(),total:(0,A.totalmem)()}}},Vt=(0,Yt.memoize)(Zr);var Wt={name:"@currents/cmd",version:"2.1.0",main:"./dist/index.js",author:{name:"Currents Software Inc",email:"hello@currents.dev"},license:"MIT",repository:{type:"git",url:"https://github.com/currents-dev/currents-reporter"},description:"Currents CLI tools",engines:{node:">=20"},scripts:{test:"vitest",rm:"rimraf dist",lint:'TIMING=1 eslint "**/*.ts*"',types:"tsc --noEmit",build:"tsup-node --minify --dts",dev:"tsup-node --watch --dts",release:"release-it","publish:npm":"npm run rm && npm run build && ./publish.js"},devDependencies:{"@jest/reporters":"^30.4.1","@jest/types":"^30.4.1","@release-it/conventional-changelog":"^12.0.0","release-it":"^21.0.2","@types/archiver":"^6.0.3","@types/async-retry":"^1.4.9","@types/debug":"^4.1.12","@types/fs-extra":"^11.0.4","@types/getos":"^3.0.4","@types/lodash":"^4.17.16","@types/node":"^25.5.0","@types/proxy-from-env":"^1.0.4","@types/semver":"^7.5.8","@types/tmp":"^0.2.6","@types/unzipper":"^0.10.11","@types/uuid":"^10.0.0","@types/xml2js":"^0.4.14","@types/xxhashjs":"^0.2.4",jest:"^30.4.2","jest-cli":"^30.4.2","jest-config":"^30.4.2",rimraf:"^6.0.1",tsup:"^8.3.5",typescript:"^5.9.3",vitest:"^4.1.11"},dependencies:{"@commander-js/extra-typings":"^14.0.0","@currents/commit-info":"2.0.0",archiver:"^7.0.1","async-retry":"^1.3.3",axios:"1.20.0","axios-retry":"4.5.0",chalk:"^4.1.2",commander:"^14.0.0",debug:"^4.4.0",dotenv:"^17.4.2",execa:"^9.5.1","fs-extra":"^11.3.4",getos:"^3.2.1",globby:"^11.1.0","https-proxy-agent":"^7.0.4",lodash:"^4.18.1",nanoid:"^3.3.8","pretty-ms":"^7.0.1","proxy-from-env":"^1.1.0",semver:"^7.8.5","source-map-support":"^0.5.21",tmp:"^0.2.7","tmp-promise":"^3.0.3","ts-pattern":"^5.8.0",unzipper:"^0.12.3",uuid:"11.1.1",xml2js:"^0.6.2",xxhashjs:"^0.2.2"},bin:{currents:"./dist/bin/index.js","currents-cli":"./dist/bin/index.js"},files:["dist","!**/*.map","!**/*/*.map"],keywords:["cloud test dashboard","test reporter","test results","currents","currents dashboard","ci"],exports:{".":{import:"./dist/index.js",require:"./dist/index.js",types:"./dist/index.d.ts"},"./discovery/jest":{import:"./dist/services/upload/discovery/jest/reporter.js",require:"./dist/services/upload/discovery/jest/reporter.js",types:"./dist/services/upload/discovery/jest/reporter.d.ts"},"./package.json":"./package.json"},"release-it":{npm:{publish:!1},github:{release:!0,releaseName:"${npm.name} v${version}"},plugins:{"@release-it/conventional-changelog":{preset:{name:"conventionalcommits"},header:"# Changelog",ignoreVersion:!0,infile:"./CHANGELOG.md"}},git:{commitMessage:"chore: release ${npm.name} v${version}",tagName:"${npm.name}-v${version}"}}};var $=Wt.version;var ft=u(require("lodash")),en=["apiKey","recordKey","key"];function qt(t,e){return ft.default.isPlainObject(t)?ft.default.mapValues(t,(r,n)=>e.includes(n)&&r!==void 0?"*****":qt(r,e)):t}function O(t){return qt(t,en)}var rn=[];function dt(t){rn.push(t)}var h=u(require("chalk")),b=u(require("util"));var Qt=[],Xt=[];var zt=(...t)=>{let e=b.default.format(...t);dt(e),console.log(e)},nn=(...t)=>{let e=b.default.format(...t);dt(e),console.error(e)},V=zt,E=(...t)=>{let e=b.default.format(...t);return Xt.push(e),a("WARNING: ",e),zt(h.default.bgYellow.black(" WARNING "),e)};var I=(...t)=>{let e=b.default.format(...on(t));return Qt.push(e),a("ERROR: ",b.default.format(...t)),nn(h.default.bgRed.white(" ERROR "),e)};var on=t=>t.map(e=>e instanceof Error?e.message:e),W=(t=2)=>console.log(Array(t).fill("").join(`
2
- `)),$o=h.default.cyan,Vo=h.default.blueBright,Wo=h.default.red,qo=h.default.yellow,Qo=h.default.green,Xo=h.default.gray,zo=h.default.white,Zo=h.default.black,ts=h.default.magenta,v=h.default.dim,es=h.default.bold;var F=u(require("fs-extra")),gt=require("path"),an=require("uuid");async function M(t){try{return await F.default.readJson(t)}catch(e){throw I("Error while reading JSON file: %s",t,e),I}}async function It(t,e){try{return await F.default.writeFile(t,e,"utf8"),t}catch(r){throw I(`Error writing file at ${t}:`,r),r}}async function Zt(t){try{return await F.default.ensureDir(t),a("Folder created",t),t}catch(e){throw I(`Failed to create folder at ${t}:`,e),e}}async function te(t,e){try{return await F.default.ensureDir((0,gt.dirname)(e)),await F.default.copy(t,e),a("File copied from %s to %s",t,e),e}catch(r){throw I(`Failed to copy file from ${t} to ${e}:`,r),r}}var ee=u(require("crypto"));function re(t){return ee.createHash("sha256").update(t).digest("base64").slice(0,8).replace(/\+/g,"-").replace(/\//g,"_").replace(/=+$/,"")}var Rr=u(require("axios")),Lt=u(require("fs-extra")),pt=u(require("path")),Cr=u(require("semver"));var Re=u(require("lodash"));var le=u(require("axios")),Ee=u(require("axios-retry")),Ut=u(require("lodash"));var ne=()=>process.env.CURRENTS_API_URL??"https://cy.currents.dev",oe=()=>process.env.CURRENTS_REST_API_URL??"https://api.currents.dev",se=()=>3e4;var q=require("axios"),Tt=u(require("pretty-ms"));var ae=a.extend("http"),ie=[3*1e3,15*1e3,30*1e3],ce=60*1e3;function _t(t,e=Date.now()){let r=t?.response?.headers?.["retry-after"];if(r==null||r==="")return;let n=Number(r);if(Number.isFinite(n))return Math.max(0,n*1e3);let o=Date.parse(String(r));return Number.isNaN(o)?void 0:Math.max(0,o-e)}var Q=(t,e)=>{let r=ie[Math.min(t,ie.length)-1],n=_t(e);return n===void 0?r:Math.min(Math.max(n,r),ce)},Rt=t=>(ae("isRetriableError: %o",{message:t.message,code:"code"in t?t.code:void 0,status:"response"in t?t.response?.status:void 0,headers:"response"in t?t.response?.headers:void 0,data:"response"in t?t.response?.data:void 0,isAxiosError:(0,q.isAxiosError)(t)}),"code"in t&&t.code&&["ECONNABORTED","ECONNREFUSED","ECONNRESET","ETIMEDOUT","ENETRESET"].includes(t.code)?!0:(0,q.isAxiosError)(t)?[408,429,502,503,504].includes(t.response?.status??0):!1),cn=["get","head","options","put","delete"],pe=t=>{if(!(0,q.isAxiosError)(t))return!1;let e=t.response?.status;if(e===429){let r=_t(t);return r===void 0||r<=ce}return cn.includes(t.config?.method?.toLowerCase()??"get")?Rt(t):e===408||t.code==="ECONNREFUSED"||t.code==="ENOTFOUND"},X=()=>3;function ue(t,e,r){ae("Network request '%s' failed: '%s'. Next attempt is in %s (%d/%d).",`${r.method?.toUpperCase()} ${r.url}`,e.message,(0,Tt.default)(Q(t,e)??0),t,X()),E("Network request '%s' failed: '%s'. Next attempt is in %s (%d/%d).",`${r.method?.toUpperCase()} ${r.url}`,e.message,(0,Tt.default)(Q(t,e)??0),t,X())}var Ct=a.extend("http");var ht={api:null,restApi:null};function pn(t){let e=t==="api"?ne():oe();Ct("client base url: %s",e);let r=le.default.create({baseURL:e,timeout:se(),transitional:{clarifyTimeoutError:!0}});return r.interceptors.request.use(n=>{let o=n["axios-retry"]?.retryCount??0;n.headers.set({"x-cmd-version":$}),n.headers.get("Content-Type")||n.headers.set("Content-Type","application/json");let s={...Ut.default.pick(n,"method","url","headers"),baseURL:e,data:Buffer.isBuffer(n.data)?"buffer":n.data,params:n.params};return o?Ct("network request retry: %o",me({...s,baseURL:e,isRetry:!0})):Ct("network request: %o",me(s)),n}),(0,Ee.default)(r,{retries:X(),retryCondition:t==="restApi"?pe:Rt,retryDelay:(n,o)=>Q(n,o),shouldResetTimeout:!0,onRetry:ue}),r}function z(t){return ht[t]===null&&(ht[t]=pn(t)),ht[t]}function me(t){return{method:t.method,baseURL:t.baseURL,url:t.url,data:t.isRetry?"<retry>":un(t.data),params:t.isRetry?"<retry>":t.params,headers:{...t.headers,Authorization:"Bearer ***","x-currents-key":"***"}}}function un(t){if(t?.results?.raw)return O({...t,results:{...t.results,raw:"***"}});if(typeof t=="string")try{return O(JSON.parse(t))}catch{return t}return Ut.default.isPlainObject(t)?O(t):t}var ge=require("axios"),Ie=u(require("lodash")),C=require("ts-pattern");function Te(t){(0,C.match)(t).when(ge.isAxiosError,mn).otherwise(()=>{E("Unexpected error while sending network request: %s",t)})}function mn(t){return(0,C.match)(t).with({code:"ECONNABORTED"},()=>{E("Network connection aborted")}).with({code:"ECONNREFUSED"},()=>{E("Network connection aborted")}).with({code:"ECONNRESET"},()=>{E("Network connection reset")}).with({code:"ETIMEDOUT"},()=>{E("Network connection timeout")}).with({response:C.P.not(C.P.nullish)},e=>{ln(e,{status:e.response.status,data:e.response.data})}).otherwise(e=>{E(`[currents] Unexpected network error: %s
1
+ "use strict";var Or=Object.create;var K=Object.defineProperty;var Sr=Object.getOwnPropertyDescriptor;var yr=Object.getOwnPropertyNames;var Nr=Object.getPrototypeOf,xr=Object.prototype.hasOwnProperty;var Bt=(t,e)=>{for(var r in e)K(t,r,{get:e[r],enumerable:!0})},Pt=(t,e,r,n)=>{if(e&&typeof e=="object"||typeof e=="function")for(let o of yr(e))!xr.call(t,o)&&o!==r&&K(t,o,{get:()=>e[o],enumerable:!(n=Sr(e,o))||n.enumerable});return t};var u=(t,e,r)=>(r=t!=null?Or(Nr(t)):{},Pt(e||!t||!t.__esModule?K(r,"default",{value:t,enumerable:!0}):r,t)),Lr=t=>Pt(K({},"__esModule",{value:!0}),t);var uo={};Bt(uo,{handleCurrentsReport:()=>hr});module.exports=Lr(uo);var wt=require("debug"),Br=u(require("fs-extra")),a=(0,wt.debug)("currents"),Pr=null;function Mt(t){Pr=t}var J={};Bt(J,{getNanoid:()=>wr,userFacingNanoid:()=>Et});var lt=require("nanoid"),bt="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz",wr=(t=16)=>(0,lt.customAlphabet)(bt,t)(),Et=(0,lt.customAlphabet)(bt,12);var d=require("lodash");function vt(t){return t.replace(/^([a-z][a-z0-9+.-]*:\/\/)[^/?#\s]*@/i,"$1")}var Y=a.extend("ci"),Mr=(t,e)=>(0,d.set)(t,(0,d.camelCase)(e),process.env[e]),_=t=>(0,d.transform)(t,Mr,{}),br=()=>process.env.TF_BUILD&&process.env.AZURE_HTTP_USER_AGENT,vr=()=>(0,d.some)(process.env,(t,e)=>/^CODEBUILD_/.test(e)),Fr=()=>process.env.bamboo_buildNumber,Gr=()=>(0,d.some)(process.env,(t,e)=>/^CONCOURSE_/.test(e)),kr=()=>process.env.GITLAB_CI||process.env.CI_SERVER_NAME&&/^GitLab/.test(process.env.CI_SERVER_NAME),Hr=()=>!!(process.env.BUILD_ID&&process.env.PROJECT_ID&&process.env.PROJECT_NUMBER||process.env.GCP_PROJECT||process.env.GCLOUD_PROJECT||process.env.GOOGLE_CLOUD_PROJECT),jr=()=>process.env.JENKINS_URL||process.env.JENKINS_HOME||process.env.JENKINS_VERSION||process.env.HUDSON_URL||process.env.HUDSON_HOME,Kr={appveyor:"APPVEYOR",azure:br,awsCodeBuild:vr,bamboo:Fr,bitbucket:"BITBUCKET_BUILD_NUMBER",buildkite:"BUILDKITE",circle:"CIRCLECI",concourse:Gr,codeFresh:"CF_BUILD_ID",drone:"DRONE",githubActions:"GITHUB_ACTIONS",gitlab:kr,goCD:"GO_JOB_NAME",jenkins:jr,googleCloud:Hr,semaphore:"SEMAPHORE",teamcity:"TEAMCITY_VERSION",travis:"TRAVIS",netlify:"NETLIFY"};function Jr(){let{env:t}=process;return(0,d.findKey)(Kr,e=>{if((0,d.isString)(e))return t[e];if((0,d.isFunction)(e))return e()})}var Ft=()=>({appveyor:_(["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:_(["AGENT_BUILDDIRECTORY","AGENT_ID","AGENT_JOBNAME","AGENT_JOBSTATUS","AGENT_MACHINENAME","AGENT_NAME","AGENT_OS","AGENT_OSARCHITECTURE","BUILD_BUILDID","BUILD_BUILDNUMBER","BUILD_BUILDURI","BUILD_CONTAINERID","BUILD_CRONSCHEDULE_DISPLAYNAME","BUILD_DEFINITIONNAME","BUILD_DEFINITIONVERSION","BUILD_QUEUEDBY","BUILD_QUEUEDBYID","BUILD_REASON","BUILD_REPOSITORY_ID","BUILD_REPOSITORY_NAME","BUILD_REPOSITORY_PROVIDER","BUILD_REPOSITORY_URI","BUILD_REQUESTEDFOR","BUILD_REQUESTEDFOREMAIL","BUILD_REQUESTEDFORID","BUILD_SOURCEBRANCH","BUILD_SOURCEBRANCHNAME","BUILD_SOURCESDIRECTORY","BUILD_SOURCEVERSION","BUILD_SOURCEVERSIONAUTHOR","BUILD_SOURCEVERSIONMESSAGE","BUILD_STAGINGDIRECTORY","BUILD_TRIGGEREDBY_BUILDID","BUILD_TRIGGEREDBY_BUILDNUMBER","BUILD_TRIGGEREDBY_DEFINITIONID","BUILD_TRIGGEREDBY_DEFINITIONNAME","BUILD_TRIGGEREDBY_PROJECTID","COMMON_TESTRESULTSDIRECTORY","PIPELINE_WORKSPACE","SYSTEM_COLLECTIONID","SYSTEM_COLLECTIONURI","SYSTEM_DEFAULTWORKINGDIRECTORY","SYSTEM_DEFINITIONID","SYSTEM_HOSTTYPE","SYSTEM_JOBATTEMPT","SYSTEM_JOBDISPLAYNAME","SYSTEM_JOBID","SYSTEM_JOBNAME","SYSTEM_PHASEATTEMPT","SYSTEM_PHASEDISPLAYNAME","SYSTEM_PHASENAME","SYSTEM_PLANID","SYSTEM_PULLREQUEST_ISFORK","SYSTEM_PULLREQUEST_PULLREQUESTID","SYSTEM_PULLREQUEST_PULLREQUESTNUMBER","SYSTEM_PULLREQUEST_SOURCEREPOSITORYURI","SYSTEM_PULLREQUEST_SOURCEBRANCH","SYSTEM_PULLREQUEST_SOURCECOMMITID","SYSTEM_PULLREQUEST_TARGETBRANCH","SYSTEM_PULLREQUEST_TARGETBRANCHNAME","SYSTEM_STAGEATTEMPT","SYSTEM_STAGEDISPLAYNAME","SYSTEM_STAGENAME","SYSTEM_TEAMFOUNDATIONCOLLECTIONURI","SYSTEM_TEAMPROJECT","SYSTEM_TEAMPROJECTID","SYSTEM_TIMELINEID"]),awsCodeBuild:_(["AWS_DEFAULT_REGION","AWS_REGION","CODEBUILD_BATCH_BUILD_IDENTIFIER","CODEBUILD_BUILD_ARN","CODEBUILD_BUILD_ID","CODEBUILD_BUILD_IMAGE","CODEBUILD_BUILD_NUMBER","CODEBUILD_BUILD_SUCCEEDING","CODEBUILD_BUILD_URL","CODEBUILD_INITIATOR","CODEBUILD_PROJECT_ARN","CODEBUILD_PUBLIC_BUILD_URL","CODEBUILD_RESOLVED_SOURCE_VERSION","CODEBUILD_SOURCE_REPO_URL","CODEBUILD_SOURCE_VERSION","CODEBUILD_SRC_DIR","CODEBUILD_START_TIME","CODEBUILD_WEBHOOK_ACTOR_ACCOUNT_ID","CODEBUILD_WEBHOOK_BASE_REF","CODEBUILD_WEBHOOK_EVENT","CODEBUILD_WEBHOOK_HEAD_REF","CODEBUILD_WEBHOOK_MERGE_COMMIT","CODEBUILD_WEBHOOK_PREV_COMMIT","CODEBUILD_WEBHOOK_TRIGGER","CODEBUILD_WEBHOOK_LABEL","CODEBUILD_WEBHOOK_RUN_ID","CODEBUILD_WEBHOOK_JOB_ID","CODEBUILD_WEBHOOK_WORKFLOW_NAME","CODEBUILD_RUNNER_OWNER","CODEBUILD_RUNNER_REPO","CODEBUILD_RUNNER_REPO_DOMAIN","CODEBUILD_RUNNER_WITH_BUILDSPEC"]),bamboo:_(["bamboo_buildNumber","bamboo_buildResultsUrl","bamboo_planRepository_repositoryUrl","bamboo_buildKey"]),bitbucket:_(["CI","BITBUCKET_WORKSPACE","BITBUCKET_REPO_SLUG","BITBUCKET_REPO_UUID","BITBUCKET_REPO_FULL_NAME","BITBUCKET_REPO_IS_PRIVATE","BITBUCKET_REPO_OWNER","BITBUCKET_REPO_OWNER_UUID","BITBUCKET_PROJECT_KEY","BITBUCKET_PROJECT_UUID","BITBUCKET_BUILD_NUMBER","BITBUCKET_PIPELINE_UUID","BITBUCKET_STEP_UUID","BITBUCKET_STEP_RUN_NUMBER","BITBUCKET_STEP_TRIGGERER_UUID","BITBUCKET_PARALLEL_STEP","BITBUCKET_PARALLEL_STEP_COUNT","BITBUCKET_CLONE_DIR","BITBUCKET_COMMIT","BITBUCKET_BRANCH","BITBUCKET_TAG","BITBUCKET_BOOKMARK","BITBUCKET_GIT_HTTP_ORIGIN","BITBUCKET_GIT_SSH_ORIGIN","BITBUCKET_PR_ID","BITBUCKET_PR_DESTINATION_BRANCH","BITBUCKET_PR_DESTINATION_COMMIT","BITBUCKET_DEPLOYMENT_ENVIRONMENT","BITBUCKET_DEPLOYMENT_ENVIRONMENT_UUID","BITBUCKET_EXIT_CODE"]),buildkite:_(["BUILDKITE_ORGANIZATION_SLUG","BUILDKITE_PIPELINE_ID","BUILDKITE_PIPELINE_NAME","BUILDKITE_PIPELINE_SLUG","BUILDKITE_PIPELINE_DEFAULT_BRANCH","BUILDKITE_REPO","BUILDKITE_SOURCE","BUILDKITE_BRANCH","BUILDKITE_TAG","BUILDKITE_COMMIT","BUILDKITE_MESSAGE","BUILDKITE_BUILD_AUTHOR","BUILDKITE_BUILD_AUTHOR_EMAIL","BUILDKITE_JOB_ID","BUILDKITE_BUILD_ID","BUILDKITE_BUILD_URL","BUILDKITE_BUILD_NUMBER","BUILDKITE_LABEL","BUILDKITE_COMMAND","BUILDKITE_STEP_ID","BUILDKITE_STEP_KEY","BUILDKITE_PARALLEL_JOB","BUILDKITE_PARALLEL_JOB_COUNT","BUILDKITE_RETRY_COUNT","BUILDKITE_COMPUTE_TYPE","BUILDKITE_CLUSTER_NAME","BUILDKITE_PULL_REQUEST","BUILDKITE_PULL_REQUEST_REPO","BUILDKITE_PULL_REQUEST_BASE_BRANCH","BUILDKITE_PULL_REQUEST_DRAFT","BUILDKITE_PULL_REQUEST_LABELS","BUILDKITE_MERGE_QUEUE_BASE_BRANCH","BUILDKITE_MERGE_QUEUE_BASE_COMMIT","BUILDKITE_REBUILT_FROM_BUILD_ID","BUILDKITE_REBUILT_FROM_BUILD_NUMBER","BUILDKITE_TRIGGERED_FROM_BUILD_ID","BUILDKITE_TRIGGERED_FROM_BUILD_NUMBER","BUILDKITE_TRIGGERED_FROM_BUILD_PIPELINE_SLUG"]),circle:_(["CI","CIRCLECI","CIRCLE_BRANCH","CIRCLE_BUILD_NUM","CIRCLE_BUILD_URL","CIRCLE_PREVIOUS_BUILD_NUM","CIRCLE_JOB","CIRCLE_WORKFLOW_ID","CIRCLE_WORKFLOW_JOB_ID","CIRCLE_WORKFLOW_WORKSPACE_ID","CIRCLE_PIPELINE_ID","CIRCLE_ORGANIZATION_ID","CIRCLE_PROJECT_ID","CIRCLE_PROJECT_REPONAME","CIRCLE_PROJECT_USERNAME","CIRCLE_REPOSITORY_URL","CIRCLE_WORKING_DIRECTORY","CIRCLE_SHA1","CIRCLE_TAG","CIRCLE_USERNAME","CIRCLE_NODE_INDEX","CIRCLE_NODE_TOTAL","CIRCLE_PR_NUMBER","CIRCLE_PR_REPONAME","CIRCLE_PR_USERNAME","CIRCLE_PULL_REQUEST","CIRCLE_PULL_REQUESTS","CI_PULL_REQUEST"]),concourse:_(["BUILD_ID","BUILD_NAME","BUILD_JOB_NAME","BUILD_PIPELINE_NAME","BUILD_TEAM_NAME","ATC_EXTERNAL_URL"]),codeFresh:_(["CF_BUILD_ID","CF_BUILD_URL","CF_CURRENT_ATTEMPT","CF_STEP_NAME","CF_PIPELINE_NAME","CF_PIPELINE_TRIGGER_ID","CF_PULL_REQUEST_ID","CF_PULL_REQUEST_IS_FORK","CF_PULL_REQUEST_NUMBER","CF_PULL_REQUEST_TARGET"]),drone:_(["DRONE_BUILD_LINK","DRONE_BUILD_NUMBER","DRONE_PULL_REQUEST"]),githubActions:_(["CI","GITHUB_ACTIONS","GITHUB_WORKFLOW","GITHUB_WORKFLOW_REF","GITHUB_WORKFLOW_SHA","GITHUB_ACTION","GITHUB_ACTION_PATH","GITHUB_ACTION_REPOSITORY","GITHUB_JOB","GITHUB_EVENT_NAME","GITHUB_EVENT_PATH","GITHUB_RUN_ID","GITHUB_RUN_NUMBER","GITHUB_RUN_ATTEMPT","GITHUB_REPOSITORY","GITHUB_REPOSITORY_ID","GITHUB_REPOSITORY_OWNER","GITHUB_REPOSITORY_OWNER_ID","GITHUB_REF","GITHUB_REF_NAME","GITHUB_REF_TYPE","GITHUB_REF_PROTECTED","GITHUB_BASE_REF","GITHUB_HEAD_REF","GITHUB_SHA","GITHUB_ACTOR","GITHUB_ACTOR_ID","GITHUB_TRIGGERING_ACTOR","GITHUB_SERVER_URL","GITHUB_API_URL","GITHUB_GRAPHQL_URL","GITHUB_WORKSPACE","GITHUB_RETENTION_DAYS","RUNNER_OS","RUNNER_ARCH","RUNNER_NAME","RUNNER_ENVIRONMENT","RUNNER_DEBUG"]),gitlab:_(["CI_PIPELINE_ID","CI_PIPELINE_URL","CI_BUILD_ID","CI_JOB_ID","CI_JOB_URL","CI_JOB_NAME","CI_NODE_INDEX","CI_NODE_TOTAL","GITLAB_HOST","CI_PROJECT_ID","CI_PROJECT_URL","CI_REPOSITORY_URL","CI_ENVIRONMENT_URL","CI_DEFAULT_BRANCH","RUN_ATTEMPT","CI_MERGE_REQUEST_IID","CI_MERGE_REQUEST_PROJECT_URL","CI_MERGE_REQUEST_TITLE","CI_MERGE_REQUEST_SOURCE_BRANCH_NAME","CI_MERGE_REQUEST_TARGET_BRANCH_NAME","CI_OPEN_MERGE_REQUESTS"]),goCD:_(["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:_(["BUILD_ID","PROJECT_ID","REPO_NAME","BRANCH_NAME","TAG_NAME","COMMIT_SHA","SHORT_SHA"]),jenkins:_(["BRANCH_NAME","BUILD_DISPLAY_NAME","BUILD_ID","BUILD_NUMBER","BUILD_TAG","BUILD_URL","CHANGE_AUTHOR","CHANGE_AUTHOR_DISPLAY_NAME","CHANGE_AUTHOR_EMAIL","CHANGE_BRANCH","CHANGE_FORK","CHANGE_ID","CHANGE_TARGET","CHANGE_TITLE","CHANGE_URL","CI","EXECUTOR_NUMBER","JAVA_HOME","JENKINS_HOME","JENKINS_URL","JOB_BASE_NAME","JOB_NAME","JOB_URL","NODE_LABELS","NODE_NAME","RUN_ARTIFACTS_DISPLAY_URL","RUN_CHANGES_DISPLAY_URL","TAG_NAME","WORKSPACE","WORKSPACE_TMP","GIT_AUTHOR_EMAIL","GIT_AUTHOR_NAME","GIT_BRANCH","GIT_COMMIT","GIT_COMMITTER_EMAIL","GIT_COMMITTER_NAME","GIT_LOCAL_BRANCH","GIT_PREVIOUS_COMMIT","GIT_PREVIOUS_SUCCESSFUL_COMMIT","GIT_URL","ghprbActualCommit","ghprbGhRepository","ghprbPullId","ghprbPullLink","ghprbSourceBranch","ghprbTargetBranch","ghprbTriggerAuthorLogin"]),semaphore:_(["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","SEMAPHORE_JOB_NAME","SEMAPHORE_JOB_UUID","SEMAPHORE_PIPELINE_ID","SEMAPHORE_PLATFORM","SEMAPHORE_PROJECT_DIR","SEMAPHORE_PROJECT_HASH_ID","SEMAPHORE_PROJECT_ID","SEMAPHORE_PROJECT_NAME","SEMAPHORE_PROJECT_UUID","SEMAPHORE_REPO_SLUG","SEMAPHORE_TRIGGER_SOURCE","SEMAPHORE_WORKFLOW_ID","PULL_REQUEST_NUMBER"]),teamcity:null,travis:_(["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"]),netlify:_(["BUILD_ID","CONTEXT","URL","DEPLOY_URL","DEPLOY_PRIME_URL","DEPLOY_ID"])}),Yr=t=>{let e=Gt();return e?(0,d.chain)(t()).get(e).value():{}};function $r(){return(0,d.chain)(Ft()).omitBy(d.isNull).keys().value()}function Vr(t){return t&&$r().includes(t)}function Gt(){let t=Jr();return Y("detected CI provider name: %s",t),t||null}function Wr(){let t=Yr(Ft);return(0,d.mapValues)(t,e=>(0,d.isString)(e)?vt(e):e)}function kt(t){let e=Wr(),r=Gt(),n=qr(t,r);return Y("detected CI provider: %s",r),Y("detected CI params: %O",e),Y("detected CI build ID: %o",n),{params:e,provider:r,ciBuildId:n}}function qr(t,e){return t?{source:"user",value:t}:Vr(e)?{source:"server",value:null}:{source:"random",value:`auto:${Et()}`}}var Ht=require("@currents/commit-info"),jt=require("lodash");var Qr=a.extend("git"),Xr=async()=>{let t=await(0,Ht.commitInfo)();return Qr("commit: %O",t),{branch:t.branch,remoteOrigin:t.remote,authorEmail:t.email,authorName:t.author,message:t.message,sha:t.sha,ghaEventData:t.ghaEventData??null}},Kt=(0,jt.memoize)(Xr);var Jt=u(require("getos")),Yt=require("lodash"),A=require("os"),$t=require("util"),zr=async()=>{if((0,A.platform)()==="linux")try{let t=await(0,$t.promisify)(Jt.default)();return"dist"in t&&"release"in t?[t.dist,t.release].join(" - "):(0,A.release)()}catch{return(0,A.release)()}return(0,A.release)()},Zr=async()=>{let t=await zr();return{osName:(0,A.platform)(),osVersion:t,osCpus:[],osMemory:{free:(0,A.freemem)(),total:(0,A.totalmem)()}}},Vt=(0,Yt.memoize)(Zr);var Wt={name:"@currents/cmd",version:"2.2.0",main:"./dist/index.js",author:{name:"Currents Software Inc",email:"hello@currents.dev"},license:"MIT",repository:{type:"git",url:"https://github.com/currents-dev/currents-reporter"},description:"Currents CLI tools",engines:{node:">=20"},scripts:{test:"vitest",rm:"rimraf dist",lint:'TIMING=1 eslint "**/*.ts*"',types:"tsc --noEmit",build:"tsup-node --minify --dts",dev:"tsup-node --watch --dts",release:"release-it","publish:npm":"npm run rm && npm run build && ./publish.js"},devDependencies:{"@jest/reporters":"^30.4.1","@jest/types":"^30.4.1","@release-it/conventional-changelog":"^12.0.0","release-it":"^21.0.2","@types/archiver":"^6.0.3","@types/async-retry":"^1.4.9","@types/debug":"^4.1.12","@types/fs-extra":"^11.0.4","@types/getos":"^3.0.4","@types/lodash":"^4.17.16","@types/node":"^25.5.0","@types/proxy-from-env":"^1.0.4","@types/semver":"^7.5.8","@types/tmp":"^0.2.6","@types/unzipper":"^0.10.11","@types/uuid":"^10.0.0","@types/xml2js":"^0.4.14","@types/xxhashjs":"^0.2.4",jest:"^30.4.2","jest-cli":"^30.4.2","jest-config":"^30.4.2",rimraf:"^6.0.1",tsup:"^8.3.5",typescript:"^5.9.3",vitest:"^4.1.11"},dependencies:{"@commander-js/extra-typings":"^14.0.0","@currents/commit-info":"2.0.0",archiver:"^7.0.1","async-retry":"^1.3.3",axios:"1.20.0","axios-retry":"4.5.0",chalk:"^4.1.2",commander:"^14.0.0",debug:"^4.4.0",dotenv:"^17.4.2",execa:"^9.5.1","fs-extra":"^11.3.4",getos:"^3.2.1",globby:"^11.1.0","https-proxy-agent":"^7.0.4",lodash:"^4.18.1",nanoid:"^3.3.8","pretty-ms":"^7.0.1","proxy-from-env":"^1.1.0",semver:"^7.8.5","source-map-support":"^0.5.21",tmp:"^0.2.7","tmp-promise":"^3.0.3","ts-pattern":"^5.8.0",unzipper:"^0.12.3",uuid:"11.1.1",xml2js:"^0.6.2",xxhashjs:"^0.2.2"},bin:{currents:"./dist/bin/index.js","currents-cli":"./dist/bin/index.js"},files:["dist","docs","!**/*.map","!**/*/*.map"],keywords:["cloud test dashboard","test reporter","test results","currents","currents dashboard","ci"],exports:{".":{import:"./dist/index.js",require:"./dist/index.js",types:"./dist/index.d.ts"},"./discovery/jest":{import:"./dist/services/upload/discovery/jest/reporter.js",require:"./dist/services/upload/discovery/jest/reporter.js",types:"./dist/services/upload/discovery/jest/reporter.d.ts"},"./package.json":"./package.json"},"release-it":{npm:{publish:!1},github:{release:!0,releaseName:"${npm.name} v${version}"},plugins:{"@release-it/conventional-changelog":{preset:{name:"conventionalcommits"},header:"# Changelog",ignoreVersion:!0,infile:"./CHANGELOG.md"}},git:{commitMessage:"chore: release ${npm.name} v${version}",tagName:"${npm.name}-v${version}"}}};var $=Wt.version;var ft=u(require("lodash")),en=["apiKey","recordKey","key"];function qt(t,e){return ft.default.isPlainObject(t)?ft.default.mapValues(t,(r,n)=>e.includes(n)&&r!==void 0?"*****":qt(r,e)):t}function O(t){return qt(t,en)}var rn=[];function dt(t){rn.push(t)}var h=u(require("chalk")),b=u(require("util"));var Qt=[],Xt=[];var zt=(...t)=>{let e=b.default.format(...t);dt(e),console.log(e)},nn=(...t)=>{let e=b.default.format(...t);dt(e),console.error(e)},V=zt,E=(...t)=>{let e=b.default.format(...t);return Xt.push(e),a("WARNING: ",e),zt(h.default.bgYellow.black(" WARNING "),e)};var I=(...t)=>{let e=b.default.format(...on(t));return Qt.push(e),a("ERROR: ",b.default.format(...t)),nn(h.default.bgRed.white(" ERROR "),e)};var on=t=>t.map(e=>e instanceof Error?e.message:e),W=(t=2)=>console.log(Array(t).fill("").join(`
2
+ `)),$o=h.default.cyan,Vo=h.default.blueBright,Wo=h.default.red,qo=h.default.yellow,Qo=h.default.green,Xo=h.default.gray,zo=h.default.white,Zo=h.default.black,ts=h.default.magenta,v=h.default.dim,es=h.default.bold;var F=u(require("fs-extra")),gt=require("path"),an=require("uuid");async function M(t){try{return await F.default.readJson(t)}catch(e){throw I("Error while reading JSON file: %s",t,e),I}}async function It(t,e){try{return await F.default.writeFile(t,e,"utf8"),t}catch(r){throw I(`Error writing file at ${t}:`,r),r}}async function Zt(t){try{return await F.default.ensureDir(t),a("Folder created",t),t}catch(e){throw I(`Failed to create folder at ${t}:`,e),e}}async function te(t,e){try{return await F.default.ensureDir((0,gt.dirname)(e)),await F.default.copy(t,e),a("File copied from %s to %s",t,e),e}catch(r){throw I(`Failed to copy file from ${t} to ${e}:`,r),r}}var ee=u(require("crypto"));function re(t){return ee.createHash("sha256").update(t).digest("base64").slice(0,8).replace(/\+/g,"-").replace(/\//g,"_").replace(/=+$/,"")}var Rr=u(require("axios")),xt=u(require("fs-extra")),pt=u(require("path")),Cr=u(require("semver"));var Re=u(require("lodash"));var le=u(require("axios")),Ee=u(require("axios-retry")),Ut=u(require("lodash"));var ne=()=>process.env.CURRENTS_API_URL??"https://cy.currents.dev",oe=()=>process.env.CURRENTS_REST_API_URL??"https://api.currents.dev",se=()=>3e4;var q=require("axios"),Tt=u(require("pretty-ms"));var ae=a.extend("http"),ie=[3*1e3,15*1e3,30*1e3],ce=60*1e3;function _t(t,e=Date.now()){let r=t?.response?.headers?.["retry-after"];if(r==null||r==="")return;let n=Number(r);if(Number.isFinite(n))return Math.max(0,n*1e3);let o=Date.parse(String(r));return Number.isNaN(o)?void 0:Math.max(0,o-e)}var Q=(t,e)=>{let r=ie[Math.min(t,ie.length)-1],n=_t(e);return n===void 0?r:Math.min(Math.max(n,r),ce)},Rt=t=>(ae("isRetriableError: %o",{message:t.message,code:"code"in t?t.code:void 0,status:"response"in t?t.response?.status:void 0,headers:"response"in t?t.response?.headers:void 0,data:"response"in t?t.response?.data:void 0,isAxiosError:(0,q.isAxiosError)(t)}),"code"in t&&t.code&&["ECONNABORTED","ECONNREFUSED","ECONNRESET","ETIMEDOUT","ENETRESET"].includes(t.code)?!0:(0,q.isAxiosError)(t)?[408,429,502,503,504].includes(t.response?.status??0):!1),cn=["get","head","options","put","delete"],pe=t=>{if(!(0,q.isAxiosError)(t))return!1;let e=t.response?.status;if(e===429){let r=_t(t);return r===void 0||r<=ce}return cn.includes(t.config?.method?.toLowerCase()??"get")?Rt(t):e===408||t.code==="ECONNREFUSED"||t.code==="ENOTFOUND"},X=()=>3;function ue(t,e,r){ae("Network request '%s' failed: '%s'. Next attempt is in %s (%d/%d).",`${r.method?.toUpperCase()} ${r.url}`,e.message,(0,Tt.default)(Q(t,e)??0),t,X()),E("Network request '%s' failed: '%s'. Next attempt is in %s (%d/%d).",`${r.method?.toUpperCase()} ${r.url}`,e.message,(0,Tt.default)(Q(t,e)??0),t,X())}var Ct=a.extend("http");var ht={api:null,restApi:null};function pn(t){let e=t==="api"?ne():oe();Ct("client base url: %s",e);let r=le.default.create({baseURL:e,timeout:se(),transitional:{clarifyTimeoutError:!0}});return r.interceptors.request.use(n=>{let o=n["axios-retry"]?.retryCount??0;n.headers.set({"x-cmd-version":$}),n.headers.get("Content-Type")||n.headers.set("Content-Type","application/json");let s={...Ut.default.pick(n,"method","url","headers"),baseURL:e,data:Buffer.isBuffer(n.data)?"buffer":n.data,params:n.params};return o?Ct("network request retry: %o",me({...s,baseURL:e,isRetry:!0})):Ct("network request: %o",me(s)),n}),(0,Ee.default)(r,{retries:X(),retryCondition:t==="restApi"?pe:Rt,retryDelay:(n,o)=>Q(n,o),shouldResetTimeout:!0,onRetry:ue}),r}function z(t){return ht[t]===null&&(ht[t]=pn(t)),ht[t]}function me(t){return{method:t.method,baseURL:t.baseURL,url:t.url,data:t.isRetry?"<retry>":un(t.data),params:t.isRetry?"<retry>":t.params,headers:{...t.headers,Authorization:"Bearer ***","x-currents-key":"***"}}}function un(t){if(t?.results?.raw)return O({...t,results:{...t.results,raw:"***"}});if(typeof t=="string")try{return O(JSON.parse(t))}catch{return t}return Ut.default.isPlainObject(t)?O(t):t}var ge=require("axios"),Ie=u(require("lodash")),C=require("ts-pattern");function Te(t){(0,C.match)(t).when(ge.isAxiosError,mn).otherwise(()=>{E("Unexpected error while sending network request: %s",t)})}function mn(t){return(0,C.match)(t).with({code:"ECONNABORTED"},()=>{E("Network connection aborted")}).with({code:"ECONNREFUSED"},()=>{E("Network connection aborted")}).with({code:"ECONNRESET"},()=>{E("Network connection reset")}).with({code:"ETIMEDOUT"},()=>{E("Network connection timeout")}).with({response:C.P.not(C.P.nullish)},e=>{ln(e,{status:e.response.status,data:e.response.data})}).otherwise(e=>{E(`[currents] Unexpected network error: %s
3
3
  %O`,t.message,{method:t.response?.config.method,url:t.response?.config.url,status:t.response?.status,payload:t.response?.config.data})})}function ln(t,{status:e,data:r}){(0,C.match)(e).with(401,()=>{E(`[currents] ${t.response?.config.method} ${t.response?.config.url} - 401 Unauthorized Request from cloud service`)}).with(400,()=>{E(`[currents] ${t.response?.config.method} ${t.response?.config.url} - 400 Bad Request from cloud service:
4
4
  %o`,r)}).with(404,()=>{E(`[currents] ${t.response?.config.method} ${t.response?.config.url} - 404 Not Found from cloud service`)}).with(429,()=>{E(`[currents] ${t.response?.config.method} ${t.response?.config.url} - 429 Too Many Requests from cloud service`)}).with(422,()=>{En(t,r)}).otherwise(()=>{E(`[currents] Unexpected network response: %s
5
5
  %O`,t.message,{method:t.response?.config.method,url:t.response?.config.url,status:t.response?.status})})}function En(t,e){(0,C.match)(e).with({code:fe.MISSING_SUITE,message:C.P.string,errors:C.P.array(C.P.string)},async r=>{let{message:n,errors:o}=r;W(1),I(...de(n,o))}).with({code:fe.RUN_EXPIRED,message:C.P.string},r=>{E(r.message)}).with({message:C.P.string,errors:C.P.array(C.P.string)},r=>{let{message:n,errors:o}=r;W(1),E(...de(n,o)),W(1)}).otherwise(()=>{E(`[currents] Unexpected network response: %s
6
6
  %O`,t.message,{method:t.response?.config.method,url:t.response?.config.url,status:t.response?.status})})}var fe={RUN_CANCELLED:"RUN_CANCELLED",RUN_EXPIRED:"RUN_EXPIRED",MISSING_SUITE:"MISSING_SUITE"};function de(t,e){return Ie.default.isString(t)?e?.length===0?[t]:[t,`
7
7
  ${(e??[]).map(r=>` - ${r}`).join(`
8
8
  `)}
9
- `]:["Unexpected network error"]}var _e=a.extend("http");async function G(t,e,r=z){try{let n=await r(t).request(e);return _e("network response: %o",{...Re.default.omit(n,"request","config"),url:n.config.url,method:n.config.method}),n}catch(n){let o=n;throw _e("network error: %o",{code:o.code,message:o.message,url:o.config?.url,method:o.config?.method,status:o.response?.status,headers:o.response?.headers,data:o.response?.data}),Te(o),o}}var ei=a.extend("api");var ci=a.extend("api");var he=require("util"),Ue=require("zlib");var Ce=a.extend("api"),fn=(0,he.promisify)(Ue.gzip);async function De(t){try{Ce("Run params: %o",O(t));let e=await dn(JSON.stringify(t));return G("api",{url:"v1/runs",method:"POST",headers:{"Content-Type":"application/json","Content-Encoding":"gzip"},data:e}).then(r=>r.data)}catch(e){throw Ce("Failed to create the run:",e),e}}async function dn(t){try{return await fn(t)}catch(e){throw I("Failed to compress run payload:",e),e}}var hi=a.extend("api");var gn=require("axios");var xi=a.extend("api");var Dt={apiKey:{name:"API key",env:"CURRENTS_API_KEY",cli:"--api-key"},recordKey:{name:"Record key",env:"CURRENTS_RECORD_KEY",cli:"--key"},projectId:{name:"Project ID",env:"CURRENTS_PROJECT_ID",cli:"--project-id"},ciBuildId:{name:"CI build ID",env:"CURRENTS_CI_BUILD_ID",cli:"--ci-build-id"},machineId:{name:"Machine ID",env:"CURRENTS_MACHINE_ID",cli:"--machine-id"},tag:{name:"Tag",cli:"--tag"},debug:{name:"Debug",env:"CURRENTS_DEBUG",cli:"--debug"}};var{debug:In,ciBuildId:Tn,recordKey:_n,projectId:Rn,machineId:Cn}=Dt,hn={debug:In,ciBuildId:Tn,recordKey:_n,projectId:Rn,machineId:Cn,tag:{...Dt.tag,env:"CURRENTS_TAG"},disableTitleTags:{name:"Disable title tags",env:"CURRENTS_DISABLE_TITLE_TAGS",cli:"--disable-title-tags"},removeTitleTags:{name:"Remove title tags",env:"CURRENTS_REMOVE_TITLE_TAGS",cli:"--remove-title-tags"},reportDir:{name:"Report folder",env:"CURRENTS_REPORT_DIR",cli:"--report-dir"}};var ca=a.extend("config");var Un=null;function Oe(){return Un}var Ot=u(require("fs-extra")),N=require("path");var Dn=u(require("path")),Se={".png":{type:"screenshot",contentType:"image/png"},".jpg":{type:"screenshot",contentType:"image/jpeg"},".jpeg":{type:"screenshot",contentType:"image/jpeg"},".webp":{type:"screenshot",contentType:"image/webp"},".gif":{type:"screenshot",contentType:"image/gif"},".mp4":{type:"video",contentType:"video/mp4"},".webm":{type:"video",contentType:"video/webm"},".svg":{type:"attachment",contentType:"image/svg+xml"},".log":{type:"attachment",contentType:"text/plain"},".txt":{type:"attachment",contentType:"text/plain"},".yml":{type:"attachment",contentType:"text/plain"},".yaml":{type:"attachment",contentType:"text/plain"},".md":{type:"attachment",contentType:"text/markdown"},".html":{type:"attachment",contentType:"text/html"},".csv":{type:"attachment",contentType:"text/csv"},".json":{type:"attachment",contentType:"application/json"},".pdf":{type:"attachment",contentType:"application/pdf"},".gz":{type:"attachment",contentType:"application/gzip"},".viewhierarchy":{type:"attachment",contentType:"application/xml"}};var ye=u(require("fs-extra")),Ne=require("path"),At=a.extend("detox"),An="detox.json";function Le(t){return[...t].sort((e,r)=>(e.session??0)-(r.session??0)||e.invocations-r.invocations)}async function xe(t){let e=(0,Ne.join)(t,An);try{let r=await ye.default.readJson(e);if(typeof r?.artifactsRootDir!="string"||!Array.isArray(r?.tests)){At("Unexpected Detox manifest contents at %s",e);return}return At("Detox manifest: %o",r),r}catch{At("No Detox manifest at %s",e);return}}var Z=require("path"),On=a.extend("detox"),Be=255,Sn=/[/\\?<>:*|"$\u0000-\u001f]/g,Pe=4;function we(t){return yn(t)??Nn(t)}function yn({rootDir:t,fullName:e,status:r,invocations:n}){try{let o=require.resolve("detox/src/artifacts/utils/ArtifactPathBuilder",{paths:[process.cwd()]}),s=require(o),c=new s({rootDir:t});return(0,Z.dirname)(c.buildPathForTestArtifact("test.mp4",{fullName:e,status:r,invocations:n}))}catch(o){On("Detox path builder is not available: %o",o);return}}function Nn({rootDir:t,fullName:e,status:r,invocations:n}){let o=xn(r),s=n>1?` (${n})`:"",c=e.slice(-Be+o.length+s.length),p=`${o}${c}${s}`.replace(Sn,"_");return(0,Z.join)(t,Ln(p,Be))}function Ln(t,e){let r=Buffer.from(t,"utf8");return r.length<=e?t:r.subarray(0,e).toString("utf8").replace(/\uFFFD$/,"")}function xn(t){switch(t){case"passed":return"\u2713 ";case"failed":return"\u2717 ";default:return""}}var be=u(require("fs-extra")),ve=require("path"),Me=a.extend("detox"),tt="detox.trace.json",Bn="ws-client-invocation";async function Fe(t){let e=(0,ve.join)(t,tt),r=new Map,n;try{n=await be.default.readJson(e)}catch{return Me("No Detox trace at %s",e),r}if(!Array.isArray(n))return Me("Unexpected Detox trace contents at %s",e),r;let o=Pn(n);return Mn(n).forEach(({pid:c,ts:p,step:l})=>{o.filter(f=>f.pid===c&&p>=f.startTs&&p<=f.endTs).sort((f,R)=>f.startTs-R.startTs).pop()?.steps.push(l)}),o.forEach(({fullName:c,invocations:p,steps:l})=>{let m=r.get(c)??[];m.push({fullName:c,invocations:p,steps:l.sort((f,R)=>+new Date(f.startTime)-+new Date(R.startTime))}),r.set(c,m)}),r}function Pn(t){let e=new Map,r=[];t.forEach(o=>{let s=`${o.pid}:${o.tid}`,c=e.get(s)??[];if(e.set(s,c),o.ph==="B"){c.push(wn(o));return}if(o.ph==="E"){let p=c.pop();p&&r.push({...p,endTs:Number(o.ts)})}});let n=[...e.values()].flatMap(o=>o.filter(s=>s!==void 0));return[...r,...n]}function wn(t){let e=t.args?.fullName;if(!(t.args?.context!=="test"||typeof e!="string"))return{fullName:e,invocations:Number(t.args?.invocations??1),pid:Number(t.pid),startTs:Number(t.ts),endTs:Number.MAX_SAFE_INTEGER,steps:[]}}function Mn(t){let e=new Map,r=[];return t.forEach(n=>{if(!n.cat?.includes(Bn))return;let o=`${n.pid}:${n.tid}`,s=e.get(o)??[];if(n.ph==="B"){s.push({name:n.name??"action",cat:n.cat,ts:Number(n.ts)}),e.set(o,s);return}if(n.ph==="E"){let c=s.pop();if(!c)return;r.push({pid:Number(n.pid),ts:c.ts,step:{title:c.name,category:"detox",startTime:new Date(c.ts/1e3).toISOString(),duration:Math.round((Number(n.ts)-c.ts)/1e3),steps:[]}})}}),r}var H=a.extend("detox"),Ge="artifacts",bn=[".mp4",".png",".jpg",".log",".txt",".json",".viewhierarchy"],vn=t=>{let e=(0,N.extname)(t);return bn.includes(e)?Se[e]:void 0};async function ke({instances:t,reportDir:e,manifest:r}){let n=Gn(r),o=await Fe(r.artifactsRootDir),s=await Zt((0,N.join)(e,Ge)),c={artifacts:0,steps:0};for(let p of t)for(let l of p.results.tests){let m=n.get(l.testId);if(!m){H("No Detox manifest entry for %s",l.testId);continue}await kn({test:l,manifestTest:m,rootDir:r.artifactsRootDir,artifactsDir:s,traceSlices:o.get(m.fullName)??[],result:c})}return c.artifacts+=await Fn({instances:t,rootDir:r.artifactsRootDir,artifactsDir:s}),c}async function Fn({instances:t,rootDir:e,artifactsDir:r}){if(!await Ot.default.pathExists((0,N.join)(e,tt)))return 0;let[n]=await He(e,[tt],r),o=t.map(s=>s.results.tests[0]).filter(s=>s!==void 0);return o.forEach(s=>{s.artifacts=[...s.artifacts??[],n]}),o.length}function Gn(t){let e=new Map;return t.tests.forEach(r=>{e.set(r.fullName,[...e.get(r.fullName)??[],r.testId])}),new Map(t.tests.filter(r=>{let n=e.get(r.fullName)?.length===1;return n||H("Ambiguous Detox test name, skipping: %s",r.fullName),n}).map(r=>[r.testId,r]))}async function kn({test:t,manifestTest:e,rootDir:r,artifactsDir:n,traceSlices:o,result:s}){let c=[...t.attempts].sort((m,f)=>m.attempt-f.attempt),p=Le(e.attempts),l=1;for(let[m,f]of p.entries()){let R=c[m];if(!R){H("No reported attempt %d of %s",m,e.fullName);continue}let g=await Hn({fullName:e.fullName,status:f.status,rootDir:r,artifactsDir:n,fromInvocation:l});g&&(l=g.invocation+1,R.artifacts=[...R.artifacts??[],...g.artifacts],s.artifacts+=g.artifacts.length);let S=Kn(o,m,g?.invocation);S.length&&(R.steps=[...R.steps??[],...S],s.steps+=S.length)}}async function Hn({fullName:t,status:e,rootDir:r,artifactsDir:n,fromInvocation:o}){for(let s=o;s<o+Pe;s++){let c=we({rootDir:r,fullName:t,status:e,invocations:s}),p=await jn(c);if(p)return{invocation:s,artifacts:await He(c,p,n)}}H("No Detox artifacts for %s [%s]",t,e)}async function jn(t){try{return(await Ot.default.readdir(t)).sort()}catch{return}}async function He(t,e,r){let n=[];for(let o of e){let s=vn(o);if(!s){H("Skipping unsupported Detox artifact %s",o);continue}let c=(0,N.join)(t,o),p=`${re(c)}${(0,N.extname)(o)}`;await te(c,(0,N.join)(r,p)),n.push({...s,path:(0,N.join)(Ge,p),name:o})}return n}function Kn(t,e,r){return((r===void 0?void 0:t.find(s=>s.invocations===r))??[...t].sort((s,c)=>s.invocations-c.invocations)[e])?.steps??[]}var x=class{constructor(e){this.config=e}async getFullTestSuite(){return[]}};var Yn=u(require("crypto"));var je=u(require("fs-extra")),Jn=u(require("path"));async function et(t){let e=await je.default.pathExists(t);if(!e)throw new Error("File does not exist");return e}function Ke(){return"root"}function Je(t){let e=(t.join(" ").match(/@(\S+)/g)??[]).filter(Boolean).map(r=>r);return Array.from(new Set([...e].map(r=>r.trim()).map(r=>r.replace("@",""))))}var $n=/^[0-9a-f]{32}$/;function Ye(t){let e=[];for(let r of t){let n=e.find(o=>o.name===r.groupId);n||(n={name:r.groupId,tags:[],tests:[]},e.push(n)),n.tests.push(...Ve(r))}return e.length===1&&$n.test(e[0].name)&&(e[0].name=Ke()),e}function $e(t,e,r){let n=[];for(let{projectId:o,spec:s}of e){let c=r.find(l=>l.spec===s&&l.groupId===o)??(t.length===1?r.find(l=>l.spec===s):void 0);if(!c){n.push(s);continue}let p=t.length===1?t[0]:t.find(l=>l.name===o);p||(p={name:o,tags:[],tests:[]},t.push(p)),p.tests.push(...Ve(c))}return n}function Ve(t){return t.results.tests.map(e=>({spec:t.spec,testId:e.testId,title:e.title,tags:e.tags??Je(e.title)}))}var cr=u(require("fs-extra")),pr=u(require("tmp"));var ir=require("lodash");function We(t){let e=[];for(let[r,n]of Object.entries(t))r==="_"||r==="$0"||r.includes("-")||(typeof n=="boolean"?n&&e.push(`--${r}`):Array.isArray(n)?n.forEach(o=>{e.push(`--${r}=${o}`)}):e.push(`--${r}=${n}`));return e.join(" ")}var qe=require("lodash"),Vn=["bail","clearCache","collectCoverage","collectCoverageFrom","color","colors","config","coverage","coverageDirectory","coveragePathIgnorePatterns","coverageProvider","coverageReporters","coverageThreshold","debug","detectLeaks","detectOpenHandles","errorOnDeprecated","expand","forceExit","json","listTests","logHeapUsage","noStackTrace","notify","notifyMode","openHandlesTimeout","outputFile","reporters","runner","shard","showConfig","showSeed","silent","testFailureExitCode","testNamePattern","verbose","waitNextEventLoopTurnForUnhandledRejectionEvents","watch","watchAll","watchPathIgnorePatterns","watchman"];function Qe(t){return(0,qe.omit)(t,...Vn)}var or=u(require("fs")),st=require("lodash"),yt=u(require("path"));var St=u(require("fs")),rt=require("module"),nt=u(require("path")),Xe=u(require("semver")),Wn=">=29.5.0";function qn(){let t=(0,rt.createRequire)(nt.default.join(process.cwd(),"package.json"));if(Qn(t)==="jest-cli")return t.resolve("jest-cli");try{return(0,rt.createRequire)(t.resolve("jest")).resolve("jest-cli")}catch{}try{return t.resolve("jest-cli")}catch{throw new Error(`Jest discovery needs the "jest" package, and it is not installed in ${process.cwd()}. Run the command from the folder of the project that ran the tests, or install Jest 29.5 or later: npm install --save-dev jest`)}}function Qn(t){for(let e of t.resolve.paths("jest")??[]){if(St.default.existsSync(nt.default.join(e,"jest","package.json")))return"jest";if(St.default.existsSync(nt.default.join(e,"jest-cli","package.json")))return"jest-cli"}return null}function ze(){let t=(0,rt.createRequire)(qn()),{version:e}=t("jest-cli/package.json");if(!Xe.default.satisfies(e,Wn,{includePrerelease:!0}))throw new Error(`Jest discovery needs Jest 29.5 or later, and ${process.cwd()} has Jest ${e}. Update Jest: npm install --save-dev jest@latest`);return t}function Ze(){return ze()("jest-cli")}function tr(){return ze()("jest-config")}function ot(t,e){return(...r)=>new Promise((n,o)=>{let s=0,c=()=>{s++;try{let p=t(...r);n(p)}catch(p){if(s>=e.length)o(p);else{let l=e[s-1];setTimeout(c,l)}}};c()})}var er=a.extend("jest-discovery");function rr(t){return["testEnvironment","globalSetup","globalTeardown"].some(e=>String(t[e]??"").includes("detox"))}function nr(t){return{...(0,st.omit)(t,["globalSetup","globalTeardown","testEnvironmentOptions"]),testEnvironment:"node"}}async function sr(t,e){let r=e.detox;try{let{readInitialOptions:n}=tr(),{config:o,configPath:s}=await n(t);r||=[o,...o.projects??[]].some(g=>typeof g!="string"&&rr(g));let c=["collectCoverage","collectCoverageFrom","coverageDirectory","coveragePathIgnorePatterns","coverageProvider","coverageReporters","coverageThreshold","errorOnDeprecated","forceCoverageMatch","notify","notifyMode","openHandlesTimeout","reporters","runner","showSeed","testFailureExitCode","verbose","watchPathIgnorePatterns","watchPlugins","watchman","bail","clearCache","color","colors","debug","detectLeaks","detectOpenHandles","expand","forceExit","json","listTests","logHeapUsage","noStackTrace","outputFile","shard","showConfig","silent","testNamePattern","waitNextEventLoopTurnForUnhandledRejectionEvents","watch","watchAll"],p=["collectCoverageFrom","coverageDirectory","coveragePathIgnorePatterns","detectLeaks","detectOpenHandles","errorOnDeprecated","forceCoverageMatch","openHandlesTimeout","runner","watchPathIgnorePatterns"],l=g=>e.detox||rr(g),m=(0,st.omit)(o,c);if(l(m)&&(m=nr(m)),m.projects&&(m.projects=m.projects.map(g=>{if(typeof g=="string")return g;let S=(0,st.omit)(g,p);return l(S)?nr(S):S})),m.rootDir&&Object.keys(m).length===1)return null;let f=yt.default.resolve(s?yt.default.dirname(s):process.cwd(),`.jest-scanner-${new Date().getTime()}.config.cjs`),R=`module.exports=${JSON.stringify(m,null,2)}`;return er("configFileContent: %O",R),or.default.writeFileSync(f,R),await ot(et,[200,200,200,200,200,1e3])(f),f}catch(n){if(er("error %o",n),r)throw new Error(`Failed to recreate the Jest config for discovery: ${n.message}`);return I("Failed to recreate the config file"),null}}async function ar(t,e){let r="!!##ThisPatternWillNotMatchAnyTestName##!!",n=t.options,o=Qe(n),s=We(o),c=n.config,p=await sr(c,e);return{cliArgs:[s,"--testNamePattern",r,"--reporters",require.resolve("@currents/cmd/discovery/jest"),"--shard=1/1","--testFailureExitCode=0",p?`--config=${p}`:"",...t.args].filter(m=>!(0,ir.isEmpty)(m)),configFilePath:p}}var Xn=a.extend("jest-discovery");async function ur(t,e){console.time(v("@currents/jest:fullTestSuite-ready"));let{run:r}=Ze(),{cliArgs:n,configFilePath:o}=await ar(t,e);try{let s=pr.default.fileSync({postfix:".json"});return Xn("running scanner: %o",n),process.env.CURRENTS_DISCOVERY_PATH=s.name,await r(n.concat(["--openHandlesTimeout=0"])),await ot(et,Array.from({length:300},()=>100))(s.name),console.timeEnd(v("@currents/jest:fullTestSuite-ready")),await M(s.name)}catch(s){return I("Failed to obtain the jest full test suite:",s),{fullTestSuite:[],specsWithoutResults:[]}}finally{o&&cr.default.unlinkSync(o)}}var mr=a.extend("jest-discovery"),it=class extends x{constructor(r,n){super(r);this.instances=n}async getFullTestSuite(){if(!this.config.frameworkConfig?.shard)return mr("Not a sharded run, listing the tests of the results"),Ye(this.instances);let{fullTestSuite:r,specsWithoutResults:n}=await ur(this.config.cliArgs,{detox:this.config.frameworkConfig.originFramework==="detox"});if(n.length===0)return r;for(let{spec:s,message:c}of n)E("Discovery could not load %s: %s",s,zn(c));let o=$e(r,n,this.instances);return E("The tests of these files are listed from the results of the shard that ran them. Currents can show the run as finished before the other shards upload."),mr("Files that did not run on this shard: %o",o),r.filter(s=>s.tests.length>0)}};function zn(t){return t.split(`
10
- `).map(e=>e.trim()).find(e=>e&&!e.startsWith("\u25CF"))??""}var Er=u(require("fs-extra"));var lr=u(require("path"));function at(t){return lr.default.join(t,"fullTestSuite.json")}var Zn=a.extend("junit-discovery");async function fr(t){console.time(v("@currents/junit:fullTestSuite-ready"));try{Zn("running scanner: %o",t);let e=at(t);process.env.CURRENTS_DISCOVERY_PATH=e;let r=Er.default.readFileSync(e,"utf-8");return JSON.parse(r)}catch(e){return I("Failed to obtain the junit full test suite:",e),[]}}var ct=class extends x{constructor(e,r){super(e),this.reportDir=r}async getFullTestSuite(){return fr(this.reportDir)}};function dr(t,e,r){switch(t.framework){case"jest":return new it(t,r);case"junit":return new ct(t,e);default:return new x(t)}}var B=u(require("fs-extra")),L=u(require("path"));async function gr(t){let e=await to(t?.reportDir);return{reportDir:e,configFilePath:t?.configFilePath??L.default.join(e,"config.json")}}async function to(t){if(t){if(!await B.default.pathExists(t))throw new Error(`No reports found: the folder "${t}" does not exist.`);return t}let e=(0,L.join)(process.cwd(),".currents"),r=await B.default.pathExists(e)?await eo(e):null;if(!r)throw new Error(`No reports found: there is no report folder in "${e}". Run the tests with a Currents reporter first, or pass --report-dir with the folder of the reports.`);return r}async function eo(t){let e=await B.default.readdir(t),r=null;for(let n of e){let o=L.default.join(t,n),s=await B.default.stat(o);s.isDirectory()&&(!r||s.birthtime>r.birthtime)&&(r={name:n,birthtime:s.birthtime})}return r?(0,L.resolve)(t,r.name):null}async function Nt(t){try{return await B.default.pathExists(t)}catch{return I("Error checking if path exists:",I),!1}}async function Ir(t){let e=L.default.join(t,"instances");return ro(e)}async function ro(t){let e=await B.default.readdir(t),r=[];for(let n of e){let o=L.default.join(t,n);(await B.default.stat(o)).isFile()&&r.push(o)}return r}var no=t=>Buffer.byteLength(JSON.stringify(t),"utf8"),Tr=(t,e=1048576)=>{let r=[],n=[],o=0;for(let s of t){let c=no(s);o+c>e&&(r.push(n),n=[],o=0),n.push(s),o+=c}return n.length>0&&r.push(n),r};var oo=3e4;async function hr(){let t=Oe();if(!t)throw new Error("Currents config is missing!");let e=await gr(t);Mt(io(e.reportDir)),a("Reporter options: %o",e),V("Report directory: %s",e.reportDir);let r=await M(e.configFilePath);a("Report config: %o",r);let n=await Ir(e.reportDir);a("Found %d instance results in the reportDir: %s",n.length,e.reportDir);let o=so(e.reportDir),s=await Nt(o),c=at(e.reportDir),p=null;if(s){let T=await M(o);E("Marker file detected. The report was already uploaded: %o",{runUrl:T.response.runUrl,isoDate:T.isoDate})}let l=[];for(let T of n)l.push(await M(T));if(p=await ao(c),p)a("Full test suite file detected: %s",c);else{let y=await dr(r,e.reportDir,l).getFullTestSuite();if(!Ur(y)||Dr(y))throw new Error("Failed to discover the full test suite!");p=y,await It(c,JSON.stringify(p))}let m=p.length===1?p[0].name:null,f={currents:t},R={type:r.framework,version:r.frameworkVersion,clientVersion:$,frameworkConfig:{originFramework:r.frameworkConfig?.originFramework,originFrameworkVersion:r.frameworkConfig?.originFrameworkVersion}},g=J.userFacingNanoid(),S=kt(t.ciBuildId),P={};for(let T of l)P[T.groupId]||(P[T.groupId]=[]),P[T.groupId].push(T);let xt=await xe(e.reportDir);if(xt){let T=await ke({instances:Object.values(P).flat(),reportDir:e.reportDir,manifest:xt});V("[currents] Attached %d Detox artifacts and %d steps",T.artifacts,T.steps)}let j=new Map;Object.values(P).forEach(T=>{T.forEach(y=>{y.artifacts?.forEach(D=>{D&&j.set(D.path,D.contentType)}),y.results.tests.forEach(D=>{D.artifacts?.forEach(U=>{U&&j.set(U.path,U.contentType)}),D.attempts.forEach(U=>{U.artifacts?.forEach(w=>{w&&j.set(w.path,w.contentType)})})})})});for await(let T of Object.keys(P)){let y=P[T],D=T;m&&(a("Default group found: %s, overwriting the group in the results",m),D=m,y=y.map(U=>({...U,groupId:m})));try{let U=Tr(y),w=await _r({ci:S,group:D,instances:[],fullTestSuite:p,config:f,machineId:g,framework:R});for(let ut=0;ut<U.length;ut++){let mt=await _r({ci:S,group:D,instances:U[ut],fullTestSuite:[],config:f,machineId:g,framework:R});mt.artifactUploadUrls&&mt.artifactUploadUrls.length>0&&await co(mt.artifactUploadUrls,e.reportDir,j)}a("Api response: %o",w),V("[%s] Run created: %s",D,w.runUrl);let Ar={response:w,isoDate:new Date().toISOString()};await It(o,JSON.stringify(Ar)),a("Marker file %s: %s",s?"overwritten":"created",o)}catch(U){throw a("Failed to upload the results to the dashboard"),U}}}async function _r({ci:t,group:e,instances:r,fullTestSuite:n,config:o,machineId:s,framework:c}){let p=await Kt(),l=await Vt(),m={browserName:"node",browserVersion:Cr.default.coerce(process.version)?.version},{currents:f}=o,g={platform:{...m,...l},ci:t,commit:p,group:e,fullTestSuite:n,config:o,projectId:f.projectId,recordKey:f.recordKey,ciBuildId:t.ciBuildId.value??void 0,tags:f.tag??[],machineId:f.machineId??s,framework:c,instances:r,previousCiBuildId:process.env.CURRENTS_PREVIOUS_CI_BUILD_ID};return a("Creating run: %o",O(g)),De(g)}function so(t){return pt.default.join(t,"upload.marker.json")}function io(t){return pt.default.join(t,`.debug-${new Date().toISOString()}.log`)}async function ao(t){if(!await Nt(t))return null;try{let e=await M(t);return!Ur(e)||Dr(e)?(E("Ignoring %s, it is not a list of projects and tests",t),null):e}catch(e){return E("Ignoring %s, it is not valid JSON: %s",t,e),null}}function Ur(t){return Array.isArray(t)&&t.every(e=>typeof e?.name=="string"&&Array.isArray(e.tests)&&e.tests.every(r=>typeof r?.spec=="string"&&typeof r.testId=="string"&&Array.isArray(r.title)&&r.title.every(n=>typeof n=="string")))}function Dr(t){return t.length===0||t.some(e=>e.tests.length===0)}async function co(t,e,r){a("Uploading %d artifacts",t.length),await Promise.all(t.map(n=>{let o=pt.default.join(e,n.path),s=r.get(n.path)||"application/octet-stream";return po(o,s,n.uploadUrl)}))}var po=async(t,e,r)=>{try{if(!await Lt.default.pathExists(t)){E("Artifact file not found: %s",t);return}let n=await Lt.default.readFile(t);await Rr.default.put(r,n,{headers:{"Content-Type":e},timeout:oo})}catch(n){a("Failed to upload artifact %s: %o",t,n)}};0&&(module.exports={handleCurrentsReport});
9
+ `]:["Unexpected network error"]}var _e=a.extend("http");async function G(t,e,r=z){try{let n=await r(t).request(e);return _e("network response: %o",{...Re.default.omit(n,"request","config"),url:n.config.url,method:n.config.method}),n}catch(n){let o=n;throw _e("network error: %o",{code:o.code,message:o.message,url:o.config?.url,method:o.config?.method,status:o.response?.status,headers:o.response?.headers,data:o.response?.data}),Te(o),o}}var ei=a.extend("api");var ci=a.extend("api");var he=require("util"),Ue=require("zlib");var Ce=a.extend("api"),fn=(0,he.promisify)(Ue.gzip);async function De(t){try{Ce("Run params: %o",O(t));let e=await dn(JSON.stringify(t));return G("api",{url:"v1/runs",method:"POST",headers:{"Content-Type":"application/json","Content-Encoding":"gzip"},data:e}).then(r=>r.data)}catch(e){throw Ce("Failed to create the run:",e),e}}async function dn(t){try{return await fn(t)}catch(e){throw I("Failed to compress run payload:",e),e}}var hi=a.extend("api");var gn=require("axios");var Li=a.extend("api");var Dt={apiKey:{name:"API key",env:"CURRENTS_API_KEY",cli:"--api-key"},recordKey:{name:"Record key",env:"CURRENTS_RECORD_KEY",cli:"--key"},projectId:{name:"Project ID",env:"CURRENTS_PROJECT_ID",cli:"--project-id"},ciBuildId:{name:"CI build ID",env:"CURRENTS_CI_BUILD_ID",cli:"--ci-build-id"},machineId:{name:"Machine ID",env:"CURRENTS_MACHINE_ID",cli:"--machine-id"},tag:{name:"Tag",cli:"--tag"},debug:{name:"Debug",env:"CURRENTS_DEBUG",cli:"--debug"}};var{debug:In,ciBuildId:Tn,recordKey:_n,projectId:Rn,machineId:Cn}=Dt,hn={debug:In,ciBuildId:Tn,recordKey:_n,projectId:Rn,machineId:Cn,tag:{...Dt.tag,env:"CURRENTS_TAG"},disableTitleTags:{name:"Disable title tags",env:"CURRENTS_DISABLE_TITLE_TAGS",cli:"--disable-title-tags"},removeTitleTags:{name:"Remove title tags",env:"CURRENTS_REMOVE_TITLE_TAGS",cli:"--remove-title-tags"},reportDir:{name:"Report folder",env:"CURRENTS_REPORT_DIR",cli:"--report-dir"}};var ca=a.extend("config");var Un=null;function Oe(){return Un}var Ot=u(require("fs-extra")),N=require("path");var Dn=u(require("path")),Se={".png":{type:"screenshot",contentType:"image/png"},".jpg":{type:"screenshot",contentType:"image/jpeg"},".jpeg":{type:"screenshot",contentType:"image/jpeg"},".webp":{type:"screenshot",contentType:"image/webp"},".gif":{type:"screenshot",contentType:"image/gif"},".mp4":{type:"video",contentType:"video/mp4"},".webm":{type:"video",contentType:"video/webm"},".svg":{type:"attachment",contentType:"image/svg+xml"},".log":{type:"attachment",contentType:"text/plain"},".txt":{type:"attachment",contentType:"text/plain"},".yml":{type:"attachment",contentType:"text/plain"},".yaml":{type:"attachment",contentType:"text/plain"},".md":{type:"attachment",contentType:"text/markdown"},".html":{type:"attachment",contentType:"text/html"},".csv":{type:"attachment",contentType:"text/csv"},".json":{type:"attachment",contentType:"application/json"},".pdf":{type:"attachment",contentType:"application/pdf"},".gz":{type:"attachment",contentType:"application/gzip"},".viewhierarchy":{type:"attachment",contentType:"application/xml"}};var ye=u(require("fs-extra")),Ne=require("path"),At=a.extend("detox"),An="detox.json";function xe(t){return[...t].sort((e,r)=>(e.session??0)-(r.session??0)||e.invocations-r.invocations)}async function Le(t){let e=(0,Ne.join)(t,An);try{let r=await ye.default.readJson(e);if(typeof r?.artifactsRootDir!="string"||!Array.isArray(r?.tests)){At("Unexpected Detox manifest contents at %s",e);return}return At("Detox manifest: %o",r),r}catch{At("No Detox manifest at %s",e);return}}var Z=require("path"),On=a.extend("detox"),Be=255,Sn=/[/\\?<>:*|"$\u0000-\u001f]/g,Pe=4;function we(t){return yn(t)??Nn(t)}function yn({rootDir:t,fullName:e,status:r,invocations:n}){try{let o=require.resolve("detox/src/artifacts/utils/ArtifactPathBuilder",{paths:[process.cwd()]}),s=require(o),c=new s({rootDir:t});return(0,Z.dirname)(c.buildPathForTestArtifact("test.mp4",{fullName:e,status:r,invocations:n}))}catch(o){On("Detox path builder is not available: %o",o);return}}function Nn({rootDir:t,fullName:e,status:r,invocations:n}){let o=Ln(r),s=n>1?` (${n})`:"",c=e.slice(-Be+o.length+s.length),p=`${o}${c}${s}`.replace(Sn,"_");return(0,Z.join)(t,xn(p,Be))}function xn(t,e){let r=Buffer.from(t,"utf8");return r.length<=e?t:r.subarray(0,e).toString("utf8").replace(/\uFFFD$/,"")}function Ln(t){switch(t){case"passed":return"\u2713 ";case"failed":return"\u2717 ";default:return""}}var be=u(require("fs-extra")),ve=require("path"),Me=a.extend("detox"),tt="detox.trace.json",Bn="ws-client-invocation";async function Fe(t){let e=(0,ve.join)(t,tt),r=new Map,n;try{n=await be.default.readJson(e)}catch{return Me("No Detox trace at %s",e),r}if(!Array.isArray(n))return Me("Unexpected Detox trace contents at %s",e),r;let o=Pn(n);return Mn(n).forEach(({pid:c,ts:p,step:l})=>{o.filter(f=>f.pid===c&&p>=f.startTs&&p<=f.endTs).sort((f,R)=>f.startTs-R.startTs).pop()?.steps.push(l)}),o.forEach(({fullName:c,invocations:p,steps:l})=>{let m=r.get(c)??[];m.push({fullName:c,invocations:p,steps:l.sort((f,R)=>+new Date(f.startTime)-+new Date(R.startTime))}),r.set(c,m)}),r}function Pn(t){let e=new Map,r=[];t.forEach(o=>{let s=`${o.pid}:${o.tid}`,c=e.get(s)??[];if(e.set(s,c),o.ph==="B"){c.push(wn(o));return}if(o.ph==="E"){let p=c.pop();p&&r.push({...p,endTs:Number(o.ts)})}});let n=[...e.values()].flatMap(o=>o.filter(s=>s!==void 0));return[...r,...n]}function wn(t){let e=t.args?.fullName;if(!(t.args?.context!=="test"||typeof e!="string"))return{fullName:e,invocations:Number(t.args?.invocations??1),pid:Number(t.pid),startTs:Number(t.ts),endTs:Number.MAX_SAFE_INTEGER,steps:[]}}function Mn(t){let e=new Map,r=[];return t.forEach(n=>{if(!n.cat?.includes(Bn))return;let o=`${n.pid}:${n.tid}`,s=e.get(o)??[];if(n.ph==="B"){s.push({name:n.name??"action",cat:n.cat,ts:Number(n.ts)}),e.set(o,s);return}if(n.ph==="E"){let c=s.pop();if(!c)return;r.push({pid:Number(n.pid),ts:c.ts,step:{title:c.name,category:"detox",startTime:new Date(c.ts/1e3).toISOString(),duration:Math.round((Number(n.ts)-c.ts)/1e3),steps:[]}})}}),r}var H=a.extend("detox"),Ge="artifacts",bn=[".mp4",".png",".jpg",".log",".txt",".json",".viewhierarchy"],vn=t=>{let e=(0,N.extname)(t);return bn.includes(e)?Se[e]:void 0};async function ke({instances:t,reportDir:e,manifest:r}){let n=Gn(r),o=await Fe(r.artifactsRootDir),s=await Zt((0,N.join)(e,Ge)),c={artifacts:0,steps:0};for(let p of t)for(let l of p.results.tests){let m=n.get(l.testId);if(!m){H("No Detox manifest entry for %s",l.testId);continue}await kn({test:l,manifestTest:m,rootDir:r.artifactsRootDir,artifactsDir:s,traceSlices:o.get(m.fullName)??[],result:c})}return c.artifacts+=await Fn({instances:t,rootDir:r.artifactsRootDir,artifactsDir:s}),c}async function Fn({instances:t,rootDir:e,artifactsDir:r}){if(!await Ot.default.pathExists((0,N.join)(e,tt)))return 0;let[n]=await He(e,[tt],r),o=t.map(s=>s.results.tests[0]).filter(s=>s!==void 0);return o.forEach(s=>{s.artifacts=[...s.artifacts??[],n]}),o.length}function Gn(t){let e=new Map;return t.tests.forEach(r=>{e.set(r.fullName,[...e.get(r.fullName)??[],r.testId])}),new Map(t.tests.filter(r=>{let n=e.get(r.fullName)?.length===1;return n||H("Ambiguous Detox test name, skipping: %s",r.fullName),n}).map(r=>[r.testId,r]))}async function kn({test:t,manifestTest:e,rootDir:r,artifactsDir:n,traceSlices:o,result:s}){let c=[...t.attempts].sort((m,f)=>m.attempt-f.attempt),p=xe(e.attempts),l=1;for(let[m,f]of p.entries()){let R=c[m];if(!R){H("No reported attempt %d of %s",m,e.fullName);continue}let g=await Hn({fullName:e.fullName,status:f.status,rootDir:r,artifactsDir:n,fromInvocation:l});g&&(l=g.invocation+1,R.artifacts=[...R.artifacts??[],...g.artifacts],s.artifacts+=g.artifacts.length);let S=Kn(o,m,g?.invocation);S.length&&(R.steps=[...R.steps??[],...S],s.steps+=S.length)}}async function Hn({fullName:t,status:e,rootDir:r,artifactsDir:n,fromInvocation:o}){for(let s=o;s<o+Pe;s++){let c=we({rootDir:r,fullName:t,status:e,invocations:s}),p=await jn(c);if(p)return{invocation:s,artifacts:await He(c,p,n)}}H("No Detox artifacts for %s [%s]",t,e)}async function jn(t){try{return(await Ot.default.readdir(t)).sort()}catch{return}}async function He(t,e,r){let n=[];for(let o of e){let s=vn(o);if(!s){H("Skipping unsupported Detox artifact %s",o);continue}let c=(0,N.join)(t,o),p=`${re(c)}${(0,N.extname)(o)}`;await te(c,(0,N.join)(r,p)),n.push({...s,path:(0,N.join)(Ge,p),name:o})}return n}function Kn(t,e,r){return((r===void 0?void 0:t.find(s=>s.invocations===r))??[...t].sort((s,c)=>s.invocations-c.invocations)[e])?.steps??[]}var L=class{constructor(e){this.config=e}async getFullTestSuite(){return[]}};var Yn=u(require("crypto"));var je=u(require("fs-extra")),Jn=u(require("path"));async function et(t){let e=await je.default.pathExists(t);if(!e)throw new Error("File does not exist");return e}function Ke(){return"root"}function Je(t){let e=(t.join(" ").match(/@(\S+)/g)??[]).filter(Boolean).map(r=>r);return Array.from(new Set([...e].map(r=>r.trim()).map(r=>r.replace("@",""))))}var $n=/^[0-9a-f]{32}$/;function Ye(t){let e=[];for(let r of t){let n=e.find(o=>o.name===r.groupId);n||(n={name:r.groupId,tags:[],tests:[]},e.push(n)),n.tests.push(...Ve(r))}return e.length===1&&$n.test(e[0].name)&&(e[0].name=Ke()),e}function $e(t,e,r){let n=[];for(let{projectId:o,spec:s}of e){let c=r.find(l=>l.spec===s&&l.groupId===o)??(t.length===1?r.find(l=>l.spec===s):void 0);if(!c){n.push(s);continue}let p=t.length===1?t[0]:t.find(l=>l.name===o);p||(p={name:o,tags:[],tests:[]},t.push(p)),p.tests.push(...Ve(c))}return n}function Ve(t){return t.results.tests.map(e=>({spec:t.spec,testId:e.testId,title:e.title,tags:e.tags??Je(e.title)}))}var cr=u(require("fs-extra")),pr=u(require("tmp"));var ir=require("lodash");function We(t){let e=[];for(let[r,n]of Object.entries(t))r==="_"||r==="$0"||r.includes("-")||(typeof n=="boolean"?n&&e.push(`--${r}`):Array.isArray(n)?n.forEach(o=>{e.push(`--${r}=${o}`)}):e.push(`--${r}=${n}`));return e.join(" ")}var qe=require("lodash"),Vn=["bail","clearCache","collectCoverage","collectCoverageFrom","color","colors","config","coverage","coverageDirectory","coveragePathIgnorePatterns","coverageProvider","coverageReporters","coverageThreshold","debug","detectLeaks","detectOpenHandles","errorOnDeprecated","expand","forceExit","json","listTests","logHeapUsage","noStackTrace","notify","notifyMode","openHandlesTimeout","outputFile","reporters","runner","shard","showConfig","showSeed","silent","testFailureExitCode","testNamePattern","verbose","waitNextEventLoopTurnForUnhandledRejectionEvents","watch","watchAll","watchPathIgnorePatterns","watchman"];function Qe(t){return(0,qe.omit)(t,...Vn)}var or=u(require("fs")),st=require("lodash"),yt=u(require("path"));var St=u(require("fs")),rt=require("module"),nt=u(require("path")),Xe=u(require("semver")),Wn=">=29.5.0";function qn(){let t=(0,rt.createRequire)(nt.default.join(process.cwd(),"package.json"));if(Qn(t)==="jest-cli")return t.resolve("jest-cli");try{return(0,rt.createRequire)(t.resolve("jest")).resolve("jest-cli")}catch{}try{return t.resolve("jest-cli")}catch{throw new Error(`Jest discovery needs the "jest" package, and it is not installed in ${process.cwd()}. Run the command from the folder of the project that ran the tests, or install Jest 29.5 or later: npm install --save-dev jest`)}}function Qn(t){for(let e of t.resolve.paths("jest")??[]){if(St.default.existsSync(nt.default.join(e,"jest","package.json")))return"jest";if(St.default.existsSync(nt.default.join(e,"jest-cli","package.json")))return"jest-cli"}return null}function ze(){let t=(0,rt.createRequire)(qn()),{version:e}=t("jest-cli/package.json");if(!Xe.default.satisfies(e,Wn,{includePrerelease:!0}))throw new Error(`Jest discovery needs Jest 29.5 or later, and ${process.cwd()} has Jest ${e}. Update Jest: npm install --save-dev jest@latest`);return t}function Ze(){return ze()("jest-cli")}function tr(){return ze()("jest-config")}function ot(t,e){return(...r)=>new Promise((n,o)=>{let s=0,c=()=>{s++;try{let p=t(...r);n(p)}catch(p){if(s>=e.length)o(p);else{let l=e[s-1];setTimeout(c,l)}}};c()})}var er=a.extend("jest-discovery");function rr(t){return["testEnvironment","globalSetup","globalTeardown"].some(e=>String(t[e]??"").includes("detox"))}function nr(t){return{...(0,st.omit)(t,["globalSetup","globalTeardown","testEnvironmentOptions"]),testEnvironment:"node"}}async function sr(t,e){let r=e.detox;try{let{readInitialOptions:n}=tr(),{config:o,configPath:s}=await n(t);r||=[o,...o.projects??[]].some(g=>typeof g!="string"&&rr(g));let c=["collectCoverage","collectCoverageFrom","coverageDirectory","coveragePathIgnorePatterns","coverageProvider","coverageReporters","coverageThreshold","errorOnDeprecated","forceCoverageMatch","notify","notifyMode","openHandlesTimeout","reporters","runner","showSeed","testFailureExitCode","verbose","watchPathIgnorePatterns","watchPlugins","watchman","bail","clearCache","color","colors","debug","detectLeaks","detectOpenHandles","expand","forceExit","json","listTests","logHeapUsage","noStackTrace","outputFile","shard","showConfig","silent","testNamePattern","waitNextEventLoopTurnForUnhandledRejectionEvents","watch","watchAll"],p=["collectCoverageFrom","coverageDirectory","coveragePathIgnorePatterns","detectLeaks","detectOpenHandles","errorOnDeprecated","forceCoverageMatch","openHandlesTimeout","runner","watchPathIgnorePatterns"],l=g=>e.detox||rr(g),m=(0,st.omit)(o,c);if(l(m)&&(m=nr(m)),m.projects&&(m.projects=m.projects.map(g=>{if(typeof g=="string")return g;let S=(0,st.omit)(g,p);return l(S)?nr(S):S})),m.rootDir&&Object.keys(m).length===1)return null;let f=yt.default.resolve(s?yt.default.dirname(s):process.cwd(),`.jest-scanner-${new Date().getTime()}.config.cjs`),R=`module.exports=${JSON.stringify(m,null,2)}`;return er("configFileContent: %O",R),or.default.writeFileSync(f,R),await ot(et,[200,200,200,200,200,1e3])(f),f}catch(n){if(er("error %o",n),r)throw new Error(`Failed to recreate the Jest config for discovery: ${n.message}`);return I("Failed to recreate the config file"),null}}async function ar(t,e){let r="!!##ThisPatternWillNotMatchAnyTestName##!!",n=t.options,o=Qe(n),s=We(o),c=n.config,p=await sr(c,e);return{cliArgs:[s,"--testNamePattern",r,"--reporters",require.resolve("@currents/cmd/discovery/jest"),"--shard=1/1","--testFailureExitCode=0",p?`--config=${p}`:"",...t.args].filter(m=>!(0,ir.isEmpty)(m)),configFilePath:p}}var Xn=a.extend("jest-discovery");async function ur(t,e){console.time(v("@currents/jest:fullTestSuite-ready"));let{run:r}=Ze(),{cliArgs:n,configFilePath:o}=await ar(t,e);try{let s=pr.default.fileSync({postfix:".json"});return Xn("running scanner: %o",n),process.env.CURRENTS_DISCOVERY_PATH=s.name,await r(n.concat(["--openHandlesTimeout=0"])),await ot(et,Array.from({length:300},()=>100))(s.name),console.timeEnd(v("@currents/jest:fullTestSuite-ready")),await M(s.name)}catch(s){return I("Failed to obtain the jest full test suite:",s),{fullTestSuite:[],specsWithoutResults:[]}}finally{o&&cr.default.unlinkSync(o)}}var mr=a.extend("jest-discovery"),it=class extends L{constructor(r,n){super(r);this.instances=n}async getFullTestSuite(){if(!this.config.frameworkConfig?.shard)return mr("Not a sharded run, listing the tests of the results"),Ye(this.instances);let{fullTestSuite:r,specsWithoutResults:n}=await ur(this.config.cliArgs,{detox:this.config.frameworkConfig.originFramework==="detox"});if(n.length===0)return r;for(let{spec:s,message:c}of n)E("Discovery could not load %s: %s",s,zn(c));let o=$e(r,n,this.instances);return E("The tests of these files are listed from the results of the shard that ran them. Currents can show the run as finished before the other shards upload."),mr("Files that did not run on this shard: %o",o),r.filter(s=>s.tests.length>0)}};function zn(t){return t.split(`
10
+ `).map(e=>e.trim()).find(e=>e&&!e.startsWith("\u25CF"))??""}var Er=u(require("fs-extra"));var lr=u(require("path"));function at(t){return lr.default.join(t,"fullTestSuite.json")}var Zn=a.extend("junit-discovery");async function fr(t){console.time(v("@currents/junit:fullTestSuite-ready"));try{Zn("running scanner: %o",t);let e=at(t);process.env.CURRENTS_DISCOVERY_PATH=e;let r=Er.default.readFileSync(e,"utf-8");return JSON.parse(r)}catch(e){return I("Failed to obtain the junit full test suite:",e),[]}}var ct=class extends L{constructor(e,r){super(e),this.reportDir=r}async getFullTestSuite(){return fr(this.reportDir)}};function dr(t,e,r){switch(t.framework){case"jest":return new it(t,r);case"junit":return new ct(t,e);default:return new L(t)}}var B=u(require("fs-extra")),x=u(require("path"));async function gr(t){let e=await to(t?.reportDir);return{reportDir:e,configFilePath:t?.configFilePath??x.default.join(e,"config.json")}}async function to(t){if(t){if(!await B.default.pathExists(t))throw new Error(`No reports found: the folder "${t}" does not exist.`);return t}let e=(0,x.join)(process.cwd(),".currents"),r=await B.default.pathExists(e)?await eo(e):null;if(!r)throw new Error(`No reports found: there is no report folder in "${e}". Run the tests with a Currents reporter first, or pass --report-dir with the folder of the reports.`);return r}async function eo(t){let e=await B.default.readdir(t),r=null;for(let n of e){let o=x.default.join(t,n),s=await B.default.stat(o);s.isDirectory()&&(!r||s.birthtime>r.birthtime)&&(r={name:n,birthtime:s.birthtime})}return r?(0,x.resolve)(t,r.name):null}async function Nt(t){try{return await B.default.pathExists(t)}catch{return I("Error checking if path exists:",I),!1}}async function Ir(t){let e=x.default.join(t,"instances");return ro(e)}async function ro(t){let e=await B.default.readdir(t),r=[];for(let n of e){let o=x.default.join(t,n);(await B.default.stat(o)).isFile()&&r.push(o)}return r}var no=t=>Buffer.byteLength(JSON.stringify(t),"utf8"),Tr=(t,e=1048576)=>{let r=[],n=[],o=0;for(let s of t){let c=no(s);o+c>e&&(r.push(n),n=[],o=0),n.push(s),o+=c}return n.length>0&&r.push(n),r};var oo=3e4;async function hr(){let t=Oe();if(!t)throw new Error("Currents config is missing!");let e=await gr(t);Mt(io(e.reportDir)),a("Reporter options: %o",e),V("Report directory: %s",e.reportDir);let r=await M(e.configFilePath);a("Report config: %o",r);let n=await Ir(e.reportDir);a("Found %d instance results in the reportDir: %s",n.length,e.reportDir);let o=so(e.reportDir),s=await Nt(o),c=at(e.reportDir),p=null;if(s){let T=await M(o);E("Marker file detected. The report was already uploaded: %o",{runUrl:T.response.runUrl,isoDate:T.isoDate})}let l=[];for(let T of n)l.push(await M(T));if(p=await ao(c),p)a("Full test suite file detected: %s",c);else{let y=await dr(r,e.reportDir,l).getFullTestSuite();if(!Ur(y)||Dr(y))throw new Error("Failed to discover the full test suite!");p=y,await It(c,JSON.stringify(p))}let m=p.length===1?p[0].name:null,f={currents:t},R={type:r.framework,version:r.frameworkVersion,clientVersion:$,frameworkConfig:{originFramework:r.frameworkConfig?.originFramework,originFrameworkVersion:r.frameworkConfig?.originFrameworkVersion}},g=J.userFacingNanoid(),S=kt(t.ciBuildId),P={};for(let T of l)P[T.groupId]||(P[T.groupId]=[]),P[T.groupId].push(T);let Lt=await Le(e.reportDir);if(Lt){let T=await ke({instances:Object.values(P).flat(),reportDir:e.reportDir,manifest:Lt});V("[currents] Attached %d Detox artifacts and %d steps",T.artifacts,T.steps)}let j=new Map;Object.values(P).forEach(T=>{T.forEach(y=>{y.artifacts?.forEach(D=>{D&&j.set(D.path,D.contentType)}),y.results.tests.forEach(D=>{D.artifacts?.forEach(U=>{U&&j.set(U.path,U.contentType)}),D.attempts.forEach(U=>{U.artifacts?.forEach(w=>{w&&j.set(w.path,w.contentType)})})})})});for await(let T of Object.keys(P)){let y=P[T],D=T;m&&(a("Default group found: %s, overwriting the group in the results",m),D=m,y=y.map(U=>({...U,groupId:m})));try{let U=Tr(y),w=await _r({ci:S,group:D,instances:[],fullTestSuite:p,config:f,machineId:g,framework:R});for(let ut=0;ut<U.length;ut++){let mt=await _r({ci:S,group:D,instances:U[ut],fullTestSuite:[],config:f,machineId:g,framework:R});mt.artifactUploadUrls&&mt.artifactUploadUrls.length>0&&await co(mt.artifactUploadUrls,e.reportDir,j)}a("Api response: %o",w),V("[%s] Run created: %s",D,w.runUrl);let Ar={response:w,isoDate:new Date().toISOString()};await It(o,JSON.stringify(Ar)),a("Marker file %s: %s",s?"overwritten":"created",o)}catch(U){throw a("Failed to upload the results to the dashboard"),U}}}async function _r({ci:t,group:e,instances:r,fullTestSuite:n,config:o,machineId:s,framework:c}){let p=await Kt(),l=await Vt(),m={browserName:"node",browserVersion:Cr.default.coerce(process.version)?.version},{currents:f}=o,g={platform:{...m,...l},ci:t,commit:p,group:e,fullTestSuite:n,config:o,projectId:f.projectId,recordKey:f.recordKey,ciBuildId:t.ciBuildId.value??void 0,tags:f.tag??[],machineId:f.machineId??s,framework:c,instances:r,previousCiBuildId:process.env.CURRENTS_PREVIOUS_CI_BUILD_ID};return a("Creating run: %o",O(g)),De(g)}function so(t){return pt.default.join(t,"upload.marker.json")}function io(t){return pt.default.join(t,`.debug-${new Date().toISOString()}.log`)}async function ao(t){if(!await Nt(t))return null;try{let e=await M(t);return!Ur(e)||Dr(e)?(E("Ignoring %s, it is not a list of projects and tests",t),null):e}catch(e){return E("Ignoring %s, it is not valid JSON: %s",t,e),null}}function Ur(t){return Array.isArray(t)&&t.every(e=>typeof e?.name=="string"&&Array.isArray(e.tests)&&e.tests.every(r=>typeof r?.spec=="string"&&typeof r.testId=="string"&&Array.isArray(r.title)&&r.title.every(n=>typeof n=="string")))}function Dr(t){return t.length===0||t.some(e=>e.tests.length===0)}async function co(t,e,r){a("Uploading %d artifacts",t.length),await Promise.all(t.map(n=>{let o=pt.default.join(e,n.path),s=r.get(n.path)||"application/octet-stream";return po(o,s,n.uploadUrl)}))}var po=async(t,e,r)=>{try{if(!await xt.default.pathExists(t)){E("Artifact file not found: %s",t);return}let n=await xt.default.readFile(t);await Rr.default.put(r,n,{headers:{"Content-Type":e},timeout:oo})}catch(n){a("Failed to upload artifact %s: %o",t,n)}};0&&(module.exports={handleCurrentsReport});
11
11
  /*! For license information please see index.js.LEGAL.txt */
12
12
  //# sourceMappingURL=index.js.map
@@ -5,122 +5,40 @@ description: Run the Currents CLI (the `currents` command of the npm package @cu
5
5
 
6
6
  # Currents CLI
7
7
 
8
- `currents` sends test results and files to Currents. It is the command of the npm package `@currents/cmd`.
9
-
10
- ## Install
11
-
12
- ```bash
13
- npm install --save-dev @currents/cmd
14
- ```
15
-
16
- In the project, run it as `npx currents`. Outside a project, use `npx --package @currents/cmd currents`: without the package installed, `npx currents` runs an unrelated npm package named `currents`.
8
+ `currents` is the command of the npm package `@currents/cmd`. In a project that has the package, run `npx currents`. Elsewhere, run `npx --package @currents/cmd currents`: `npx currents` alone runs an unrelated npm package.
17
9
 
18
10
  ## Pick the command
19
11
 
20
- | Task | Command |
21
- | ---------------------------------------------------------------------------- | ------------------------------------------------------------- |
22
- | Upload the results a Currents reporter wrote (Jest, Node test runner, Detox) | `currents run upload` |
23
- | Report JUnit XML results | `currents run upload --input-format junit` |
24
- | Attach logs or other files to a run that CI recorded | `currents run attach` |
25
- | Cancel a run when its CI workflow is cancelled | `currents run cancel` |
26
- | Record a browser session and share a link to it | `currents session start`, `session attach`, `session share` |
27
- | Save the last run so that a CI rerun runs only the failed Playwright tests | `currents cache set` and `cache get` with `--preset last-run` |
28
- | Save files in one CI job and restore them in another | `currents cache set` and `cache get` with `--id` |
29
- | Get the data of a run | `currents run get` |
30
- | Call any other REST API route, such as listing runs or cancelling a run | `currents api <path>` |
12
+ - `currents run upload`: upload the results of a Currents reporter (Jest, Node test runner, Detox). With `--input-format junit`, upload JUnit XML.
13
+ - `currents run attach`: attach logs or other files to a run that CI recorded.
14
+ - `currents run cancel`: cancel a run when its CI workflow is cancelled.
15
+ - `currents run get`: get the data of a run.
16
+ - `currents session start`, then `session attach` and `session share`: record a browser session and share a link to it.
17
+ - `currents cache set` and `cache get` with `--preset last-run`: rerun only the failed Playwright tests in a CI rerun. With `--id`: save files in one CI job and restore them in another.
18
+ - `currents api <path>`: call any other REST API route.
31
19
 
32
20
  `@currents/playwright` and the Cypress integration send results themselves. Do not add `currents run upload` after them.
33
21
 
34
- Run `currents <command> --help` for the options and more examples of a command. The help is the reference: do not guess an option that it does not list.
35
-
36
- ## Examples
37
-
38
- These are the examples from `--help`:
39
-
40
- ```bash
41
- currents run upload --key <record-key> --project-id <id> --ci-build-id <build-id>
42
- currents run upload --key <record-key> --project-id <id> --ci-build-id <build-id> --input-format junit --input-file "./*.xml" --framework postman
43
- currents run attach --key <record-key> --project-id <id> --ci-build-id <build-id> --machine-id shard-1 docker-logs.zip
44
- currents run attach --key <record-key> --project-id <id> --ci-build-id <build-id> --spec tests/cart.spec.ts --test-title "adds an item" --attempt 0 screenshot.png
45
- currents run cancel --key <record-key> --project-id <id> --ci-build-id <build-id>
46
- currents cache set --key <record-key> --preset last-run
47
- currents cache get --key <record-key> --preset last-run
48
- currents run get --api-key <api-key> --project-id <project-id> --ci-build-id <ci-build-id>
49
- ```
50
-
51
- - With `--input-format`, `run upload` converts the reports to the Currents format first, then uploads them. Put quotes around the `--input-file` pattern so that the CLI expands it, not the shell: the shell passes only the first file.
52
- - Without `--id`, `cache set` and `cache get` use an ID made from the CI job. When they warn `No CI job detected`, pass the same `--id` to both.
53
- - Without `--spec`, `run attach` attaches the files to the whole run. `--machine-id` names the CI machine the files come from; run-level files are listed by machine when it is set. `--spec`, `--test-title` and `--attempt` attach to a spec file, a test or one attempt of a test (the first attempt is `0`).
54
-
55
- ## Call the REST API
56
-
57
- `currents api <path>` sends a request to any route of the Currents REST API with the API key and prints the response body. Use it when no other command does the task. The routes are in the REST API docs: https://docs.currents.dev/resources/api/api-resources
58
-
59
- ```bash
60
- currents api /v1/runs/<run-id>
61
- currents api /v1/projects/<project-id>/runs -X GET -f "branches[]=main" -f status=FAILED
62
- currents api /v1/runs/<run-id>/cancel -X PUT
63
- ```
64
-
65
- - The path can start with `/v1/`, `v1/` or the route name.
66
- - `-f key=value` adds a field; `true`, `false`, `null` and numbers are sent as JSON values. `-F key=value` adds a field that is always a string.
67
- - Without `-X`, fields make the request a POST with the fields in a JSON body. A GET sends them in the query string, so pass `-X GET` with fields.
68
- - `--input <file>` sends the file as the body; the fields then go in the query string, whatever the method.
69
- - A response that is not 2xx prints its body on stderr and exits with `1`.
22
+ Before you use a command, run `currents <command> --help` for its options and examples, and do not use an option it does not list. For CI steps run `currents docs ci-setup`, and for the session flow run `currents docs sessions`. If `docs` is an unknown command, update `@currents/cmd`.
70
23
 
71
24
  ## Credentials
72
25
 
73
- Each command takes one kind of key. Both come from the Currents dashboard.
74
-
75
- | Command | Key | Option | Environment variable |
76
- | ---------------------------------------------------- | --------------------------------------------------- | -------------------- | ----------------------------------------- |
77
- | `run upload`, `run cancel`, `cache set`, `cache get` | record key | `--key` | `CURRENTS_RECORD_KEY` |
78
- | `run attach` | record key, or an API key when no record key is set | `--key`, `--api-key` | `CURRENTS_RECORD_KEY`, `CURRENTS_API_KEY` |
79
- | `session start`, `session attach`, `session share` | record key, or an API key when no record key is set | `--key`, `--api-key` | `CURRENTS_RECORD_KEY`, `CURRENTS_API_KEY` |
80
- | `run get`, `api` | API key | `--api-key` | `CURRENTS_API_KEY` |
81
-
82
- Other environment variables the commands read:
83
-
84
- - `CURRENTS_PROJECT_ID`: `run upload`, `run attach`, `run cancel`, `session start`, `run get`
85
- - `CURRENTS_CI_BUILD_ID`: `run upload`, `run attach`, `run cancel`, `run get`. `run get` ignores it when `--branch` or `--tag` is set
86
- - `CURRENTS_RUN_ID`: `run cancel`
87
- - `CURRENTS_MACHINE_ID`: `run upload`, `run attach`
88
- - `CURRENTS_SESSION_ID`: `session attach`, `session share`
89
- - `CURRENTS_REPORT_DIR`: `run upload`
90
- - `CURRENTS_TAG`: `run upload`, comma-separated tags for the run
91
- - `CURRENTS_REMOVE_TITLE_TAGS`, `CURRENTS_DISABLE_TITLE_TAGS`: `run upload`, same as `--remove-title-tags` and `--disable-title-tags`
92
- - `CURRENTS_PREVIOUS_CI_BUILD_ID`: `run upload`, the CI build ID of the earlier attempt of this CI build, sent with the run
93
- - `CURRENTS_OUTPUT`: `run get`, same as `--output`
94
- - `CURRENTS_DEBUG`: all commands, same as `--debug`
95
- - `CURRENTS_API_URL`: the Currents API address for `run upload`, `run cancel` and `cache`. `CURRENTS_REST_API_URL`: the REST API address for `run attach`, `run get`, `session` and `api`. Set them only to reach a server other than Currents, such as a local test server
96
-
97
- An option on the command line wins over its environment variable, and the environment variable wins over the default. For a flag such as `CURRENTS_DEBUG`, `false`, `0`, `no` and `off` turn it off, and any other value turns it on.
98
-
99
- Set keys as environment variables or CI secrets, not as options, so that they stay out of shell history and CI logs. In CI, set `CURRENTS_CI_BUILD_ID` once for the job, so that the reporter, `run attach` and `run cancel` find the same run. `run cancel` does not find the CI build ID by itself: it needs `--ci-build-id` or `--run-id`.
100
-
101
- ## Exit codes
102
-
103
- - `0`: the command finished. It is also `0` when `run cancel` finds no run to cancel, when `cache get --continue` finds no cache, and when `cache set --continue` finds no files to save.
104
- - `1`: anything else. For example a missing option, an option value the command does not take, an API error, or a file that could not be uploaded. `currents` without a command prints the help and exits with `1`.
105
-
106
- Errors go to stderr, prefixed with `ERROR`. Other output goes to stdout, except for `run get` without `--output`, `session start --json` and `api`: they print only the response or JSON on stdout, and everything else on stderr.
107
-
108
- When a command fails:
26
+ - Record key, in `CURRENTS_RECORD_KEY` or `--key`: `run upload`, `run cancel`, `cache`.
27
+ - API key, in `CURRENTS_API_KEY` or `--api-key`: `run get`, `api`.
28
+ - `run attach` and `session` take either key. The record key wins when both are set.
109
29
 
110
- 1. Read the message. For a missing value it names the option and the environment variable to set.
111
- 2. A 401 or 403 from the API usually means the wrong key: a record key where an API key is needed, an API key without write access, or a key of another organization.
112
- 3. Run the command again with `--debug` to see the requests and the resolved configuration. Keys are replaced with `*****` in it.
113
- 4. `run attach` and `session attach` print `Attached <file>` for each file that arrived and `Failed <file>` for each that did not. Attach only the failed files again.
114
- 5. Do not retry a failed command in a loop. Report the error and what you tried.
30
+ Both keys come from the Currents dashboard. Set them as environment variables or CI secrets, not as options.
115
31
 
116
32
  ## Safety
117
33
 
118
- - Never print, echo, log or commit a record key or an API key, and do not put a key in a command you show to the user. Write `<record-key>` or refer to the environment variable.
119
- - `session start` writes `.currents-session/session.json` and a `.gitignore` that keeps the folder out of git. Do not commit the folder and do not delete that `.gitignore`.
120
- - Anyone with a session share link can open what you attach. Attach only test data and files from development accounts.
121
- - `run attach` and `session attach` refuse files named `.env` or `.env.*`. In a folder you pass, they skip hidden files and folders, and links. Do not rename or copy files to get around this.
34
+ - Never print, log or commit a key, and do not put one in a command you show to the user. Write `<record-key>` or name the environment variable.
35
+ - Do not commit `.currents-session/`, which `session start` writes.
36
+ - Anyone with a share link can open what you attach. Attach only test data and files from development accounts.
37
+ - `run attach` and `session attach` refuse `.env` files and skip hidden files. Do not rename or copy files to get around this.
122
38
 
123
- ## References
39
+ ## Exit codes and errors
124
40
 
125
- - [references/ci-setup.md](references/ci-setup.md): GitHub Actions and GitLab CI steps for `run upload`, `run attach`, `run cancel` and rerunning failed tests with `cache`.
126
- - [references/sessions.md](references/sessions.md): the `session start`, `attach`, `share` flow, what to attach and what each command prints.
41
+ - `0` when the command finished, `1` otherwise. Errors go to stderr, prefixed with `ERROR`.
42
+ - A 401 or 403 usually means the wrong key: a record key where an API key is needed, an API key without write access, or a key of another organization.
43
+ - Run the command again with `--debug` to see the requests. Keys are hidden in it.
44
+ - Do not retry a failed command in a loop. Report the error and what you tried.
@@ -1,3 +1,7 @@
1
+ ---
2
+ description: GitHub Actions and GitLab CI steps: upload results, attach files, cancel a run, rerun only the failed Playwright tests
3
+ ---
4
+
1
5
  # CI setup
2
6
 
3
7
  Steps for GitHub Actions and GitLab CI. They assume `@currents/cmd` is in the project's `devDependencies`, so that `npx currents` runs it.
@@ -1,3 +1,7 @@
1
+ ---
2
+ description: Record an agent or browser session as evidence and share it: start, attach, share and what each prints
3
+ ---
4
+
1
5
  # Sessions
2
6
 
3
7
  A session holds the files of an ad-hoc, one-off agent or browser session, such as screenshots, a Playwright MCP trace and logs, and gives a link to share them. Use it as evidence: a bug before and after a fix, or proof that something works.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@currents/cmd",
3
- "version": "2.1.0",
3
+ "version": "2.2.0",
4
4
  "main": "./dist/index.js",
5
5
  "author": {
6
6
  "name": "Currents Software Inc",
@@ -88,6 +88,7 @@
88
88
  },
89
89
  "files": [
90
90
  "dist",
91
+ "docs",
91
92
  "!**/*.map",
92
93
  "!**/*/*.map"
93
94
  ],