@currents/cmd 1.11.0-beta.2 → 2.0.0-beta.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/README.md +45 -11
- package/dist/bin/index.js +58 -89
- package/dist/index.js +8 -9
- package/dist/services/upload/discovery/jest/reporter.js +1 -1
- package/dist/skills/currents-cli/SKILL.md +126 -0
- package/dist/skills/currents-cli/references/ci-setup.md +147 -0
- package/dist/skills/currents-cli/references/sessions.md +74 -0
- package/package.json +10 -5
package/dist/index.js
CHANGED
|
@@ -1,12 +1,11 @@
|
|
|
1
|
-
"use strict";var ir=Object.create;var K=Object.defineProperty;var ar=Object.getOwnPropertyDescriptor;var cr=Object.getOwnPropertyNames;var Er=Object.getPrototypeOf,ur=Object.prototype.hasOwnProperty;var he=(e,t)=>{for(var r in t)K(e,r,{get:t[r],enumerable:!0})},Se=(e,t,r,o)=>{if(t&&typeof t=="object"||typeof t=="function")for(let n of cr(t))!ur.call(e,n)&&n!==r&&K(e,n,{get:()=>t[n],enumerable:!(o=ar(t,n))||o.enumerable});return e};var u=(e,t,r)=>(r=e!=null?ir(Er(e)):{},Se(t||!e||!e.__esModule?K(r,"default",{value:e,enumerable:!0}):r,e)),pr=e=>Se(K({},"__esModule",{value:!0}),e);var No={};he(No,{handleCurrentsReport:()=>nr});module.exports=pr(No);var Ne=require("debug"),mr=u(require("fs-extra")),c=(0,Ne.debug)("currents"),_r=null;function Be(e){_r=e}var j={};he(j,{getNanoid:()=>lr,userFacingNanoid:()=>Ee});var ce=require("nanoid"),Le="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz",lr=(e=16)=>(0,ce.customAlphabet)(Le,e)(),Ee=(0,ce.customAlphabet)(Le,12);var m=require("lodash");var Y=c.extend("ci"),Ir=(e,...t)=>(0,m.chain)(t).compact().join(e).value(),Rr=(e,t)=>(0,m.set)(e,(0,m.camelCase)(t),process.env[t]),f=e=>(0,m.transform)(e,Rr,{}),fr=()=>process.env.TF_BUILD&&process.env.AZURE_HTTP_USER_AGENT,Tr=()=>(0,m.some)(process.env,(e,t)=>/^CODEBUILD_/.test(t)),dr=()=>process.env.bamboo_buildNumber,gr=()=>(0,m.some)(process.env,(e,t)=>/^CONCOURSE_/.test(t)),Cr=()=>process.env.GITLAB_CI||process.env.CI_SERVER_NAME&&/^GitLab/.test(process.env.CI_SERVER_NAME),Ur=()=>!!(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),Or=()=>process.env.JENKINS_URL||process.env.JENKINS_HOME||process.env.JENKINS_VERSION||process.env.HUDSON_URL||process.env.HUDSON_HOME,Dr={appveyor:"APPVEYOR",azure:fr,awsCodeBuild:Tr,bamboo:dr,bitbucket:"BITBUCKET_BUILD_NUMBER",buildkite:"BUILDKITE",circle:"CIRCLECI",concourse:gr,codeFresh:"CF_BUILD_ID",drone:"DRONE",githubActions:"GITHUB_ACTIONS",gitlab:Cr,goCD:"GO_JOB_NAME",jenkins:Or,googleCloud:Ur,semaphore:"SEMAPHORE",teamcity:"TEAMCITY_VERSION",travis:"TRAVIS",netlify:"NETLIFY"};function Ar(){let{env:e}=process;return(0,m.findKey)(Dr,t=>{if((0,m.isString)(t))return e[t];if((0,m.isFunction)(t))return t()})}var Pe=()=>({appveyor:f(["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:f(["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:f(["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:f(["bamboo_buildNumber","bamboo_buildResultsUrl","bamboo_planRepository_repositoryUrl","bamboo_buildKey"]),bitbucket:f(["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:f(["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:f(["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:f(["BUILD_ID","BUILD_NAME","BUILD_JOB_NAME","BUILD_PIPELINE_NAME","BUILD_TEAM_NAME","ATC_EXTERNAL_URL"]),codeFresh:f(["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:f(["DRONE_BUILD_LINK","DRONE_BUILD_NUMBER","DRONE_PULL_REQUEST"]),githubActions:f(["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:f(["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:f(["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:f(["BUILD_ID","PROJECT_ID","REPO_NAME","BRANCH_NAME","TAG_NAME","COMMIT_SHA","SHORT_SHA"]),jenkins:f(["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:f(["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:f(["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:f(["BUILD_ID","CONTEXT","URL","DEPLOY_URL","DEPLOY_PRIME_URL","DEPLOY_ID"])}),hr=()=>{let{env:e}=process;return{appveyor:{sha:e.APPVEYOR_REPO_COMMIT,branch:e.APPVEYOR_PULL_REQUEST_HEAD_REPO_BRANCH||e.APPVEYOR_REPO_BRANCH,message:Ir(`
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
%
|
|
5
|
-
%
|
|
6
|
-
%O`,
|
|
7
|
-
|
|
8
|
-
${(t??[]).map(r=>` - ${r}`).join(`
|
|
1
|
+
"use strict";var Er=Object.create;var j=Object.defineProperty;var mr=Object.getOwnPropertyDescriptor;var lr=Object.getOwnPropertyNames;var fr=Object.getPrototypeOf,dr=Object.prototype.hasOwnProperty;var yt=(t,e)=>{for(var r in e)j(t,r,{get:e[r],enumerable:!0})},Lt=(t,e,r,n)=>{if(e&&typeof e=="object"||typeof e=="function")for(let o of lr(e))!dr.call(t,o)&&o!==r&&j(t,o,{get:()=>e[o],enumerable:!(n=mr(e,o))||n.enumerable});return t};var u=(t,e,r)=>(r=t!=null?Er(fr(t)):{},Lt(e||!t||!t.__esModule?j(r,"default",{value:t,enumerable:!0}):r,t)),gr=t=>Lt(j({},"__esModule",{value:!0}),t);var jn={};yt(jn,{handleCurrentsReport:()=>pr});module.exports=gr(jn);var Bt=require("debug"),Ir=u(require("fs-extra")),a=(0,Bt.debug)("currents"),_r=null;function xt(t){_r=t}var Y={};yt(Y,{getNanoid:()=>Tr,userFacingNanoid:()=>ut});var pt=require("nanoid"),Pt="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz",Tr=(t=16)=>(0,pt.customAlphabet)(Pt,t)(),ut=(0,pt.customAlphabet)(Pt,12);var E=require("lodash");function Mt(t){return t.replace(/^([a-z][a-z0-9+.-]*:\/\/)[^/?#\s]*@/i,"$1")}var $=a.extend("ci"),Rr=(t,e)=>(0,E.set)(t,(0,E.camelCase)(e),process.env[e]),I=t=>(0,E.transform)(t,Rr,{}),Cr=()=>process.env.TF_BUILD&&process.env.AZURE_HTTP_USER_AGENT,Ur=()=>(0,E.some)(process.env,(t,e)=>/^CODEBUILD_/.test(e)),Dr=()=>process.env.bamboo_buildNumber,hr=()=>(0,E.some)(process.env,(t,e)=>/^CONCOURSE_/.test(e)),Ar=()=>process.env.GITLAB_CI||process.env.CI_SERVER_NAME&&/^GitLab/.test(process.env.CI_SERVER_NAME),Or=()=>!!(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),Sr=()=>process.env.JENKINS_URL||process.env.JENKINS_HOME||process.env.JENKINS_VERSION||process.env.HUDSON_URL||process.env.HUDSON_HOME,Nr={appveyor:"APPVEYOR",azure:Cr,awsCodeBuild:Ur,bamboo:Dr,bitbucket:"BITBUCKET_BUILD_NUMBER",buildkite:"BUILDKITE",circle:"CIRCLECI",concourse:hr,codeFresh:"CF_BUILD_ID",drone:"DRONE",githubActions:"GITHUB_ACTIONS",gitlab:Ar,goCD:"GO_JOB_NAME",jenkins:Sr,googleCloud:Or,semaphore:"SEMAPHORE",teamcity:"TEAMCITY_VERSION",travis:"TRAVIS",netlify:"NETLIFY"};function yr(){let{env:t}=process;return(0,E.findKey)(Nr,e=>{if((0,E.isString)(e))return t[e];if((0,E.isFunction)(e))return e()})}var wt=()=>({appveyor:I(["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:I(["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:I(["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:I(["bamboo_buildNumber","bamboo_buildResultsUrl","bamboo_planRepository_repositoryUrl","bamboo_buildKey"]),bitbucket:I(["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:I(["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:I(["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:I(["BUILD_ID","BUILD_NAME","BUILD_JOB_NAME","BUILD_PIPELINE_NAME","BUILD_TEAM_NAME","ATC_EXTERNAL_URL"]),codeFresh:I(["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:I(["DRONE_BUILD_LINK","DRONE_BUILD_NUMBER","DRONE_PULL_REQUEST"]),githubActions:I(["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:I(["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:I(["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:I(["BUILD_ID","PROJECT_ID","REPO_NAME","BRANCH_NAME","TAG_NAME","COMMIT_SHA","SHORT_SHA"]),jenkins:I(["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:I(["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:I(["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:I(["BUILD_ID","CONTEXT","URL","DEPLOY_URL","DEPLOY_PRIME_URL","DEPLOY_ID"])}),Lr=t=>{let e=bt();return e?(0,E.chain)(t()).get(e).value():{}};function Br(){return(0,E.chain)(wt()).omitBy(E.isNull).keys().value()}function xr(t){return t&&Br().includes(t)}function bt(){let t=yr();return $("detected CI provider name: %s",t),t||null}function Pr(){let t=Lr(wt);return(0,E.mapValues)(t,e=>(0,E.isString)(e)?Mt(e):e)}function vt(t){let e=Pr(),r=bt(),n=Mr(t,r);return $("detected CI provider: %s",r),$("detected CI params: %O",e),$("detected CI build ID: %o",n),{params:e,provider:r,ciBuildId:n}}function Mr(t,e){return t?{source:"user",value:t}:xr(e)?{source:"server",value:null}:{source:"random",value:`auto:${ut()}`}}var Ft=require("@currents/commit-info"),Gt=require("lodash");var wr=a.extend("git"),br=async()=>{let t=await(0,Ft.commitInfo)();return wr("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}},Ht=(0,Gt.memoize)(br);var kt=u(require("getos")),Kt=require("lodash"),O=require("os"),jt=require("util"),vr=async()=>{if((0,O.platform)()==="linux")try{let t=await(0,jt.promisify)(kt.default)();return"dist"in t&&"release"in t?[t.dist,t.release].join(" - "):(0,O.release)()}catch{return(0,O.release)()}return(0,O.release)()},Fr=async()=>{let t=await vr();return{osName:(0,O.platform)(),osVersion:t,osCpus:[],osMemory:{free:(0,O.freemem)(),total:(0,O.totalmem)()}}},Yt=(0,Kt.memoize)(Fr);var $t={name:"@currents/cmd",version:"2.0.0-beta.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",rimraf:"^6.0.1",tsup:"^8.3.5",typescript:"^5.9.3",vitest:"^4.1.0"},dependencies:{"@commander-js/extra-typings":"^14.0.0","@currents/commit-info":"2.0.0-beta.0",archiver:"^7.0.1","async-retry":"^1.3.3",axios:"1.18.1","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","jest-cli":"^30.2.0","jest-config":"^30.3.0",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 V=$t.version;var Et=u(require("lodash")),Hr=["apiKey","recordKey","key"];function Vt(t,e){return Et.default.isPlainObject(t)?Et.default.mapValues(t,(r,n)=>e.includes(n)&&r!==void 0?"*****":Vt(r,e)):t}function S(t){return Vt(t,Hr)}var kr=[];function mt(t){kr.push(t)}var T=u(require("chalk")),b=u(require("util"));var Jt=[],Wt=[];var qt=(...t)=>{let e=b.default.format(...t);mt(e),console.log(e)},Kr=(...t)=>{let e=b.default.format(...t);mt(e),console.error(e)},J=qt,f=(...t)=>{let e=b.default.format(...t);return Wt.push(e),a("WARNING: ",e),qt(T.default.bgYellow.black(" WARNING "),e)};var d=(...t)=>{let e=b.default.format(...jr(t));return Jt.push(e),a("ERROR: ",b.default.format(...t)),Kr(T.default.bgRed.white(" ERROR "),e)};var jr=t=>t.map(e=>e instanceof Error?e.message:e),W=(t=2)=>console.log(Array(t).fill("").join(`
|
|
2
|
+
`)),Ao=T.default.cyan,Oo=T.default.blueBright,So=T.default.red,No=T.default.yellow,yo=T.default.green,Lo=T.default.gray,Bo=T.default.white,xo=T.default.black,Po=T.default.magenta,v=T.default.dim,Mo=T.default.bold;var F=u(require("fs-extra")),lt=require("path"),$r=require("uuid");async function M(t){try{return await F.default.readJson(t)}catch(e){throw d("Error while reading JSON file: %s",t,e),d}}async function ft(t,e){try{return await F.default.writeFile(t,e,"utf8"),t}catch(r){throw d(`Error writing file at ${t}:`,r),r}}async function Qt(t){try{return await F.default.ensureDir(t),a("Folder created",t),t}catch(e){throw d(`Failed to create folder at ${t}:`,e),e}}async function Xt(t,e){try{return await F.default.ensureDir((0,lt.dirname)(e)),await F.default.copy(t,e),a("File copied from %s to %s",t,e),e}catch(r){throw d(`Failed to copy file from ${t} to ${e}:`,r),r}}var zt=u(require("crypto"));function Zt(t){return zt.createHash("sha256").update(t).digest("base64").slice(0,8).replace(/\+/g,"-").replace(/\//g,"_").replace(/=+$/,"")}var ar=u(require("axios")),St=u(require("fs-extra")),it=u(require("path")),cr=u(require("semver"));var Ie=u(require("lodash"));var pe=u(require("axios")),ue=u(require("axios-retry")),Rt=u(require("lodash"));var te=()=>process.env.CURRENTS_API_URL??"https://cy.currents.dev",ee=()=>process.env.CURRENTS_REST_API_URL??"https://api.currents.dev",re=()=>3e4;var q=require("axios"),dt=u(require("pretty-ms"));var oe=a.extend("http"),ne=[3*1e3,15*1e3,30*1e3],se=60*1e3;function gt(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=ne[Math.min(t,ne.length)-1],n=gt(e);return n===void 0?r:Math.min(Math.max(n,r),se)},It=t=>(oe("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),Vr=["get","head","options","put","delete"],ie=t=>{if(!(0,q.isAxiosError)(t))return!1;let e=t.response?.status;if(e===429){let r=gt(t);return r===void 0||r<=se}return Vr.includes(t.config?.method?.toLowerCase()??"get")?It(t):e===408||t.code==="ECONNREFUSED"||t.code==="ENOTFOUND"},X=()=>3;function ae(t,e,r){oe("Network request '%s' failed: '%s'. Next attempt is in %s (%d/%d).",`${r.method?.toUpperCase()} ${r.url}`,e.message,(0,dt.default)(Q(t,e)??0),t,X()),f("Network request '%s' failed: '%s'. Next attempt is in %s (%d/%d).",`${r.method?.toUpperCase()} ${r.url}`,e.message,(0,dt.default)(Q(t,e)??0),t,X())}var _t=a.extend("http");var Tt={api:null,restApi:null};function Jr(t){let e=t==="api"?te():ee();_t("client base url: %s",e);let r=pe.default.create({baseURL:e,timeout:re(),transitional:{clarifyTimeoutError:!0}});return r.interceptors.request.use(n=>{let o=n["axios-retry"]?.retryCount??0;n.headers.set({"x-cmd-version":V}),n.headers.get("Content-Type")||n.headers.set("Content-Type","application/json");let s={...Rt.default.pick(n,"method","url","headers"),baseURL:e,data:Buffer.isBuffer(n.data)?"buffer":n.data,params:n.params};return o?_t("network request retry: %o",ce({...s,baseURL:e,isRetry:!0})):_t("network request: %o",ce(s)),n}),(0,ue.default)(r,{retries:X(),retryCondition:t==="restApi"?ie:It,retryDelay:(n,o)=>Q(n,o),shouldResetTimeout:!0,onRetry:ae}),r}function z(t){return Tt[t]===null&&(Tt[t]=Jr(t)),Tt[t]}function ce(t){return{method:t.method,baseURL:t.baseURL,url:t.url,data:t.isRetry?"<retry>":Wr(t.data),params:t.isRetry?"<retry>":t.params,headers:{...t.headers,Authorization:"Bearer ***","x-currents-key":"***"}}}function Wr(t){if(t?.results?.raw)return S({...t,results:{...t.results,raw:"***"}});if(typeof t=="string")try{return S(JSON.parse(t))}catch{return t}return Rt.default.isPlainObject(t)?S(t):t}var le=require("axios"),fe=u(require("lodash")),_=require("ts-pattern");function de(t){(0,_.match)(t).when(le.isAxiosError,qr).otherwise(()=>{f("Unexpected error while sending network request: %s",t)})}function qr(t){return(0,_.match)(t).with({code:"ECONNABORTED"},()=>{f("Network connection aborted")}).with({code:"ECONNREFUSED"},()=>{f("Network connection aborted")}).with({code:"ECONNRESET"},()=>{f("Network connection reset")}).with({code:"ETIMEDOUT"},()=>{f("Network connection timeout")}).with({response:_.P.not(_.P.nullish)},e=>{Qr(e,{status:e.response.status,data:e.response.data})}).otherwise(e=>{f(`[currents] Unexpected network error: %s
|
|
3
|
+
%O`,t.message,{method:t.response?.config.method,url:t.response?.config.url,status:t.response?.status,payload:t.response?.config.data})})}function Qr(t,{status:e,data:r}){(0,_.match)(e).with(401,()=>{f(`[currents] ${t.response?.config.method} ${t.response?.config.url} - 401 Unauthorized Request from cloud service`)}).with(400,()=>{f(`[currents] ${t.response?.config.method} ${t.response?.config.url} - 400 Bad Request from cloud service:
|
|
4
|
+
%o`,r)}).with(404,()=>{f(`[currents] ${t.response?.config.method} ${t.response?.config.url} - 404 Not Found from cloud service`)}).with(429,()=>{f(`[currents] ${t.response?.config.method} ${t.response?.config.url} - 429 Too Many Requests from cloud service`)}).with(422,()=>{Xr(t,r)}).otherwise(()=>{f(`[currents] Unexpected network response: %s
|
|
5
|
+
%O`,t.message,{method:t.response?.config.method,url:t.response?.config.url,status:t.response?.status})})}function Xr(t,e){(0,_.match)(e).with({code:Ee.MISSING_SUITE,message:_.P.string,errors:_.P.array(_.P.string)},async r=>{let{message:n,errors:o}=r;W(1),d(...me(n,o))}).with({code:Ee.RUN_EXPIRED,message:_.P.string},r=>{f(r.message)}).with({message:_.P.string,errors:_.P.array(_.P.string)},r=>{let{message:n,errors:o}=r;W(1),f(...me(n,o)),W(1)}).otherwise(()=>{f(`[currents] Unexpected network response: %s
|
|
6
|
+
%O`,t.message,{method:t.response?.config.method,url:t.response?.config.url,status:t.response?.status})})}var Ee={RUN_CANCELLED:"RUN_CANCELLED",RUN_EXPIRED:"RUN_EXPIRED",MISSING_SUITE:"MISSING_SUITE"};function me(t,e){return fe.default.isString(t)?e?.length===0?[t]:[t,`
|
|
7
|
+
${(e??[]).map(r=>` - ${r}`).join(`
|
|
9
8
|
`)}
|
|
10
|
-
`]:["Unexpected network error"]}var _t=c.extend("http");async function F(e,t,r=at){try{let o=await r(e).request(t);return _t("network response: %o",{...lt.default.omit(o,"request","config"),url:o.config.url,method:o.config.method}),o}catch(o){let n=o;throw _t("network error: %o",{code:n.code,message:n.message,url:n.config?.url,method:n.config?.method,status:n.response?.status,headers:n.response?.headers,data:n.response?.data}),mt(n),n}}var fs=c.extend("api");var Ds=c.extend("api");var Rt=require("util"),ft=require("zlib");var It=c.extend("api"),Jr=(0,Rt.promisify)(ft.gzip);async function Tt(e){try{It("Run params: %o",S(e));let t=await $r(JSON.stringify(e));return F("api",{url:"v1/runs",method:"POST",headers:{"Content-Type":"application/json","Content-Encoding":"gzip"},data:t}).then(r=>r.data)}catch(t){throw It("Failed to create the run:",t),t}}async function $r(e){try{return await Jr(e)}catch(t){throw I("Failed to compress run payload:",t),t}}var vs=c.extend("api");var si=c.extend("config");var Wr=null;function dt(){return Wr}var Ce=u(require("fs-extra")),N=require("path");var gt=u(require("fs-extra")),Ct=require("path"),ge=c.extend("detox"),Qr="detox.json";function Ut(e){return[...e].sort((t,r)=>(t.session??0)-(r.session??0)||t.invocations-r.invocations)}async function Ot(e){let t=(0,Ct.join)(e,Qr);try{let r=await gt.default.readJson(t);if(typeof r?.artifactsRootDir!="string"||!Array.isArray(r?.tests)){ge("Unexpected Detox manifest contents at %s",t);return}return ge("Detox manifest: %o",r),r}catch{ge("No Detox manifest at %s",t);return}}var X=require("path"),qr=c.extend("detox"),Dt=255,Xr=/[/\\?<>:*|"$\u0000-\u001f]/g,At=4;function ht(e){return zr(e)??Zr(e)}function zr({rootDir:e,fullName:t,status:r,invocations:o}){try{let n=require.resolve("detox/src/artifacts/utils/ArtifactPathBuilder",{paths:[process.cwd()]}),s=require(n),i=new s({rootDir:e});return(0,X.dirname)(i.buildPathForTestArtifact("test.mp4",{fullName:t,status:r,invocations:o}))}catch(n){qr("Detox path builder is not available: %o",n);return}}function Zr({rootDir:e,fullName:t,status:r,invocations:o}){let n=to(r),s=o>1?` (${o})`:"",i=t.slice(-Dt+n.length+s.length),E=`${n}${i}${s}`.replace(Xr,"_");return(0,X.join)(e,eo(E,Dt))}function eo(e,t){let r=Buffer.from(e,"utf8");return r.length<=t?e:r.subarray(0,t).toString("utf8").replace(/\uFFFD$/,"")}function to(e){switch(e){case"passed":return"\u2713 ";case"failed":return"\u2717 ";default:return""}}var Nt=u(require("fs-extra")),Bt=require("path"),St=c.extend("detox"),z="detox.trace.json",ro="ws-client-invocation";async function Lt(e){let t=(0,Bt.join)(e,z),r=new Map,o;try{o=await Nt.default.readJson(t)}catch{return St("No Detox trace at %s",t),r}if(!Array.isArray(o))return St("Unexpected Detox trace contents at %s",t),r;let n=oo(o);return so(o).forEach(({pid:i,ts:E,step:p})=>{n.filter(R=>R.pid===i&&E>=R.startTs&&E<=R.endTs).sort((R,g)=>R.startTs-g.startTs).pop()?.steps.push(p)}),n.forEach(({fullName:i,invocations:E,steps:p})=>{let _=r.get(i)??[];_.push({fullName:i,invocations:E,steps:p.sort((R,g)=>+new Date(R.startTime)-+new Date(g.startTime))}),r.set(i,_)}),r}function oo(e){let t=new Map,r=[];e.forEach(n=>{let s=`${n.pid}:${n.tid}`,i=t.get(s)??[];if(t.set(s,i),n.ph==="B"){i.push(no(n));return}if(n.ph==="E"){let E=i.pop();E&&r.push({...E,endTs:Number(n.ts)})}});let o=[...t.values()].flatMap(n=>n.filter(s=>s!==void 0));return[...r,...o]}function no(e){let t=e.args?.fullName;if(!(e.args?.context!=="test"||typeof t!="string"))return{fullName:t,invocations:Number(e.args?.invocations??1),pid:Number(e.pid),startTs:Number(e.ts),endTs:Number.MAX_SAFE_INTEGER,steps:[]}}function so(e){let t=new Map,r=[];return e.forEach(o=>{if(!o.cat?.includes(ro))return;let n=`${o.pid}:${o.tid}`,s=t.get(n)??[];if(o.ph==="B"){s.push({name:o.name??"action",cat:o.cat,ts:Number(o.ts)}),t.set(n,s);return}if(o.ph==="E"){let i=s.pop();if(!i)return;r.push({pid:Number(o.pid),ts:i.ts,step:{title:i.name,category:"detox",startTime:new Date(i.ts/1e3).toISOString(),duration:Math.round((Number(o.ts)-i.ts)/1e3),steps:[]}})}}),r}var H=c.extend("detox"),Pt="artifacts",io={".mp4":{type:"video",contentType:"video/mp4"},".png":{type:"screenshot",contentType:"image/png"},".jpg":{type:"screenshot",contentType:"image/jpeg"},".log":{type:"attachment",contentType:"text/plain"},".txt":{type:"attachment",contentType:"text/plain"},".json":{type:"attachment",contentType:"application/json"},".viewhierarchy":{type:"attachment",contentType:"application/xml"}};async function yt({instances:e,reportDir:t,manifest:r}){let o=co(r),n=await Lt(r.artifactsRootDir),s=await We((0,N.join)(t,Pt)),i={artifacts:0,steps:0};for(let E of e)for(let p of E.results.tests){let _=o.get(p.testId);if(!_){H("No Detox manifest entry for %s",p.testId);continue}await Eo({test:p,manifestTest:_,rootDir:r.artifactsRootDir,artifactsDir:s,traceSlices:n.get(_.fullName)??[],result:i})}return i.artifacts+=await ao({instances:e,rootDir:r.artifactsRootDir,artifactsDir:s}),i}async function ao({instances:e,rootDir:t,artifactsDir:r}){if(!await Ce.default.pathExists((0,N.join)(t,z)))return 0;let[o]=await Mt(t,[z],r),n=e.map(s=>s.results.tests[0]).filter(s=>s!==void 0);return n.forEach(s=>{s.artifacts=[...s.artifacts??[],o]}),n.length}function co(e){let t=new Map;return e.tests.forEach(r=>{t.set(r.fullName,[...t.get(r.fullName)??[],r.testId])}),new Map(e.tests.filter(r=>{let o=t.get(r.fullName)?.length===1;return o||H("Ambiguous Detox test name, skipping: %s",r.fullName),o}).map(r=>[r.testId,r]))}async function Eo({test:e,manifestTest:t,rootDir:r,artifactsDir:o,traceSlices:n,result:s}){let i=[...e.attempts].sort((_,R)=>_.attempt-R.attempt),E=Ut(t.attempts),p=1;for(let[_,R]of E.entries()){let g=i[_];if(!g){H("No reported attempt %d of %s",_,t.fullName);continue}let O=await uo({fullName:t.fullName,status:R.status,rootDir:r,artifactsDir:o,fromInvocation:p});O&&(p=O.invocation+1,g.artifacts=[...g.artifacts??[],...O.artifacts],s.artifacts+=O.artifacts.length);let x=mo(n,_,O?.invocation);x.length&&(g.steps=[...g.steps??[],...x],s.steps+=x.length)}}async function uo({fullName:e,status:t,rootDir:r,artifactsDir:o,fromInvocation:n}){for(let s=n;s<n+At;s++){let i=ht({rootDir:r,fullName:e,status:t,invocations:s}),E=await po(i);if(E)return{invocation:s,artifacts:await Mt(i,E,o)}}H("No Detox artifacts for %s [%s]",e,t)}async function po(e){try{return(await Ce.default.readdir(e)).sort()}catch{return}}async function Mt(e,t,r){let o=[];for(let n of t){let s=io[(0,N.extname)(n)];if(!s){H("Skipping unsupported Detox artifact %s",n);continue}let i=(0,N.join)(e,n),E=`${Xe(i)}${(0,N.extname)(n)}`;await Qe(i,(0,N.join)(r,E)),o.push({...s,path:(0,N.join)(Pt,E),name:n})}return o}function mo(e,t,r){return((r===void 0?void 0:e.find(s=>s.invocations===r))??[...e].sort((s,i)=>s.invocations-i.invocations)[t])?.steps??[]}var L=class{constructor(t){this.config=t}async getFullTestSuite(){return[]}};var Yt=u(require("fs-extra")),Vt=require("jest-cli"),Jt=u(require("tmp"));var Kt=require("lodash");function xt(e){let t=[];for(let[r,o]of Object.entries(e))r==="_"||r==="$0"||r.includes("-")||(typeof o=="boolean"?o&&t.push(`--${r}`):Array.isArray(o)?o.forEach(n=>{t.push(`--${r}=${n}`)}):t.push(`--${r}=${o}`));return t.join(" ")}var bt=require("lodash"),_o=["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","testNamePattern","verbose","waitNextEventLoopTurnForUnhandledRejectionEvents","watch","watchAll","watchPathIgnorePatterns","watchman"];function wt(e){return(0,bt.omit)(e,..._o)}var Ft=u(require("fs")),Ht=require("jest-config"),Ue=require("lodash"),Oe=u(require("path"));function Z(e,t){return(...r)=>new Promise((o,n)=>{let s=0,i=()=>{s++;try{let E=e(...r);o(E)}catch(E){if(s>=t.length)n(E);else{let p=t[s-1];setTimeout(i,p)}}};i()})}var vt=u(require("fs-extra")),lo=u(require("path"));async function ee(e){let t=await vt.default.pathExists(e);if(!t)throw new Error("File does not exist");return t}var Gt=c.extend("jest-discovery");async function kt(e){try{let{config:t,configPath:r}=await(0,Ht.readInitialOptions)(e),o=["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"],n=["collectCoverageFrom","coverageDirectory","coveragePathIgnorePatterns","detectLeaks","detectOpenHandles","errorOnDeprecated","forceCoverageMatch","openHandlesTimeout","runner","watchPathIgnorePatterns"],s=(0,Ue.omit)(t,o);if(s.projects&&(s.projects=s.projects.map(p=>typeof p!="string"?(0,Ue.omit)(p,n):p)),s.rootDir&&Object.keys(s).length===1)return null;let i=Oe.default.resolve(r?Oe.default.dirname(r):process.cwd(),`.jest-scanner-${new Date().getTime()}.config.cjs`),E=`module.exports=${JSON.stringify(s,null,2)}`;return Gt("configFileContent: %O",E),Ft.default.writeFileSync(i,E),await Z(ee,[200,200,200,200,200,1e3])(i),i}catch(t){return I("Failed to recreate the config file"),Gt("error %o",t),null}}async function jt(e){let t="!!##ThisPatternWillNotMatchAnyTestName##!!",r=e.options,o=wt(r),n=xt(o),s=r.config,i=await kt(s);return{cliArgs:[n,"--testNamePattern",t,"--reporters","@currents/cmd/discovery/jest","--shard=1/1",i?`--config=${i}`:"",...e.args].filter(p=>!(0,Kt.isEmpty)(p)),configFilePath:i}}var Io=c.extend("jest-discovery");async function $t(e,t){console.time(w("@currents/jest:fullTestSuite-ready"));let{cliArgs:r,configFilePath:o}=await jt(t);try{let n=Jt.default.fileSync({postfix:".json"});return Io("running scanner: %o",r),process.env.CURRENTS_DISCOVERY_PATH=n.name,await(0,Vt.run)(r.concat(["--openHandlesTimeout=0"])),await Z(ee,Array.from({length:300},()=>100))(n.name),console.timeEnd(w("@currents/jest:fullTestSuite-ready")),await M(n.name)}catch(n){return I("Failed to obtain the jest full test suite:",n),[]}finally{o&&Yt.default.unlinkSync(o)}}var te=class extends L{constructor(t){super(t)}async getFullTestSuite(){return $t(this.config.frameworkConfig,this.config.cliArgs)}};var Qt=u(require("fs-extra"));var Wt=u(require("path"));function re(e){return Wt.default.join(e,"fullTestSuite.json")}var Ro=c.extend("junit-discovery");async function qt(e){console.time(w("@currents/junit:fullTestSuite-ready"));try{Ro("running scanner: %o",e);let t=re(e);process.env.CURRENTS_DISCOVERY_PATH=t;let r=Qt.default.readFileSync(t,"utf-8");return JSON.parse(r)}catch(t){return I("Failed to obtain the junit full test suite:",t),[]}}var oe=class extends L{constructor(t,r){super(t),this.reportDir=r}async getFullTestSuite(){return qt(this.reportDir)}};function Xt(e,t){switch(e.framework){case"jest":return new te(e);case"junit":return new oe(e,t);default:return new L(e)}}var G=u(require("fs-extra")),B=u(require("path"));async function zt(e){let t=await fo(e?.reportDir);if(!t)throw new Error("Failed to find the report dir");return{reportDir:t,configFilePath:e?.configFilePath??B.default.join(t,"config.json")}}async function fo(e){return e?(await ne(e),e):To((0,B.join)(process.cwd(),".currents"))}async function To(e){let t=await G.default.readdir(e),r=null;for(let o of t){let n=B.default.join(e,o),s=await G.default.stat(n);s.isDirectory()&&(!r||s.birthtime>r.birthtime)&&(r={name:o,birthtime:s.birthtime})}return r?(0,B.resolve)(e,r.name):null}async function ne(e){try{return await G.default.pathExists(e)}catch{return I("Error checking if path exists:",I),!1}}async function Zt(e){let t=B.default.join(e,"instances");return go(t)}async function go(e){let t=await G.default.readdir(e),r=[];for(let o of t){let n=B.default.join(e,o);(await G.default.stat(n)).isFile()&&r.push(n)}return r}var Co=e=>Buffer.byteLength(JSON.stringify(e),"utf8"),er=(e,t=1048576)=>{let r=[],o=[],n=0;for(let s of e){let i=Co(s);n+i>t&&(r.push(o),o=[],n=0),o.push(s),n+=i}return o.length>0&&r.push(o),r};var Uo=3e4;async function nr(){let e=dt();if(!e)throw new Error("Currents config is missing!");let t=await zt(e);Be(Do(t.reportDir)),c("Reporter options: %o",t),$("Report directory: %s",t.reportDir);let r=await M(t.configFilePath);c("Report config: %o",r);let o=await Zt(t.reportDir);c("Found %d instance results in the reportDir: %s",o.length,t.reportDir);let n=Oo(t.reportDir),s=await ne(n),i=re(t.reportDir),E=null;if(s){let C=await M(n);l("Marker file detected. The report was already uploaded: %o",{runUrl:C.response.runUrl,isoDate:C.isoDate})}if(await ne(i)&&(E=await M(i),c("Full test suite file detected: %s",i)),E)c("The discovery stage was skipped");else{if(E=await Xt(r,t.reportDir).getFullTestSuite(),Ao(E))throw new Error("Failed to discover the full test suite!");await _e(i,JSON.stringify(E))}let _=E.length===1?E[0].name:null,R={currents:e},g={type:r.framework,version:r.frameworkVersion,clientVersion:J,frameworkConfig:{originFramework:r.frameworkConfig?.originFramework,originFrameworkVersion:r.frameworkConfig?.originFrameworkVersion}},O=j.userFacingNanoid(),x=be(e.ciBuildId),P={};for await(let C of o){let D=await M(C);P[D.groupId]||(P[D.groupId]=[]),P[D.groupId].push(D)}let Ae=await Ot(t.reportDir);if(Ae){let C=await yt({instances:Object.values(P).flat(),reportDir:t.reportDir,manifest:Ae});$("[currents] Attached %d Detox artifacts and %d steps",C.artifacts,C.steps)}let k=new Map;Object.values(P).forEach(C=>{C.forEach(D=>{D.artifacts?.forEach(A=>{A&&k.set(A.path,A.contentType)}),D.results.tests.forEach(A=>{A.artifacts?.forEach(U=>{U&&k.set(U.path,U.contentType)}),A.attempts.forEach(U=>{U.artifacts?.forEach(y=>{y&&k.set(y.path,y.contentType)})})})})});for await(let C of Object.keys(P)){let D=P[C],A=C;_&&(c("Default group found: %s, overwriting the group in the results",_),A=_,D=D.map(U=>({...U,groupId:_})));try{let U=er(D),y=await tr({ci:x,group:A,instances:[],fullTestSuite:E,config:R,machineId:O,framework:g});for(let ie=0;ie<U.length;ie++){let ae=await tr({ci:x,group:A,instances:U[ie],fullTestSuite:[],config:R,machineId:O,framework:g});ae.artifactUploadUrls&&ae.artifactUploadUrls.length>0&&await ho(ae.artifactUploadUrls,t.reportDir,k)}c("Api response: %o",y),$("[%s] Run created: %s",A,y.runUrl);let sr={response:y,isoDate:new Date().toISOString()};await _e(n,JSON.stringify(sr)),c("Marker file %s: %s",s?"overwritten":"created",n)}catch(U){throw c("Failed to upload the results to the dashboard"),U}}}async function tr({ci:e,group:t,instances:r,fullTestSuite:o,config:n,machineId:s,framework:i}){let E=await Fe(),p=await je(),_={browserName:"node",browserVersion:or.default.coerce(process.version)?.version},{currents:R}=n,O={platform:{..._,...p},ci:e,commit:E,group:t,fullTestSuite:o,config:n,projectId:R.projectId,recordKey:R.recordKey,ciBuildId:e.ciBuildId.value??void 0,tags:R.tag??[],machineId:R.machineId??s,framework:i,instances:r,previousCiBuildId:process.env.CURRENTS_PREVIOUS_CI_BUILD_ID};return c("Creating run: %o",S(O)),Tt(O)}function Oo(e){return se.default.join(e,"upload.marker.json")}function Do(e){return se.default.join(e,`.debug-${new Date().toISOString()}.log`)}function Ao(e){return e.length===0||e.some(t=>t.tests.length===0)}async function ho(e,t,r){c("Uploading %d artifacts",e.length),await Promise.all(e.map(o=>{let n=se.default.join(t,o.path),s=r.get(o.path)||"application/octet-stream";return So(n,s,o.uploadUrl)}))}var So=async(e,t,r)=>{try{if(!await De.default.pathExists(e)){l("Artifact file not found: %s",e);return}let o=await De.default.readFile(e);await rr.default.put(r,o,{headers:{"Content-Type":t},timeout:Uo})}catch(o){c("Failed to upload artifact %s: %o",e,o)}};0&&(module.exports={handleCurrentsReport});
|
|
9
|
+
`]:["Unexpected network error"]}var ge=a.extend("http");async function G(t,e,r=z){try{let n=await r(t).request(e);return ge("network response: %o",{...Ie.default.omit(n,"request","config"),url:n.config.url,method:n.config.method}),n}catch(n){let o=n;throw ge("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}),de(o),o}}var Ms=a.extend("api");var ks=a.extend("api");var Te=require("util"),Re=require("zlib");var _e=a.extend("api"),zr=(0,Te.promisify)(Re.gzip);async function Ce(t){try{_e("Run params: %o",S(t));let e=await Zr(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 _e("Failed to create the run:",e),e}}async function Zr(t){try{return await zr(t)}catch(e){throw d("Failed to compress run payload:",e),e}}var ei=a.extend("api");var tn=require("axios");var ui=a.extend("api");var Ct={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:en,ciBuildId:rn,recordKey:nn,projectId:on,machineId:sn}=Ct,an={debug:en,ciBuildId:rn,recordKey:nn,projectId:on,machineId:sn,tag:{...Ct.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 ki=a.extend("config");var cn=null;function De(){return cn}var Dt=u(require("fs-extra")),N=require("path");var pn=u(require("path")),he={".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 Ae=u(require("fs-extra")),Oe=require("path"),Ut=a.extend("detox"),un="detox.json";function Se(t){return[...t].sort((e,r)=>(e.session??0)-(r.session??0)||e.invocations-r.invocations)}async function Ne(t){let e=(0,Oe.join)(t,un);try{let r=await Ae.default.readJson(e);if(typeof r?.artifactsRootDir!="string"||!Array.isArray(r?.tests)){Ut("Unexpected Detox manifest contents at %s",e);return}return Ut("Detox manifest: %o",r),r}catch{Ut("No Detox manifest at %s",e);return}}var Z=require("path"),En=a.extend("detox"),ye=255,mn=/[/\\?<>:*|"$\u0000-\u001f]/g,Le=4;function Be(t){return ln(t)??fn(t)}function ln({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){En("Detox path builder is not available: %o",o);return}}function fn({rootDir:t,fullName:e,status:r,invocations:n}){let o=gn(r),s=n>1?` (${n})`:"",c=e.slice(-ye+o.length+s.length),p=`${o}${c}${s}`.replace(mn,"_");return(0,Z.join)(t,dn(p,ye))}function dn(t,e){let r=Buffer.from(t,"utf8");return r.length<=e?t:r.subarray(0,e).toString("utf8").replace(/\uFFFD$/,"")}function gn(t){switch(t){case"passed":return"\u2713 ";case"failed":return"\u2717 ";default:return""}}var Pe=u(require("fs-extra")),Me=require("path"),xe=a.extend("detox"),tt="detox.trace.json",In="ws-client-invocation";async function we(t){let e=(0,Me.join)(t,tt),r=new Map,n;try{n=await Pe.default.readJson(e)}catch{return xe("No Detox trace at %s",e),r}if(!Array.isArray(n))return xe("Unexpected Detox trace contents at %s",e),r;let o=_n(n);return Rn(n).forEach(({pid:c,ts:p,step:m})=>{o.filter(g=>g.pid===c&&p>=g.startTs&&p<=g.endTs).sort((g,R)=>g.startTs-R.startTs).pop()?.steps.push(m)}),o.forEach(({fullName:c,invocations:p,steps:m})=>{let l=r.get(c)??[];l.push({fullName:c,invocations:p,steps:m.sort((g,R)=>+new Date(g.startTime)-+new Date(R.startTime))}),r.set(c,l)}),r}function _n(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(Tn(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 Tn(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 Rn(t){let e=new Map,r=[];return t.forEach(n=>{if(!n.cat?.includes(In))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 k=a.extend("detox"),be="artifacts",Cn=[".mp4",".png",".jpg",".log",".txt",".json",".viewhierarchy"],Un=t=>{let e=(0,N.extname)(t);return Cn.includes(e)?he[e]:void 0};async function ve({instances:t,reportDir:e,manifest:r}){let n=hn(r),o=await we(r.artifactsRootDir),s=await Qt((0,N.join)(e,be)),c={artifacts:0,steps:0};for(let p of t)for(let m of p.results.tests){let l=n.get(m.testId);if(!l){k("No Detox manifest entry for %s",m.testId);continue}await An({test:m,manifestTest:l,rootDir:r.artifactsRootDir,artifactsDir:s,traceSlices:o.get(l.fullName)??[],result:c})}return c.artifacts+=await Dn({instances:t,rootDir:r.artifactsRootDir,artifactsDir:s}),c}async function Dn({instances:t,rootDir:e,artifactsDir:r}){if(!await Dt.default.pathExists((0,N.join)(e,tt)))return 0;let[n]=await Fe(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 hn(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||k("Ambiguous Detox test name, skipping: %s",r.fullName),n}).map(r=>[r.testId,r]))}async function An({test:t,manifestTest:e,rootDir:r,artifactsDir:n,traceSlices:o,result:s}){let c=[...t.attempts].sort((l,g)=>l.attempt-g.attempt),p=Se(e.attempts),m=1;for(let[l,g]of p.entries()){let R=c[l];if(!R){k("No reported attempt %d of %s",l,e.fullName);continue}let D=await On({fullName:e.fullName,status:g.status,rootDir:r,artifactsDir:n,fromInvocation:m});D&&(m=D.invocation+1,R.artifacts=[...R.artifacts??[],...D.artifacts],s.artifacts+=D.artifacts.length);let w=Nn(o,l,D?.invocation);w.length&&(R.steps=[...R.steps??[],...w],s.steps+=w.length)}}async function On({fullName:t,status:e,rootDir:r,artifactsDir:n,fromInvocation:o}){for(let s=o;s<o+Le;s++){let c=Be({rootDir:r,fullName:t,status:e,invocations:s}),p=await Sn(c);if(p)return{invocation:s,artifacts:await Fe(c,p,n)}}k("No Detox artifacts for %s [%s]",t,e)}async function Sn(t){try{return(await Dt.default.readdir(t)).sort()}catch{return}}async function Fe(t,e,r){let n=[];for(let o of e){let s=Un(o);if(!s){k("Skipping unsupported Detox artifact %s",o);continue}let c=(0,N.join)(t,o),p=`${Zt(c)}${(0,N.extname)(o)}`;await Xt(c,(0,N.join)(r,p)),n.push({...s,path:(0,N.join)(be,p),name:o})}return n}function Nn(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 qe=u(require("fs-extra")),Qe=require("jest-cli"),Xe=u(require("tmp"));var Je=require("lodash");function Ge(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 He=require("lodash"),yn=["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","testNamePattern","verbose","waitNextEventLoopTurnForUnhandledRejectionEvents","watch","watchAll","watchPathIgnorePatterns","watchman"];function ke(t){return(0,He.omit)(t,...yn)}var Ye=u(require("fs")),$e=require("jest-config"),ht=require("lodash"),At=u(require("path"));function et(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 m=e[s-1];setTimeout(c,m)}}};c()})}var Ke=u(require("fs-extra")),Ln=u(require("path"));async function rt(t){let e=await Ke.default.pathExists(t);if(!e)throw new Error("File does not exist");return e}var je=a.extend("jest-discovery");async function Ve(t){try{let{config:e,configPath:r}=await(0,$e.readInitialOptions)(t),n=["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"],o=["collectCoverageFrom","coverageDirectory","coveragePathIgnorePatterns","detectLeaks","detectOpenHandles","errorOnDeprecated","forceCoverageMatch","openHandlesTimeout","runner","watchPathIgnorePatterns"],s=(0,ht.omit)(e,n);if(s.projects&&(s.projects=s.projects.map(m=>typeof m!="string"?(0,ht.omit)(m,o):m)),s.rootDir&&Object.keys(s).length===1)return null;let c=At.default.resolve(r?At.default.dirname(r):process.cwd(),`.jest-scanner-${new Date().getTime()}.config.cjs`),p=`module.exports=${JSON.stringify(s,null,2)}`;return je("configFileContent: %O",p),Ye.default.writeFileSync(c,p),await et(rt,[200,200,200,200,200,1e3])(c),c}catch(e){return d("Failed to recreate the config file"),je("error %o",e),null}}async function We(t){let e="!!##ThisPatternWillNotMatchAnyTestName##!!",r=t.options,n=ke(r),o=Ge(n),s=r.config,c=await Ve(s);return{cliArgs:[o,"--testNamePattern",e,"--reporters","@currents/cmd/discovery/jest","--shard=1/1",c?`--config=${c}`:"",...t.args].filter(m=>!(0,Je.isEmpty)(m)),configFilePath:c}}var Bn=a.extend("jest-discovery");async function ze(t,e){console.time(v("@currents/jest:fullTestSuite-ready"));let{cliArgs:r,configFilePath:n}=await We(e);try{let o=Xe.default.fileSync({postfix:".json"});return Bn("running scanner: %o",r),process.env.CURRENTS_DISCOVERY_PATH=o.name,await(0,Qe.run)(r.concat(["--openHandlesTimeout=0"])),await et(rt,Array.from({length:300},()=>100))(o.name),console.timeEnd(v("@currents/jest:fullTestSuite-ready")),await M(o.name)}catch(o){return d("Failed to obtain the jest full test suite:",o),[]}finally{n&&qe.default.unlinkSync(n)}}var nt=class extends L{constructor(e){super(e)}async getFullTestSuite(){return ze(this.config.frameworkConfig,this.config.cliArgs)}};var tr=u(require("fs-extra"));var Ze=u(require("path"));function ot(t){return Ze.default.join(t,"fullTestSuite.json")}var xn=a.extend("junit-discovery");async function er(t){console.time(v("@currents/junit:fullTestSuite-ready"));try{xn("running scanner: %o",t);let e=ot(t);process.env.CURRENTS_DISCOVERY_PATH=e;let r=tr.default.readFileSync(e,"utf-8");return JSON.parse(r)}catch(e){return d("Failed to obtain the junit full test suite:",e),[]}}var st=class extends L{constructor(e,r){super(e),this.reportDir=r}async getFullTestSuite(){return er(this.reportDir)}};function rr(t,e){switch(t.framework){case"jest":return new nt(t);case"junit":return new st(t,e);default:return new L(t)}}var B=u(require("fs-extra")),y=u(require("path"));async function nr(t){let e=await Pn(t?.reportDir);return{reportDir:e,configFilePath:t?.configFilePath??y.default.join(e,"config.json")}}async function Pn(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,y.join)(process.cwd(),".currents"),r=await B.default.pathExists(e)?await Mn(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 Mn(t){let e=await B.default.readdir(t),r=null;for(let n of e){let o=y.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,y.resolve)(t,r.name):null}async function Ot(t){try{return await B.default.pathExists(t)}catch{return d("Error checking if path exists:",d),!1}}async function or(t){let e=y.default.join(t,"instances");return wn(e)}async function wn(t){let e=await B.default.readdir(t),r=[];for(let n of e){let o=y.default.join(t,n);(await B.default.stat(o)).isFile()&&r.push(o)}return r}var bn=t=>Buffer.byteLength(JSON.stringify(t),"utf8"),sr=(t,e=1048576)=>{let r=[],n=[],o=0;for(let s of t){let c=bn(s);o+c>e&&(r.push(n),n=[],o=0),n.push(s),o+=c}return n.length>0&&r.push(n),r};var vn=3e4;async function pr(){let t=De();if(!t)throw new Error("Currents config is missing!");let e=await nr(t);xt(Gn(e.reportDir)),a("Reporter options: %o",e),J("Report directory: %s",e.reportDir);let r=await M(e.configFilePath);a("Report config: %o",r);let n=await or(e.reportDir);a("Found %d instance results in the reportDir: %s",n.length,e.reportDir);let o=Fn(e.reportDir),s=await Ot(o),c=ot(e.reportDir),p=null;if(s){let C=await M(o);f("Marker file detected. The report was already uploaded: %o",{runUrl:C.response.runUrl,isoDate:C.isoDate})}if(await Ot(c)&&(p=await M(c),a("Full test suite file detected: %s",c)),p)a("The discovery stage was skipped");else{if(p=await rr(r,e.reportDir).getFullTestSuite(),Hn(p))throw new Error("Failed to discover the full test suite!");await ft(c,JSON.stringify(p))}let l=p.length===1?p[0].name:null,g={currents:t},R={type:r.framework,version:r.frameworkVersion,clientVersion:V,frameworkConfig:{originFramework:r.frameworkConfig?.originFramework,originFrameworkVersion:r.frameworkConfig?.originFrameworkVersion}},D=Y.userFacingNanoid(),w=vt(t.ciBuildId),x={};for await(let C of n){let h=await M(C);x[h.groupId]||(x[h.groupId]=[]),x[h.groupId].push(h)}let Nt=await Ne(e.reportDir);if(Nt){let C=await ve({instances:Object.values(x).flat(),reportDir:e.reportDir,manifest:Nt});J("[currents] Attached %d Detox artifacts and %d steps",C.artifacts,C.steps)}let K=new Map;Object.values(x).forEach(C=>{C.forEach(h=>{h.artifacts?.forEach(A=>{A&&K.set(A.path,A.contentType)}),h.results.tests.forEach(A=>{A.artifacts?.forEach(U=>{U&&K.set(U.path,U.contentType)}),A.attempts.forEach(U=>{U.artifacts?.forEach(P=>{P&&K.set(P.path,P.contentType)})})})})});for await(let C of Object.keys(x)){let h=x[C],A=C;l&&(a("Default group found: %s, overwriting the group in the results",l),A=l,h=h.map(U=>({...U,groupId:l})));try{let U=sr(h),P=await ir({ci:w,group:A,instances:[],fullTestSuite:p,config:g,machineId:D,framework:R});for(let at=0;at<U.length;at++){let ct=await ir({ci:w,group:A,instances:U[at],fullTestSuite:[],config:g,machineId:D,framework:R});ct.artifactUploadUrls&&ct.artifactUploadUrls.length>0&&await kn(ct.artifactUploadUrls,e.reportDir,K)}a("Api response: %o",P),J("[%s] Run created: %s",A,P.runUrl);let ur={response:P,isoDate:new Date().toISOString()};await ft(o,JSON.stringify(ur)),a("Marker file %s: %s",s?"overwritten":"created",o)}catch(U){throw a("Failed to upload the results to the dashboard"),U}}}async function ir({ci:t,group:e,instances:r,fullTestSuite:n,config:o,machineId:s,framework:c}){let p=await Ht(),m=await Yt(),l={browserName:"node",browserVersion:cr.default.coerce(process.version)?.version},{currents:g}=o,D={platform:{...l,...m},ci:t,commit:p,group:e,fullTestSuite:n,config:o,projectId:g.projectId,recordKey:g.recordKey,ciBuildId:t.ciBuildId.value??void 0,tags:g.tag??[],machineId:g.machineId??s,framework:c,instances:r,previousCiBuildId:process.env.CURRENTS_PREVIOUS_CI_BUILD_ID};return a("Creating run: %o",S(D)),Ce(D)}function Fn(t){return it.default.join(t,"upload.marker.json")}function Gn(t){return it.default.join(t,`.debug-${new Date().toISOString()}.log`)}function Hn(t){return t.length===0||t.some(e=>e.tests.length===0)}async function kn(t,e,r){a("Uploading %d artifacts",t.length),await Promise.all(t.map(n=>{let o=it.default.join(e,n.path),s=r.get(n.path)||"application/octet-stream";return Kn(o,s,n.uploadUrl)}))}var Kn=async(t,e,r)=>{try{if(!await St.default.pathExists(t)){f("Artifact file not found: %s",t);return}let n=await St.default.readFile(t);await ar.default.put(r,n,{headers:{"Content-Type":e},timeout:vn})}catch(n){a("Failed to upload artifact %s: %o",t,n)}};0&&(module.exports={handleCurrentsReport});
|
|
11
10
|
/*! For license information please see index.js.LEGAL.txt */
|
|
12
11
|
//# sourceMappingURL=index.js.map
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";var
|
|
1
|
+
"use strict";var E=Object.create;var a=Object.defineProperty;var v=Object.getOwnPropertyDescriptor;var P=Object.getOwnPropertyNames;var D=Object.getPrototypeOf,W=Object.prototype.hasOwnProperty;var O=(t,e)=>{for(var o in e)a(t,o,{get:e[o],enumerable:!0})},R=(t,e,o,n)=>{if(e&&typeof e=="object"||typeof e=="function")for(let r of P(e))!W.call(t,r)&&r!==o&&a(t,r,{get:()=>e[r],enumerable:!(n=v(e,r))||n.enumerable});return t};var i=(t,e,o)=>(o=t!=null?E(D(t)):{},R(e||!t||!t.__esModule?a(o,"default",{value:t,enumerable:!0}):o,t)),_=t=>R(a({},"__esModule",{value:!0}),t);var B={};O(B,{default:()=>m});module.exports=_(B);var b=require("debug"),$=i(require("fs-extra")),c=(0,b.debug)("currents");var A=i(require("fs-extra"));var w=i(require("crypto"));var H=i(require("fs-extra")),u=i(require("path"));function S(t,e){return L(u.default.relative(e,t))}function L(t){return t.split(u.default.sep).join(u.default.posix.sep)}function C(){return"root"}function y(t){return t.context.config.displayName?.name??t.context.config.id}function x(t){return[...t.ancestorTitles,t.title]}function T(t){return S(t.path,t.context.config.rootDir)}function I(t,e){let o=x(e),n=T(t),r=o.join(" ")+n;return w.default.createHash("sha256").update(r).digest("hex").substring(0,16)}function j(t){let e=(t.join(" ").match(/@(\S+)/g)??[]).filter(Boolean).map(o=>o);return Array.from(new Set([...e].map(o=>o.trim()).map(o=>o.replace("@",""))))}var M=[];function k(t){M.push(t)}var s=i(require("chalk")),p=i(require("util"));var F=[];var G=(...t)=>{let e=p.default.format(...t);k(e),console.error(e)};var N=(...t)=>{let e=p.default.format(...Y(t));return F.push(e),c("ERROR: ",p.default.format(...t)),G(s.default.bgRed.white(" ERROR "),e)};var Y=t=>t.map(e=>e instanceof Error?e.message:e);var at=s.default.cyan,ct=s.default.blueBright,ut=s.default.red,pt=s.default.yellow,gt=s.default.green,mt=s.default.gray,ft=s.default.white,dt=s.default.black,xt=s.default.magenta,h=s.default.dim,Tt=s.default.bold;var g=c.extend("jest-discovery"),m=class{constructor(){this.specsWithoutResultsCount=0;this.fullTestSuite={}}onRunStart(e){g("onRunStart, results: %O",e),console.time(h("@currents/jest-discovery"))}onTestFileResult(e,o){let n=y(e);this.fullTestSuite[n]||(this.fullTestSuite[n]={name:n,tags:[],tests:[]});let r=T(e);g("onTestFileResult [%s][%s]",n,r),o.testResults.length===0?(g("Failed to obtain spec results, error:",r,o.failureMessage),this.specsWithoutResultsCount+=1):this.fullTestSuite[n].tests.push(...o.testResults.map(f=>{let d=x(f);return{spec:r,tags:j(d),testId:I(e,f),title:d}}))}async onRunComplete(e,o){let n=process.env.CURRENTS_DISCOVERY_PATH;if(!n)throw new Error("CURRENTS_DISCOVERY_PATH is not set");let r=[];this.specsWithoutResultsCount>0?N("Incomplete full test suite! Run the command with --debug flag."):(r=this.getFullTestSuite(e),g("onRunComplete %s, %o",n,r)),await A.default.writeFile(n,JSON.stringify(r),"utf8"),console.timeEnd(h("@currents/jest-discovery"))}getFullTestSuite(e){let o=Object.values(this.fullTestSuite),n=o.length===1,r=o.length>0&&e.size>0&&[...e][0].config.id===o[0].name;return n&&r&&(o[0].name=C()),o}};
|
|
2
2
|
//# sourceMappingURL=reporter.js.map
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: currents-cli
|
|
3
|
+
description: Run the Currents CLI (the `currents` command of the npm package @currents/cmd). Use when asked to upload test results to Currents, convert JUnit or other test reports to the Currents format, attach files or logs to a CI run, cancel a Currents run when CI is cancelled, record a browser session and share it as evidence, cache the last run so a CI rerun runs only the failed tests, or call a Currents REST API route from the command line. Also use when adding these steps to GitHub Actions or GitLab CI.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Currents CLI
|
|
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`.
|
|
17
|
+
|
|
18
|
+
## Pick the command
|
|
19
|
+
|
|
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>` |
|
|
31
|
+
|
|
32
|
+
`@currents/playwright` and the Cypress integration send results themselves. Do not add `currents run upload` after them.
|
|
33
|
+
|
|
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`.
|
|
70
|
+
|
|
71
|
+
## Credentials
|
|
72
|
+
|
|
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` | API key with write access | `--api-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:
|
|
109
|
+
|
|
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.
|
|
115
|
+
|
|
116
|
+
## Safety
|
|
117
|
+
|
|
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, links and subfolders. Do not rename or copy files to get around this.
|
|
122
|
+
|
|
123
|
+
## References
|
|
124
|
+
|
|
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.
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
# CI setup
|
|
2
|
+
|
|
3
|
+
Steps for GitHub Actions and GitLab CI. They assume `@currents/cmd` is in the project's `devDependencies`, so that `npx currents` runs it.
|
|
4
|
+
|
|
5
|
+
In every example:
|
|
6
|
+
|
|
7
|
+
- the record key is a CI secret, passed as `CURRENTS_RECORD_KEY`;
|
|
8
|
+
- `CURRENTS_PROJECT_ID` holds the project ID;
|
|
9
|
+
- `CURRENTS_CI_BUILD_ID` is set once for the job, so that the reporter, `run attach` and `run cancel` find the same run. It includes the attempt number, so a rerun of the workflow records a new run.
|
|
10
|
+
|
|
11
|
+
## GitHub Actions
|
|
12
|
+
|
|
13
|
+
```yaml
|
|
14
|
+
env:
|
|
15
|
+
CURRENTS_PROJECT_ID: <project-id>
|
|
16
|
+
CURRENTS_RECORD_KEY: ${{ secrets.CURRENTS_RECORD_KEY }}
|
|
17
|
+
CURRENTS_CI_BUILD_ID: ${{ github.repository }}-${{ github.run_id }}-${{ github.run_attempt }}
|
|
18
|
+
|
|
19
|
+
jobs:
|
|
20
|
+
test:
|
|
21
|
+
runs-on: ubuntu-latest
|
|
22
|
+
strategy:
|
|
23
|
+
fail-fast: false
|
|
24
|
+
matrix:
|
|
25
|
+
shard: [1, 2]
|
|
26
|
+
steps:
|
|
27
|
+
- uses: actions/checkout@v4
|
|
28
|
+
- uses: actions/setup-node@v4
|
|
29
|
+
with:
|
|
30
|
+
node-version: 22 # the CLI needs Node 20 or later
|
|
31
|
+
- run: npm ci
|
|
32
|
+
# Steps from the sections below go here.
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
### Upload after a reporter
|
|
36
|
+
|
|
37
|
+
`@currents/jest` (also used for Detox) and `@currents/node-test-reporter` write results to `.currents/`. Upload them in a step that runs when the tests fail too:
|
|
38
|
+
|
|
39
|
+
```yaml
|
|
40
|
+
- run: npx jest --shard=${{ matrix.shard }}/${{ strategy.job-total }}
|
|
41
|
+
- if: ${{ !cancelled() }}
|
|
42
|
+
run: npx currents run upload
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
For JUnit XML, `run upload` converts the reports first:
|
|
46
|
+
|
|
47
|
+
```yaml
|
|
48
|
+
- if: ${{ !cancelled() }}
|
|
49
|
+
run: npx currents run upload --input-format junit --input-file "reports/*.xml" --framework postman
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
`--framework` takes `postman`, `node`, `vitest` or `wdio`. See `currents run upload --help`.
|
|
53
|
+
|
|
54
|
+
### Attach files to the run
|
|
55
|
+
|
|
56
|
+
After the tests, attach logs to the run. `--machine-id` names the CI machine the files come from; run-level files are listed by machine when it is set:
|
|
57
|
+
|
|
58
|
+
```yaml
|
|
59
|
+
- if: ${{ !cancelled() }}
|
|
60
|
+
run: |
|
|
61
|
+
docker compose logs > docker-logs.txt
|
|
62
|
+
npx currents run attach --machine-id shard-${{ matrix.shard }} docker-logs.txt
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
To attach a file to a test, pass `--spec` and `--test-title`. See `currents run attach --help`.
|
|
66
|
+
|
|
67
|
+
### Cancel the run when the workflow is cancelled
|
|
68
|
+
|
|
69
|
+
```yaml
|
|
70
|
+
- if: ${{ cancelled() }}
|
|
71
|
+
run: npx currents run cancel
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
It cancels the run with `CURRENTS_CI_BUILD_ID` in the project. If the job was cancelled before the run was created, it prints `No run to cancel` and exits with `0`.
|
|
75
|
+
|
|
76
|
+
### Rerun only the failed Playwright tests
|
|
77
|
+
|
|
78
|
+
Restore the last run before the tests and save it after them:
|
|
79
|
+
|
|
80
|
+
```yaml
|
|
81
|
+
- run: npx currents cache get --preset last-run --matrix-index ${{ matrix.shard }} --matrix-total ${{ strategy.job-total }} --continue
|
|
82
|
+
- run: npx playwright test $(cat .currents_env)
|
|
83
|
+
- if: ${{ !cancelled() }}
|
|
84
|
+
run: npx currents cache set --preset last-run --matrix-index ${{ matrix.shard }} --matrix-total ${{ strategy.job-total }}
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
- `cache get` writes the Playwright options to `.currents_env` (change the path with `--preset-output`). On the first attempt they are `--shard=<index>/<total>`. When the workflow is rerun and the last run was saved, they are `--last-failed --shard=1/1`.
|
|
88
|
+
- `--continue` lets the first attempt go on when there is no saved run yet.
|
|
89
|
+
- `cache set` saves Playwright's `.last-run.json` from `test-results` (change it with `--pw-output-dir`).
|
|
90
|
+
- `--matrix-index` starts at 1.
|
|
91
|
+
|
|
92
|
+
## GitLab CI
|
|
93
|
+
|
|
94
|
+
Set `CURRENTS_RECORD_KEY` as a masked CI/CD variable in the project settings.
|
|
95
|
+
|
|
96
|
+
### Upload after a reporter
|
|
97
|
+
|
|
98
|
+
```yaml
|
|
99
|
+
test:
|
|
100
|
+
image: node:22 # the CLI needs Node 20 or later
|
|
101
|
+
variables:
|
|
102
|
+
CURRENTS_PROJECT_ID: <project-id>
|
|
103
|
+
CURRENTS_CI_BUILD_ID: $CI_PIPELINE_ID
|
|
104
|
+
script:
|
|
105
|
+
- npm ci
|
|
106
|
+
- npx jest
|
|
107
|
+
after_script:
|
|
108
|
+
- npx currents run upload
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
`after_script` runs when the tests fail too. For JUnit XML, add the `--input-format` options to `run upload`, as in the GitHub Actions example.
|
|
112
|
+
|
|
113
|
+
### Attach files and cancel the run
|
|
114
|
+
|
|
115
|
+
`after_script` also runs when the job is cancelled, and `CI_JOB_STATUS` says how the job ended:
|
|
116
|
+
|
|
117
|
+
```yaml
|
|
118
|
+
after_script:
|
|
119
|
+
- npx currents run attach --machine-id $CI_JOB_ID docker-logs.txt
|
|
120
|
+
- if [ "$CI_JOB_STATUS" = "canceled" ]; then npx currents run cancel; fi
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
### Rerun only the failed Playwright tests
|
|
124
|
+
|
|
125
|
+
```yaml
|
|
126
|
+
test:
|
|
127
|
+
image: node:22
|
|
128
|
+
parallel: 2
|
|
129
|
+
variables:
|
|
130
|
+
CURRENTS_PROJECT_ID: <project-id>
|
|
131
|
+
script:
|
|
132
|
+
- npm ci
|
|
133
|
+
- npx currents cache get --preset last-run --continue
|
|
134
|
+
- . ./.currents_env
|
|
135
|
+
- export CURRENTS_CI_BUILD_ID="$CI_PIPELINE_ID-$RUN_ATTEMPT"
|
|
136
|
+
- npx playwright test $EXTRA_PW_FLAGS
|
|
137
|
+
after_script:
|
|
138
|
+
- . ./.currents_env && export RUN_ATTEMPT && npx currents cache set --preset last-run
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
`after_script` runs in a new shell, so it sources `.currents_env` again. `cache set` saves `RUN_ATTEMPT` with the cache, and the next retry counts on from it.
|
|
142
|
+
|
|
143
|
+
On GitLab, `.currents_env` sets three variables:
|
|
144
|
+
|
|
145
|
+
- `EXTRA_PW_FLAGS`: options for `playwright test`, `--shard=<index>/<total>` from `CI_NODE_INDEX` and `CI_NODE_TOTAL`, or `--last-failed --shard=1/1` on a retried job whose last run was saved;
|
|
146
|
+
- `EXTRA_PWCP_FLAGS`: `--last-failed` or nothing, for `pwc`;
|
|
147
|
+
- `RUN_ATTEMPT`: 1 on the first attempt, one more on each retry. Use it in `CURRENTS_CI_BUILD_ID` so that a retry records a new run.
|