@currents/cmd 2.0.0-beta.0 → 2.0.1

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 CHANGED
@@ -36,6 +36,8 @@ Obtain `--project-id` and [--key](https://docs.currents.dev/guides/record-key) f
36
36
  - use `process.env.CURRENTS_REPORT_DIR` or `--report-dir` to read the results previously generated by one of supported reporters, otherwise
37
37
  - use the most recently created folder named as `.currents/[timestamp]-[uuidv4()]` in the current working directory
38
38
 
39
+ To upload `@currents/jest` results, `currents run upload` runs the Jest installed in the current folder to list every test of the suite. Run it from the project folder, with Jest 29.5 or later installed. `@currents/cmd` does not install Jest. A Detox run that is not sharded or filtered writes the list of tests itself, and its upload does not run Jest.
40
+
39
41
  For [Detox](https://wix.github.io/Detox/) runs reported by `@currents/jest`, `currents run upload` also attaches the videos, screenshots and logs that Detox recorded to the matching test attempt, adds the element actions of `detox.trace.json` as steps, and uploads `detox.trace.json`. Run it after `detox test` exits: Detox finishes writing the files only then.
40
42
 
41
43
  ### Configuration
package/dist/bin/index.js CHANGED
@@ -1,63 +1,63 @@
1
1
  #! /usr/bin/env node
2
- "use strict";var vc=Object.create;var lr=Object.defineProperty;var Mc=Object.getOwnPropertyDescriptor;var Fc=Object.getOwnPropertyNames;var kc=Object.getPrototypeOf,Gc=Object.prototype.hasOwnProperty;var $c=(t,e)=>{for(var r in e)lr(t,r,{get:e[r],enumerable:!0})},Kc=(t,e,r,o)=>{if(e&&typeof e=="object"||typeof e=="function")for(let n of Fc(e))!Gc.call(t,n)&&n!==r&&lr(t,n,{get:()=>e[n],enumerable:!(o=Mc(e,n))||o.enumerable});return t};var l=(t,e,r)=>(r=t!=null?vc(kc(t)):{},Kc(e||!t||!t.__esModule?lr(r,"default",{value:t,enumerable:!0}):r,t));var UO=require("source-map-support/register");var Nc=require("@commander-js/extra-typings");var bo={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 xt=bo.version;var no=require("@commander-js/extra-typings");var jc=[];function fr(t){jc.push(t)}var b=l(require("chalk")),Y=l(require("util"));var gr=require("debug"),Vc=l(require("fs-extra")),p=(0,gr.debug)("currents"),Jc=null;function No(){gr.debug.enable("currents,currents:*")}function Lo(t){Jc=t}var Bo=[],vo=[];var ne=(...t)=>{let e=Y.default.format(...t);fr(e),console.log(e)},Mo=(...t)=>{let e=Y.default.format(...t);fr(e),console.error(e)},T=ne,E=(...t)=>{let e=Y.default.format(...t);return vo.push(e),p("WARNING: ",e),ne(b.default.bgYellow.black(" WARNING "),e)},gt=(...t)=>{let e=Y.default.format(...Fo(t));return p("WARNING: ",Y.default.format(...t)),ne(b.default.bgYellow.black(" WARNING "),e)},se=(...t)=>Mo(b.default.bgYellow.black(" WARNING "),Y.default.format(...t)),ie=(...t)=>ne(b.default.green.bold(Y.default.format(...t))),C=(...t)=>{let e=Y.default.format(...Fo(t));return Bo.push(e),p("ERROR: ",Y.default.format(...t)),Mo(b.default.bgRed.white(" ERROR "),e)};var Fo=t=>t.map(e=>e instanceof Error?e.message:e),ae=(t=2)=>console.log(Array(t).fill("").join(`
3
- `)),Mu=b.default.cyan,Fu=b.default.blueBright,ku=b.default.red,Gu=b.default.yellow,$u=b.default.green,Ku=b.default.gray,Hu=b.default.white,ju=b.default.black,Vu=b.default.magenta,x=b.default.dim,Ju=b.default.bold;var ko=80,hr=" ",Wc=" ";function qc(t){let e=t.match(/"[^"]*"|'[^']*'|\S+/g)??[],r=[];for(let o of e){let n=r[r.length-1];n?.startsWith("-")&&!n.includes(" ")&&!o.startsWith("-")?r[r.length-1]=`${n} ${o}`:r.push(o)}return r}function zc(t){if(t.includes(`
2
+ "use strict";var jc=Object.create;var gr=Object.defineProperty;var $c=Object.getOwnPropertyDescriptor;var Kc=Object.getOwnPropertyNames;var Hc=Object.getPrototypeOf,Jc=Object.prototype.hasOwnProperty;var Vc=(t,e)=>{for(var r in e)gr(t,r,{get:e[r],enumerable:!0})},Yc=(t,e,r,o)=>{if(e&&typeof e=="object"||typeof e=="function")for(let n of Kc(e))!Jc.call(t,n)&&n!==r&&gr(t,n,{get:()=>e[n],enumerable:!(o=$c(e,n))||o.enumerable});return t};var l=(t,e,r)=>(r=t!=null?jc(Hc(t)):{},Yc(e||!t||!t.__esModule?gr(r,"default",{value:t,enumerable:!0}):r,t));var jO=require("source-map-support/register");var Fc=require("@commander-js/extra-typings");var vo={name:"@currents/cmd",version:"2.0.1",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 xt=vo.version;var ao=require("@commander-js/extra-typings");var qc=[];function hr(t){qc.push(t)}var b=l(require("chalk")),Y=l(require("util"));var Er=require("debug"),zc=l(require("fs-extra")),p=(0,Er.debug)("currents"),Qc=null;function Bo(){Er.debug.enable("currents,currents:*")}function Mo(t){Qc=t}var Fo=[],ko=[];var ne=(...t)=>{let e=Y.default.format(...t);hr(e),console.log(e)},Go=(...t)=>{let e=Y.default.format(...t);hr(e),console.error(e)},T=ne,E=(...t)=>{let e=Y.default.format(...t);return ko.push(e),p("WARNING: ",e),ne(b.default.bgYellow.black(" WARNING "),e)},gt=(...t)=>{let e=Y.default.format(...jo(t));return p("WARNING: ",Y.default.format(...t)),ne(b.default.bgYellow.black(" WARNING "),e)},se=(...t)=>Go(b.default.bgYellow.black(" WARNING "),Y.default.format(...t)),ie=(...t)=>ne(b.default.green.bold(Y.default.format(...t))),C=(...t)=>{let e=Y.default.format(...jo(t));return Fo.push(e),p("ERROR: ",Y.default.format(...t)),Go(b.default.bgRed.white(" ERROR "),e)};var jo=t=>t.map(e=>e instanceof Error?e.message:e),ae=(t=2)=>console.log(Array(t).fill("").join(`
3
+ `)),Ju=b.default.cyan,Vu=b.default.blueBright,Yu=b.default.red,Wu=b.default.yellow,qu=b.default.green,zu=b.default.gray,Qu=b.default.white,Xu=b.default.black,Zu=b.default.magenta,x=b.default.dim,tl=b.default.bold;var $o=80,Ir=" ",Zc=" ";function tp(t){let e=t.match(/"[^"]*"|'[^']*'|\S+/g)??[],r=[];for(let o of e){let n=r[r.length-1];n?.startsWith("-")&&!n.includes(" ")&&!o.startsWith("-")?r[r.length-1]=`${n} ${o}`:r.push(o)}return r}function ep(t){if(t.includes(`
4
4
  `))return t.split(`
5
- `).map(o=>hr+o);let e=[],r=hr;for(let o of qc(t)){let n=r.trim()==="";!n&&r.length+1+o.length+2>ko?(e.push(`${r} \\`),r=Wc+o):r=n?r+o:`${r} ${o}`}return[...e,r]}function Qc(t){let e=`${hr}# `,r=[],o=e;for(let n of t.split(" "))o!==e&&o.length+1+n.length>ko?(r.push(o),o=e+n):o=o===e?o+n:`${o} ${n}`;return[...r,o].map(n=>x(n))}function y(t){return`
5
+ `).map(o=>Ir+o);let e=[],r=Ir;for(let o of tp(t)){let n=r.trim()==="";!n&&r.length+1+o.length+2>$o?(e.push(`${r} \\`),r=Zc+o):r=n?r+o:`${r} ${o}`}return[...e,r]}function rp(t){let e=`${Ir}# `,r=[],o=e;for(let n of t.split(" "))o!==e&&o.length+1+n.length>$o?(r.push(o),o=e+n):o=o===e?o+n:`${o} ${n}`;return[...r,o].map(n=>x(n))}function y(t){return`
6
6
  Examples:
7
- ${t.map(r=>[...Qc(r.comment),...r.commands.flatMap(zc)].join(`
7
+ ${t.map(r=>[...rp(r.comment),...r.commands.flatMap(ep)].join(`
8
8
  `)).join(`
9
9
 
10
10
  `)}
11
- `}var Er=l(require("lodash")),Xc=["apiKey","recordKey","key"];function Go(t,e){return Er.default.isPlainObject(t)?Er.default.mapValues(t,(r,o)=>e.includes(o)&&r!==void 0?"*****":Go(r,e)):t}function h(t){return Go(t,Xc)}var W=class extends Error{};var q=l(require("fs-extra")),jt=require("path"),$o=require("uuid");async function ht(t){try{return await q.default.readJson(t)}catch(e){throw C("Error while reading JSON file: %s",t,e),C}}async function Et(t,e){try{return await q.default.writeFile(t,e,"utf8"),t}catch(r){throw C(`Error writing file at ${t}:`,r),r}}async function Vt(t,e){try{try{return await q.default.access(t),t}catch{return await q.default.writeFile(t,e,"utf8"),t}}catch(r){throw C(`Error writing file at ${t}:`,r),r}}async function Ko(t,e){if(e){await q.default.ensureDir(t);return}let r=(0,jt.dirname)(t);await q.default.ensureDir(r)}function Zc(){let t=new Date().toISOString().replace(/[:.]/g,"-"),e=(0,$o.v4)();return`${t}-${e}`}async function Ho(t,e){let r=Zc(),o=(0,jt.join)(t,e,r);return It(o)}async function It(t){try{return await q.default.ensureDir(t),p("Folder created",t),t}catch(e){throw C(`Failed to create folder at ${t}:`,e),e}}async function ce(t,e){try{return await q.default.ensureDir((0,jt.dirname)(e)),await q.default.copy(t,e),p("File copied from %s to %s",t,e),e}catch(r){throw C(`Failed to copy file from ${t} to ${e}:`,r),r}}var jo=l(require("crypto"));function et(t){return jo.createHash("sha256").update(t).digest("base64").slice(0,8).replace(/\+/g,"-").replace(/\//g,"_").replace(/=+$/,"")}var pe={};$c(pe,{getNanoid:()=>Cr,userFacingNanoid:()=>Tr});var Ir=require("nanoid"),Vo="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz",Cr=(t=16)=>(0,Ir.customAlphabet)(Vo,t)(),Tr=(0,Ir.customAlphabet)(Vo,12);function yr(t){return t.replace(/^([a-z][a-z0-9+.-]*:\/\/)[^/?#\s]*@/i,"$1")}function At(t){return yr(t).replace(/[?#].*$/,"")}function tp(t){return Object.entries(t??{}).reduce((e,[r,o])=>o===void 0?e:{...e,[r]:o},{})}function Jo(t){if(!(t===void 0||t.trim()===""))return!["false","0","no","off"].includes(t.trim().toLowerCase())}function N(t,e){return"env"in t[e]&&t[e].env?t[e].env:""}function de(t,e){return t[e].cli}function me(t,e){return t[e].name}function U(t,e,r,o){let n=tp(r);return e.forEach(s=>{if(!n[s]){let i=s,c=N(t,i);throw C(`${me(t,i)} is required: pass ${x(de(t,i))}${c?` or set ${x(c)}`:""}`),new W("Missing required config variable")}}),typeof o=="function"&&o(n),n}var _={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{apiKey:ep,debug:rp,ciBuildId:op,projectId:np,tag:sp}=_,ue={apiKey:ep,debug:rp,ciBuildId:op,projectId:np,tag:sp,branch:{name:"Branch",cli:"--branch"},output:{name:"Output file",env:"CURRENTS_OUTPUT",cli:"--output"}};var ip=p.extend("config"),ap=["apiKey","projectId"],cp=t=>{let{ciBuildId:e,tag:r,branch:o}=t;if(!([e,r,o].filter(Boolean).length===1||r&&o&&!e))throw C("Pass --ci-build-id, or --branch, --tag or both"),new W("Missing or invalid parameters")},Rr=null;function Yo(t){Rr=U(ue,ap,t,cp),ip("Resolved config: %o",h(Rr))}function le(){return Rr}var Sn=require("fs/promises");function St({apiKey:t,recordKey:e}){return e?{"x-currents-key":e}:t?{Authorization:`Bearer ${t}`}:{}}var mn=l(require("lodash"));var rn=l(require("axios")),on=l(require("axios-retry")),Ar=l(require("lodash"));var Wo=()=>process.env.CURRENTS_API_URL??"https://cy.currents.dev",Jt=()=>process.env.CURRENTS_REST_API_URL??"https://api.currents.dev",qo=()=>3e4;var fe=require("axios"),_r=l(require("pretty-ms"));var Qo=p.extend("http"),zo=[3*1e3,15*1e3,30*1e3],Xo=60*1e3;function Ee(t,e=Date.now()){let r=t?.response?.headers?.["retry-after"];if(r==null||r==="")return;let o=Number(r);if(Number.isFinite(o))return Math.max(0,o*1e3);let n=Date.parse(String(r));return Number.isNaN(n)?void 0:Math.max(0,n-e)}var ge=(t,e)=>{let r=zo[Math.min(t,zo.length)-1],o=Ee(e);return o===void 0?r:Math.min(Math.max(o,r),Xo)},wr=t=>(Qo("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,fe.isAxiosError)(t)}),"code"in t&&t.code&&["ECONNABORTED","ECONNREFUSED","ECONNRESET","ETIMEDOUT","ENETRESET"].includes(t.code)?!0:(0,fe.isAxiosError)(t)?[408,429,502,503,504].includes(t.response?.status??0):!1),pp=["get","head","options","put","delete"],Zo=t=>{if(!(0,fe.isAxiosError)(t))return!1;let e=t.response?.status;if(e===429){let r=Ee(t);return r===void 0||r<=Xo}return pp.includes(t.config?.method?.toLowerCase()??"get")?wr(t):e===408||t.code==="ECONNREFUSED"||t.code==="ENOTFOUND"},he=()=>3;function tn(t,e,r){Qo("Network request '%s' failed: '%s'. Next attempt is in %s (%d/%d).",`${r.method?.toUpperCase()} ${r.url}`,e.message,(0,_r.default)(ge(t,e)??0),t,he()),E("Network request '%s' failed: '%s'. Next attempt is in %s (%d/%d).",`${r.method?.toUpperCase()} ${r.url}`,e.message,(0,_r.default)(ge(t,e)??0),t,he())}var Or=p.extend("http");var xr={api:null,restApi:null};function dp(t){let e=t==="api"?Wo():Jt();Or("client base url: %s",e);let r=rn.default.create({baseURL:e,timeout:qo(),transitional:{clarifyTimeoutError:!0}});return r.interceptors.request.use(o=>{let n=o["axios-retry"]?.retryCount??0;o.headers.set({"x-cmd-version":xt}),o.headers.get("Content-Type")||o.headers.set("Content-Type","application/json");let s={...Ar.default.pick(o,"method","url","headers"),baseURL:e,data:Buffer.isBuffer(o.data)?"buffer":o.data,params:o.params};return n?Or("network request retry: %o",en({...s,baseURL:e,isRetry:!0})):Or("network request: %o",en(s)),o}),(0,on.default)(r,{retries:he(),retryCondition:t==="restApi"?Zo:wr,retryDelay:(o,n)=>ge(o,n),shouldResetTimeout:!0,onRetry:tn}),r}function Ut(t){return xr[t]===null&&(xr[t]=dp(t)),xr[t]}function en(t){return{method:t.method,baseURL:t.baseURL,url:t.url,data:t.isRetry?"<retry>":mp(t.data),params:t.isRetry?"<retry>":t.params,headers:{...t.headers,Authorization:"Bearer ***","x-currents-key":"***"}}}function mp(t){if(t?.results?.raw)return h({...t,results:{...t.results,raw:"***"}});if(typeof t=="string")try{return h(JSON.parse(t))}catch{return t}return Ar.default.isPlainObject(t)?h(t):t}var an=require("axios"),cn=l(require("lodash")),B=require("ts-pattern");function pn(t){(0,B.match)(t).when(an.isAxiosError,up).otherwise(()=>{E("Unexpected error while sending network request: %s",t)})}function up(t){return(0,B.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:B.P.not(B.P.nullish)},e=>{lp(e,{status:e.response.status,data:e.response.data})}).otherwise(e=>{E(`[currents] Unexpected network error: %s
12
- %O`,t.message,{method:t.response?.config.method,url:t.response?.config.url,status:t.response?.status,payload:t.response?.config.data})})}function lp(t,{status:e,data:r}){(0,B.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:
13
- %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,()=>{fp(t,r)}).otherwise(()=>{E(`[currents] Unexpected network response: %s
14
- %O`,t.message,{method:t.response?.config.method,url:t.response?.config.url,status:t.response?.status})})}function fp(t,e){(0,B.match)(e).with({code:nn.MISSING_SUITE,message:B.P.string,errors:B.P.array(B.P.string)},async r=>{let{message:o,errors:n}=r;ae(1),C(...sn(o,n))}).with({code:nn.RUN_EXPIRED,message:B.P.string},r=>{E(r.message)}).with({message:B.P.string,errors:B.P.array(B.P.string)},r=>{let{message:o,errors:n}=r;ae(1),E(...sn(o,n)),ae(1)}).otherwise(()=>{E(`[currents] Unexpected network response: %s
15
- %O`,t.message,{method:t.response?.config.method,url:t.response?.config.url,status:t.response?.status})})}var nn={RUN_CANCELLED:"RUN_CANCELLED",RUN_EXPIRED:"RUN_EXPIRED",MISSING_SUITE:"MISSING_SUITE"};function sn(t,e){return cn.default.isString(t)?e?.length===0?[t]:[t,`
11
+ `}var Cr=l(require("lodash")),op=["apiKey","recordKey","key"];function Ko(t,e){return Cr.default.isPlainObject(t)?Cr.default.mapValues(t,(r,o)=>e.includes(o)&&r!==void 0?"*****":Ko(r,e)):t}function h(t){return Ko(t,op)}var W=class extends Error{};var q=l(require("fs-extra")),Ht=require("path"),Ho=require("uuid");async function ht(t){try{return await q.default.readJson(t)}catch(e){throw C("Error while reading JSON file: %s",t,e),C}}async function Et(t,e){try{return await q.default.writeFile(t,e,"utf8"),t}catch(r){throw C(`Error writing file at ${t}:`,r),r}}async function Jt(t,e){try{try{return await q.default.access(t),t}catch{return await q.default.writeFile(t,e,"utf8"),t}}catch(r){throw C(`Error writing file at ${t}:`,r),r}}async function Jo(t,e){if(e){await q.default.ensureDir(t);return}let r=(0,Ht.dirname)(t);await q.default.ensureDir(r)}function np(){let t=new Date().toISOString().replace(/[:.]/g,"-"),e=(0,Ho.v4)();return`${t}-${e}`}async function Vo(t,e){let r=np(),o=(0,Ht.join)(t,e,r);return It(o)}async function It(t){try{return await q.default.ensureDir(t),p("Folder created",t),t}catch(e){throw C(`Failed to create folder at ${t}:`,e),e}}async function ce(t,e){try{return await q.default.ensureDir((0,Ht.dirname)(e)),await q.default.copy(t,e),p("File copied from %s to %s",t,e),e}catch(r){throw C(`Failed to copy file from ${t} to ${e}:`,r),r}}var Yo=l(require("crypto"));function et(t){return Yo.createHash("sha256").update(t).digest("base64").slice(0,8).replace(/\+/g,"-").replace(/\//g,"_").replace(/=+$/,"")}var pe={};Vc(pe,{getNanoid:()=>yr,userFacingNanoid:()=>Rr});var Tr=require("nanoid"),Wo="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz",yr=(t=16)=>(0,Tr.customAlphabet)(Wo,t)(),Rr=(0,Tr.customAlphabet)(Wo,12);function _r(t){return t.replace(/^([a-z][a-z0-9+.-]*:\/\/)[^/?#\s]*@/i,"$1")}function At(t){return _r(t).replace(/[?#].*$/,"")}function sp(t){return Object.entries(t??{}).reduce((e,[r,o])=>o===void 0?e:{...e,[r]:o},{})}function qo(t){if(!(t===void 0||t.trim()===""))return!["false","0","no","off"].includes(t.trim().toLowerCase())}function N(t,e){return"env"in t[e]&&t[e].env?t[e].env:""}function de(t,e){return t[e].cli}function me(t,e){return t[e].name}function U(t,e,r,o){let n=sp(r);return e.forEach(s=>{if(!n[s]){let i=s,c=N(t,i);throw C(`${me(t,i)} is required: pass ${x(de(t,i))}${c?` or set ${x(c)}`:""}`),new W("Missing required config variable")}}),typeof o=="function"&&o(n),n}var _={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{apiKey:ip,debug:ap,ciBuildId:cp,projectId:pp,tag:dp}=_,ue={apiKey:ip,debug:ap,ciBuildId:cp,projectId:pp,tag:dp,branch:{name:"Branch",cli:"--branch"},output:{name:"Output file",env:"CURRENTS_OUTPUT",cli:"--output"}};var mp=p.extend("config"),up=["apiKey","projectId"],lp=t=>{let{ciBuildId:e,tag:r,branch:o}=t;if(!([e,r,o].filter(Boolean).length===1||r&&o&&!e))throw C("Pass --ci-build-id, or --branch, --tag or both"),new W("Missing or invalid parameters")},wr=null;function zo(t){wr=U(ue,up,t,lp),mp("Resolved config: %o",h(wr))}function le(){return wr}var Pn=require("fs/promises");function St({apiKey:t,recordKey:e}){return e?{"x-currents-key":e}:t?{Authorization:`Bearer ${t}`}:{}}var fn=l(require("lodash"));var sn=l(require("axios")),an=l(require("axios-retry")),Ur=l(require("lodash"));var Qo=()=>process.env.CURRENTS_API_URL??"https://cy.currents.dev",Vt=()=>process.env.CURRENTS_REST_API_URL??"https://api.currents.dev",Xo=()=>3e4;var fe=require("axios"),Or=l(require("pretty-ms"));var tn=p.extend("http"),Zo=[3*1e3,15*1e3,30*1e3],en=60*1e3;function Ee(t,e=Date.now()){let r=t?.response?.headers?.["retry-after"];if(r==null||r==="")return;let o=Number(r);if(Number.isFinite(o))return Math.max(0,o*1e3);let n=Date.parse(String(r));return Number.isNaN(n)?void 0:Math.max(0,n-e)}var ge=(t,e)=>{let r=Zo[Math.min(t,Zo.length)-1],o=Ee(e);return o===void 0?r:Math.min(Math.max(o,r),en)},xr=t=>(tn("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,fe.isAxiosError)(t)}),"code"in t&&t.code&&["ECONNABORTED","ECONNREFUSED","ECONNRESET","ETIMEDOUT","ENETRESET"].includes(t.code)?!0:(0,fe.isAxiosError)(t)?[408,429,502,503,504].includes(t.response?.status??0):!1),fp=["get","head","options","put","delete"],rn=t=>{if(!(0,fe.isAxiosError)(t))return!1;let e=t.response?.status;if(e===429){let r=Ee(t);return r===void 0||r<=en}return fp.includes(t.config?.method?.toLowerCase()??"get")?xr(t):e===408||t.code==="ECONNREFUSED"||t.code==="ENOTFOUND"},he=()=>3;function on(t,e,r){tn("Network request '%s' failed: '%s'. Next attempt is in %s (%d/%d).",`${r.method?.toUpperCase()} ${r.url}`,e.message,(0,Or.default)(ge(t,e)??0),t,he()),E("Network request '%s' failed: '%s'. Next attempt is in %s (%d/%d).",`${r.method?.toUpperCase()} ${r.url}`,e.message,(0,Or.default)(ge(t,e)??0),t,he())}var Ar=p.extend("http");var Sr={api:null,restApi:null};function gp(t){let e=t==="api"?Qo():Vt();Ar("client base url: %s",e);let r=sn.default.create({baseURL:e,timeout:Xo(),transitional:{clarifyTimeoutError:!0}});return r.interceptors.request.use(o=>{let n=o["axios-retry"]?.retryCount??0;o.headers.set({"x-cmd-version":xt}),o.headers.get("Content-Type")||o.headers.set("Content-Type","application/json");let s={...Ur.default.pick(o,"method","url","headers"),baseURL:e,data:Buffer.isBuffer(o.data)?"buffer":o.data,params:o.params};return n?Ar("network request retry: %o",nn({...s,baseURL:e,isRetry:!0})):Ar("network request: %o",nn(s)),o}),(0,an.default)(r,{retries:he(),retryCondition:t==="restApi"?rn:xr,retryDelay:(o,n)=>ge(o,n),shouldResetTimeout:!0,onRetry:on}),r}function Ut(t){return Sr[t]===null&&(Sr[t]=gp(t)),Sr[t]}function nn(t){return{method:t.method,baseURL:t.baseURL,url:t.url,data:t.isRetry?"<retry>":hp(t.data),params:t.isRetry?"<retry>":t.params,headers:{...t.headers,Authorization:"Bearer ***","x-currents-key":"***"}}}function hp(t){if(t?.results?.raw)return h({...t,results:{...t.results,raw:"***"}});if(typeof t=="string")try{return h(JSON.parse(t))}catch{return t}return Ur.default.isPlainObject(t)?h(t):t}var dn=require("axios"),mn=l(require("lodash")),v=require("ts-pattern");function un(t){(0,v.match)(t).when(dn.isAxiosError,Ep).otherwise(()=>{E("Unexpected error while sending network request: %s",t)})}function Ep(t){return(0,v.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:v.P.not(v.P.nullish)},e=>{Ip(e,{status:e.response.status,data:e.response.data})}).otherwise(e=>{E(`[currents] Unexpected network error: %s
12
+ %O`,t.message,{method:t.response?.config.method,url:t.response?.config.url,status:t.response?.status,payload:t.response?.config.data})})}function Ip(t,{status:e,data:r}){(0,v.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:
13
+ %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,()=>{Cp(t,r)}).otherwise(()=>{E(`[currents] Unexpected network response: %s
14
+ %O`,t.message,{method:t.response?.config.method,url:t.response?.config.url,status:t.response?.status})})}function Cp(t,e){(0,v.match)(e).with({code:cn.MISSING_SUITE,message:v.P.string,errors:v.P.array(v.P.string)},async r=>{let{message:o,errors:n}=r;ae(1),C(...pn(o,n))}).with({code:cn.RUN_EXPIRED,message:v.P.string},r=>{E(r.message)}).with({message:v.P.string,errors:v.P.array(v.P.string)},r=>{let{message:o,errors:n}=r;ae(1),E(...pn(o,n)),ae(1)}).otherwise(()=>{E(`[currents] Unexpected network response: %s
15
+ %O`,t.message,{method:t.response?.config.method,url:t.response?.config.url,status:t.response?.status})})}var cn={RUN_CANCELLED:"RUN_CANCELLED",RUN_EXPIRED:"RUN_EXPIRED",MISSING_SUITE:"MISSING_SUITE"};function pn(t,e){return mn.default.isString(t)?e?.length===0?[t]:[t,`
16
16
  ${(e??[]).map(r=>` - ${r}`).join(`
17
17
  `)}
18
- `]:["Unexpected network error"]}var dn=p.extend("http");async function z(t,e,r=Ut){try{let o=await r(t).request(e);return dn("network response: %o",{...mn.default.omit(o,"request","config"),url:o.config.url,method:o.config.method}),o}catch(o){let n=o;throw dn("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}),pn(n),n}}var Dt=p.extend("api");async function un(t){try{return Dt("Request params: %o",h(t)),z("api",{url:"cache/upload",method:"POST",data:t}).then(e=>e.data)}catch(e){throw Dt("Failed to create cache:",e),e}}async function ln(t){try{return Dt("Request params: %o",h(t)),z("api",{url:"cache/v2/download",method:"POST",data:t}).then(e=>e.data)}catch(e){throw Dt("Failed to retrieve cache:",e),e}}async function fn(t){try{return Dt("Request params: %o",h(t)),z("api",{url:"cache/meta",method:"POST",data:t}).then(e=>e.data)}catch(e){throw Dt("Failed to retrieve reference cache meta:",e),e}}var gp=p.extend("api");async function gn(t){return gp("Cancel params: %o",h(t)),(await z("api",{url:"v1/runs/cancel",method:"POST",data:t})).data}var En=require("util"),In=require("zlib");var hn=p.extend("api"),hp=(0,En.promisify)(In.gzip);async function Cn(t){try{hn("Run params: %o",h(t));let e=await Ep(JSON.stringify(t));return z("api",{url:"v1/runs",method:"POST",headers:{"Content-Type":"application/json","Content-Encoding":"gzip"},data:e}).then(r=>r.data)}catch(e){throw hn("Failed to create the run:",e),e}}async function Ep(t){try{return await hp(t)}catch(e){throw C("Failed to compress run payload:",e),e}}var Tn=p.extend("api");async function yn(t,e){try{return Tn("Run params: %o",e),z("restApi",{url:"v1/runs/find",params:e,method:"GET",headers:{"Content-Type":"application/json",...St({apiKey:t})}}).then(r=>r.data)}catch(r){throw Tn("Failed to obtain run data:",r),r}}var Rn=require("axios");var _n=p.extend("api");function Ip(t){if(!(0,Rn.isAxiosError)(t)||!t.response)return t;let e=t.response.data,r=[`${t.response.status}`];e?.code&&r.push(e.code);let o=e?.error??t.message,n=Ee(t),s=n?` Retry in ${Math.ceil(n/1e3)} seconds.`:"",i=Cp(e?.candidates);return new Error(`${r.join(" ")}: ${o}${s}${i}`)}function Cp(t){return!Array.isArray(t)||t.length===0?"":`
18
+ `]:["Unexpected network error"]}var ln=p.extend("http");async function z(t,e,r=Ut){try{let o=await r(t).request(e);return ln("network response: %o",{...fn.default.omit(o,"request","config"),url:o.config.url,method:o.config.method}),o}catch(o){let n=o;throw ln("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}),un(n),n}}var Dt=p.extend("api");async function gn(t){try{return Dt("Request params: %o",h(t)),z("api",{url:"cache/upload",method:"POST",data:t}).then(e=>e.data)}catch(e){throw Dt("Failed to create cache:",e),e}}async function hn(t){try{return Dt("Request params: %o",h(t)),z("api",{url:"cache/v2/download",method:"POST",data:t}).then(e=>e.data)}catch(e){throw Dt("Failed to retrieve cache:",e),e}}async function En(t){try{return Dt("Request params: %o",h(t)),z("api",{url:"cache/meta",method:"POST",data:t}).then(e=>e.data)}catch(e){throw Dt("Failed to retrieve reference cache meta:",e),e}}var Tp=p.extend("api");async function In(t){return Tp("Cancel params: %o",h(t)),(await z("api",{url:"v1/runs/cancel",method:"POST",data:t})).data}var Tn=require("util"),yn=require("zlib");var Cn=p.extend("api"),yp=(0,Tn.promisify)(yn.gzip);async function Rn(t){try{Cn("Run params: %o",h(t));let e=await Rp(JSON.stringify(t));return z("api",{url:"v1/runs",method:"POST",headers:{"Content-Type":"application/json","Content-Encoding":"gzip"},data:e}).then(r=>r.data)}catch(e){throw Cn("Failed to create the run:",e),e}}async function Rp(t){try{return await yp(t)}catch(e){throw C("Failed to compress run payload:",e),e}}var _n=p.extend("api");async function wn(t,e){try{return _n("Run params: %o",e),z("restApi",{url:"v1/runs/find",params:e,method:"GET",headers:{"Content-Type":"application/json",...St({apiKey:t})}}).then(r=>r.data)}catch(r){throw _n("Failed to obtain run data:",r),r}}var On=require("axios");var xn=p.extend("api");function _p(t){if(!(0,On.isAxiosError)(t)||!t.response)return t;let e=t.response.data,r=[`${t.response.status}`];e?.code&&r.push(e.code);let o=e?.error??t.message,n=Ee(t),s=n?` Retry in ${Math.ceil(n/1e3)} seconds.`:"",i=wp(e?.candidates);return new Error(`${r.join(" ")}: ${o}${s}${i}`)}function wp(t){return!Array.isArray(t)||t.length===0?"":`
19
19
  Matches:
20
20
  ${t.map(({spec:r,title:o,instanceId:n,testId:s,runId:i,ciBuildId:c})=>i?` - run ${i} (CI build ID ${c})`:` - ${[r,o].filter(Boolean).join(" > ")} (instance ${n}${s?`, test ${s}`:""})`).join(`
21
- `)}`}async function Wt(t,e,r){try{return(await Ut("restApi").post(t,r,{headers:St(e)})).data.data}catch(o){throw Ip(o)}}function wn(t,e){return _n("Create session params: %o",e),Wt("v1/sessions",{apiKey:t},e)}function On(t,e,r,o){return _n("Create attachments: %o",{owner:e,target:r,attachments:o}),"sessionId"in e?Wt(`v1/sessions/${encodeURIComponent(e.sessionId)}/attachments`,t,{attachments:o}):"runId"in e?Wt(`v1/runs/${encodeURIComponent(e.runId)}/attachments`,t,{...r,attachments:o}):Wt("v1/runs/attachments",t,{...e,...r,attachments:o})}function xn(t,e){return Wt("v1/share",{apiKey:t},e)}function An(t,e){return Ut("restApi").request({...e,headers:{...St({apiKey:t}),...e.headers},responseType:"text",transformResponse:r=>r})}async function Sr(){try{let t=le();if(!t)throw new Error("Config is missing!");let e=t.ciBuildId?{projectId:t.projectId,ciBuildId:t.ciBuildId,pwLastRun:t.pwLastRun}:{projectId:t.projectId,branch:t.branch,tag:t.tag,pwLastRun:t.pwLastRun},r=await yn(t.apiKey,e);if(t.pwLastRun&&!r.data.pwLastRun)throw new Error("The API answered without the status and failed tests of the run (pwLastRun). Nothing was written.");await Tp(t.pwLastRun?r.data.pwLastRun:r.data,t)}catch(t){throw p("Failed to get run data"),t}}async function Tp(t,e){let r=JSON.stringify(t,null,2);e.output?(await Ko(e.output),await(0,Sn.writeFile)(e.output,r,"utf-8"),T(`Successfully written to ${e.output}`)):process.stdout.write(r+`
22
- `)}var Os=require("axios"),Gr=l(require("path"));var v=require("@commander-js/extra-typings");var Un=require("@commander-js/extra-typings");function Ie(t,e=[]){return t?e.concat(t.split(",").map(r=>r.trim())):e}function Dn(t){for(let e of t.options){let r=e.attributeName();if(!e.envVar||!e.isBoolean()||t.getOptionValueSource(r)!=="env")continue;let o=Jo(process.env[e.envVar]);t.setOptionValueWithSource(r,o??e.defaultValue,o===void 0?"default":"env")}}function yp(t,e){if(!Array.isArray(t))return String(t)===e;let r=o=>o.map(n=>n.trim()).filter(Boolean).join(",");return r(t.map(String))===r(e.split(","))}function Pn(t){for(let e of t.options){let r=e.attributeName(),o=e.envVar?process.env[e.envVar]:void 0,n=t.getOptionValue(r);!o||e.isBoolean()||t.getOptionValueSource(r)!=="cli"||yp(n,o)||se(`${e.long} and ${e.envVar} are set to different values; using ${e.long}`)}}function Pt(){console.log=(...t)=>console.error(...t)}async function w(t,e){try{e.debug&&No(),await t(e),process.exit(0)}catch(r){C(r.message);let o=r instanceof Un.CommanderError?r.exitCode:1;process.exit(o)}}var bn="Without it the ID comes from the CI job: on GitHub Actions the repository, the run ID and --matrix-index; on GitLab the pipeline ID and the job name; on other CI the variables that identify the pipeline and the job, and --matrix-index. When no CI job is detected the ID is random, so pass --id",Nn=new v.Option("--id <id>",`the ID to save the files under. ${bn}`),Ln=new v.Option("--id <id>",`the ID the files were saved under. ${bn}`),Bn=new v.Option("--path <path>",'comma-separated paths or glob patterns of the files to save, inside the current folder; quote globs, e.g. "dist/**/*". At most 50 MB zipped').argParser(Ie),qt=(e=>(e.lastRun="last-run",e))(qt||{}),vn=new v.Option("--preset <preset-name>",'"last-run" saves the Playwright .last-run.json files of --pw-output-dir, to rerun only the failed tests').choices(Object.values(qt)),Mn=new v.Option("--preset <preset-name>",'"last-run" restores the saved .last-run.json files and writes the Playwright options for the rerun to --preset-output').choices(Object.values(qt)),Fn=new v.Option("--output-dir <folder>","the folder to restore the files to; by default the current folder"),kn=new v.Option("--pw-output-dir <folder>","the Playwright output folder that holds .last-run.json").default("test-results"),zt=".currents_env",Gn=new v.Option("--preset-output <path>",'the file the "last-run" preset writes, relative to the current folder. On GitHub Actions and CircleCI it holds options for "playwright test"; on GitLab the shell variables EXTRA_PW_FLAGS, EXTRA_PWCP_FLAGS and RUN_ATTEMPT, to source. Nothing is written on other CI').default(zt),Ur=new v.Option("--matrix-index <number>","the index of this job among parallel jobs, from 1; each job has its own cache. Pass it when the CI does not tell the jobs apart, as in a GitHub Actions matrix").default(1).argParser($n),Dr=new v.Option("--matrix-total <number>","GitHub Actions only: the number of jobs in the matrix, for the shards that the last-run preset writes").default(1).argParser($n);function $n(t){let e=parseInt(t,10);if(isNaN(e)||e<=0||!Number.isInteger(e))throw new v.InvalidArgumentError("A positive integer is expected.");return e}var Kn=new v.Option("--continue","exit with 0 when the cache is not found").default(!1),Hn=new v.Option("--continue","exit with 0 when no files are found, and save the cache without files").default(!1);var Rp={recordKey:_.recordKey,debug:_.debug},_p={id:{name:"Cache id",cli:"--id"},preset:{name:"Preset",cli:"--preset"},pwOutputDir:{name:"Playwright output folder",cli:"--pw-output-dir"},presetOutput:{name:"Preset output path",cli:"--preset-output"},path:{name:"Paths to cache",cli:"--path"},matrixIndex:{name:"Matrix index",cli:"--matrix-index"},matrixTotal:{name:"Matrix total",cli:"--matrix-total"},continue:{name:"Continue when upload path missing",cli:"--continue"}},wp={id:{name:"Cache id",cli:"--id"},preset:{name:"Preset",cli:"--preset"},outputDir:{name:"Output folder",cli:"--output-dir"},matrixIndex:{name:"Matrix index",cli:"--matrix-index"},matrixTotal:{name:"Matrix total",cli:"--matrix-total"},continue:{name:"Continue on cache miss",cli:"--continue"}},Pr={...Rp,..._p,...wp};var jn=p.extend("config"),Vn=["recordKey"],Ct;function Jn(t){Ct={type:"SET_COMMAND_CONFIG",values:U(Pr,Vn,t)},jn("Resolved config: %o",{...Ct,values:h(Ct.values)})}function Yn(t){Ct={type:"GET_COMMAND_CONFIG",values:U(Pr,Vn,t)},jn("Resolved config: %o",{...Ct,values:h(Ct.values)})}function dt(){return Ct}function Wn(t){return{recordKey:t.key,id:t.id,preset:t.preset,outputDir:t.outputDir,presetOutput:t.presetOutput,debug:t.debug,matrixIndex:t.matrixIndex,matrixTotal:t.matrixTotal,continue:t.continue}}function qn(t){return{recordKey:t.key,id:t.id,preset:t.preset,pwOutputDir:t.pwOutputDir,path:t.path,debug:t.debug,matrixIndex:t.matrixIndex,matrixTotal:t.matrixTotal,continue:t.continue}}var R=require("lodash");var Ce=p.extend("ci"),Op=(t,e)=>(0,R.set)(t,(0,R.camelCase)(e),process.env[e]),D=t=>(0,R.transform)(t,Op,{}),xp=()=>process.env.TF_BUILD&&process.env.AZURE_HTTP_USER_AGENT,Ap=()=>(0,R.some)(process.env,(t,e)=>/^CODEBUILD_/.test(e)),Sp=()=>process.env.bamboo_buildNumber,Up=()=>(0,R.some)(process.env,(t,e)=>/^CONCOURSE_/.test(e)),Dp=()=>process.env.GITLAB_CI||process.env.CI_SERVER_NAME&&/^GitLab/.test(process.env.CI_SERVER_NAME),Pp=()=>!!(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),bp=()=>process.env.JENKINS_URL||process.env.JENKINS_HOME||process.env.JENKINS_VERSION||process.env.HUDSON_URL||process.env.HUDSON_HOME,Np={appveyor:"APPVEYOR",azure:xp,awsCodeBuild:Ap,bamboo:Sp,bitbucket:"BITBUCKET_BUILD_NUMBER",buildkite:"BUILDKITE",circle:"CIRCLECI",concourse:Up,codeFresh:"CF_BUILD_ID",drone:"DRONE",githubActions:"GITHUB_ACTIONS",gitlab:Dp,goCD:"GO_JOB_NAME",jenkins:bp,googleCloud:Pp,semaphore:"SEMAPHORE",teamcity:"TEAMCITY_VERSION",travis:"TRAVIS",netlify:"NETLIFY"};function Lp(){let{env:t}=process;return(0,R.findKey)(Np,e=>{if((0,R.isString)(e))return t[e];if((0,R.isFunction)(e))return e()})}var zn=()=>({appveyor:D(["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:D(["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:D(["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:D(["bamboo_buildNumber","bamboo_buildResultsUrl","bamboo_planRepository_repositoryUrl","bamboo_buildKey"]),bitbucket:D(["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:D(["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:D(["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:D(["BUILD_ID","BUILD_NAME","BUILD_JOB_NAME","BUILD_PIPELINE_NAME","BUILD_TEAM_NAME","ATC_EXTERNAL_URL"]),codeFresh:D(["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:D(["DRONE_BUILD_LINK","DRONE_BUILD_NUMBER","DRONE_PULL_REQUEST"]),githubActions:D(["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:D(["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:D(["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:D(["BUILD_ID","PROJECT_ID","REPO_NAME","BRANCH_NAME","TAG_NAME","COMMIT_SHA","SHORT_SHA"]),jenkins:D(["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:D(["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:D(["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:D(["BUILD_ID","CONTEXT","URL","DEPLOY_URL","DEPLOY_PRIME_URL","DEPLOY_ID"])}),Bp=t=>{let e=Qn();return e?(0,R.chain)(t()).get(e).value():{}};function vp(){return(0,R.chain)(zn()).omitBy(R.isNull).keys().value()}function Mp(t){return t&&vp().includes(t)}function Qn(){let t=Lp();return Ce("detected CI provider name: %s",t),t||null}function Fp(){let t=Bp(zn);return(0,R.mapValues)(t,e=>(0,R.isString)(e)?yr(e):e)}function rt(t){let e=Fp(),r=Qn(),o=kp(t,r);return Ce("detected CI provider: %s",r),Ce("detected CI params: %O",e),Ce("detected CI build ID: %o",o),{params:e,provider:r,ciBuildId:o}}function kp(t,e){return t?{source:"user",value:t}:Mp(e)?{source:"server",value:null}:{source:"random",value:`auto:${Tr()}`}}var Xn=l(require("archiver")),Zn=l(require("fs-extra")),br=l(require("path")),ts=l(require("unzipper"));var Gp=50*1024*1024;async function es(t,e=Gp){return new Promise((r,o)=>{let n=(0,Xn.default)("zip",{zlib:{level:9}}),s=[],i=0;n.on("data",d=>{s.push(d),i+=d.length,i>e&&o(new Error(`Zip size exceeded the limit of ${e} bytes`))}),n.on("warning",d=>{d.code==="ENOENT"?E(d):o(d)}),n.on("error",d=>o(d)),n.on("end",()=>{let d=Buffer.concat(s);r(d)});let c=async d=>{let f=process.cwd(),u=br.default.normalize(d),I=br.default.relative(f,u),g=await Zn.default.stat(d);g.isDirectory()?n.directory(d,I):n.file(d,{name:I,stats:g})};(async d=>{for(let f of d)await c(f);await n.finalize()})(t).catch(o)})}async function rs(t,e){return ts.default.Open.buffer(t).then(r=>r.extract({path:e,concurrency:3}))}var os=require("lodash");var $p={githubActions:[],gitlab:[],appveyor:["APPVEYOR_ACCOUNT_NAME","APPVEYOR_PROJECT_SLUG","APPVEYOR_BUILD_NUMBER"],azure:["SYSTEM_COLLECTIONID","BUILD_BUILDID"],awsCodeBuild:["CODEBUILD_BUILD_ID"],bamboo:["bamboo_buildKey","bamboo_buildNumber"],bitbucket:["BITBUCKET_PIPELINE_UUID"],buildkite:["BUILDKITE_BUILD_ID"],circle:["CIRCLE_WORKFLOW_WORKSPACE_ID"],concourse:["BUILD_ID"],codeFresh:["CF_BUILD_ID"],drone:["DRONE_BUILD_LINK"],goCD:["GO_PIPELINE_NAME","GO_PIPELINE_COUNTER"],googleCloud:["BUILD_ID"],jenkins:["JOB_NAME","BUILD_NUMBER"],semaphore:["SEMAPHORE_PIPELINE_ID"],travis:["TRAVIS_JOB_ID"],netlify:["BUILD_ID"]};function Kp({provider:t,params:e}){let r=t?$p[t]:null;return!r||!e?!1:r.every(o=>!!e[(0,os.camelCase)(o)])}function Te(t,e){e||Kp(t)||se("No CI job detected: without --id the cache ID is random, so cache get does not find what cache set saved. Pass --id to save and restore the same cache.")}var cs=l(require("async-retry")),ps=l(require("fs")),ds=require("stream"),Qt=require("axios");var ns=l(require("axios")),ss=require("https-proxy-agent"),is=l(require("proxy-from-env"));var Hp=p.extend("axios");function Nr(t={}){let e=ns.default.create(t);return e.interceptors.request.use(r=>{let o={...r},n=e.getUri(r),s=is.default.getProxyForUrl(n);return s&&(Hp("Using HTTP proxy %s for %s",At(s),At(n)),o.proxy=!1,o.httpsAgent=jp(s)),o}),e}var ye=null;function jp(t){return ye||(ye=new ss.HttpsProxyAgent(t),ye)}var Xt=p.extend("upload"),Re=5;async function Lr(t,e,r){return Xt("Uploading buffer %s",t.name,{buffer:Buffer.byteLength(t.buffer)}),gs(t.buffer,t.uploadUrl,e,r,t.headers,us(Buffer.byteLength(t.buffer)))}var Vp=256*1024,Jp=120*1e3;async function ms(t){return Xt("Uploading file %s",t.name,{bytes:t.sizeBytes}),gs(()=>t.sizeBytes>0?ps.default.createReadStream(t.path,{end:t.sizeBytes-1}):ds.Readable.from([]),t.uploadUrl,t.contentType,void 0,{...t.headers??{"Content-Type":t.contentType},"Content-Length":String(t.sizeBytes)},us(t.sizeBytes))}function us(t){return Jp+Math.ceil(t/Vp)*1e3}async function Yp(t,e,r,o,n,s){return Nr().request({method:"put",url:e,timeout:s,data:typeof t=="function"?t():t,...typeof t=="function"&&{maxRedirects:0},onUploadProgress:o,headers:n??{"Content-Disposition":"inline","Content-Type":r}})}async function Br(t,e){try{let r=await Nr().get(t,{responseType:"arraybuffer",onDownloadProgress:e});return Buffer.isBuffer(r.data)?r.data:Buffer.from(r.data)}catch(r){throw(0,Qt.isAxiosError)(r)&&Xt("Failed to download %s: %s",At(t),r.message),r}}var Wp=["RequestTimeout","OperationAborted","SlowDown"];function ls(t){if(t)return t.replace(/[\u0000-\u001f\u007f-\u009f]/g,"").replace(/\b[a-z][a-z0-9+.-]*:\/\/\S+/gi,e=>At(e)).slice(0,200)}function fs(t){let e=(0,Qt.isAxiosError)(t)?t.response?.data:void 0,r=typeof e=="string"?e:"";return{code:r.match(/<Code>([^<]*)<\/Code>/)?.[1],message:ls(r.match(/<Message>([^<]*)<\/Message>/)?.[1])}}function qp(t){let e=(0,Qt.isAxiosError)(t)?t.response?.status:void 0;if(e===void 0||e<400||e>=500||e===408||e===429)return!1;let{code:r}=fs(t);return!(r&&Wp.includes(r))}function zp(t){if(!(0,Qt.isAxiosError)(t)||!t.response)return t instanceof Error?t:new Error(String(t));let{code:e,message:r}=fs(t),o=[ls(e),r].filter(Boolean).join(": ");return new Error(`storage answered ${t.response.status}${o?` ${o}`:""}`)}async function gs(...t){try{await Qp(t)}catch(e){throw zp(e)}}async function Qp(t){await(0,cs.default)(async e=>{try{await Yp(...t)}catch(r){if(qp(r)){e(r);return}throw r}},{retries:Re,onRetry:(e,r)=>{if(Xt("Upload failed %d out of %d attempts: %s",r,Re,e.message),r===Re){C(`Cannot upload after ${r} times: ${e.message}`);return}E(`Upload failed ${r} out of ${Re} attempts: ${e.message}`)}})}var vr=t=>({total:e,loaded:r})=>{Xt("Uploading %s: %d / %d",t,as(r),as(e??0))};function as(t){return t/1e3/1e3}var kr=l(require("lodash"));var ot=l(require("path")),Fr=l(require("globby"));var hs=require("lodash");function Mr({config:t,cacheId:e,orgId:r,path:o,ci:n,cacheKey:s,metaCacheKey:i}){let c={id:e,orgId:r,config:(0,hs.omit)(t,"recordKey"),path:o,ci:n,createdAt:new Date().toISOString(),cacheKey:s,metaCacheKey:i};return Buffer.from(JSON.stringify(c))}function Es(t,e){t instanceof Error?gt("%s. %s.",e,t.message):gt("%s. %s.",e,"Unknown error")}var Is=async t=>{let e=ot.default.resolve(t??"./test-results"),r=[ot.default.posix.join(e.replace(/\\/g,"/"),"**/.last-run.json"),ot.default.posix.join(e.replace(/\\/g,"/"),".last-run.json")];return Fr.sync(r)},Cs=async(t=[])=>{let e=Xp(t);return e.length===0?[]:Fr.sync(e.map(r=>r.replace(/\\/g,"/")))};function Xp(t){let e=process.cwd();return t.filter(r=>{let o=ot.default.relative(e,ot.default.resolve(r));return o===".."||o.startsWith(`..${ot.default.sep}`)||ot.default.isAbsolute(o)?(Es(null,`Invalid path: "${r}". Path traversal detected. The path was skipped.`),!1):!0})}function _e(t){return t?t.path.some(e=>ot.default.basename(e)===".last-run.json"):!1}async function Ts(t,e){switch(e.provider){case"githubActions":await _s(t,e);break;case"gitlab":await Rs(t,e);break;case"circle":await ws(t,e);break;default:break}}async function ys(t,e,r){switch(e.provider){case"githubActions":await _s(t,e,r);break;case"gitlab":await Rs(t,e,r);break;case"circle":await ws(t,e,r);break;default:break}}async function Rs(t,e,r=null){let o=e.params,n=r?.ci.params,i=(n?bt(n.runAttempt,0):0)+1,c=bt(o.ciNodeIndex,1),m=bt(o.ciNodeTotal,1),d=_e(r),f=i>1&&d,u=f?"--last-failed":"",I="";m>1&&(I=f?"--shard=1/1":`--shard=${c}/${m}`);let g=[u,I].filter(Boolean).join(" ");await Et(t.presetOutput??zt,`EXTRA_PW_FLAGS="${g}"
21
+ `)}`}async function Wt(t,e,r){try{return(await Ut("restApi").post(t,r,{headers:St(e)})).data.data}catch(o){throw _p(o)}}function An(t,e){return xn("Create session params: %o",e),Wt("v1/sessions",{apiKey:t},e)}function Sn(t,e,r,o){return xn("Create attachments: %o",{owner:e,target:r,attachments:o}),"sessionId"in e?Wt(`v1/sessions/${encodeURIComponent(e.sessionId)}/attachments`,t,{attachments:o}):"runId"in e?Wt(`v1/runs/${encodeURIComponent(e.runId)}/attachments`,t,{...r,attachments:o}):Wt("v1/runs/attachments",t,{...e,...r,attachments:o})}function Un(t,e){return Wt("v1/share",{apiKey:t},e)}function Dn(t,e){return Ut("restApi").request({...e,headers:{...St({apiKey:t}),...e.headers},responseType:"text",transformResponse:r=>r})}async function Dr(){try{let t=le();if(!t)throw new Error("Config is missing!");let e=t.ciBuildId?{projectId:t.projectId,ciBuildId:t.ciBuildId,pwLastRun:t.pwLastRun}:{projectId:t.projectId,branch:t.branch,tag:t.tag,pwLastRun:t.pwLastRun},r=await wn(t.apiKey,e);if(t.pwLastRun&&!r.data.pwLastRun)throw new Error("The API answered without the status and failed tests of the run (pwLastRun). Nothing was written.");await Op(t.pwLastRun?r.data.pwLastRun:r.data,t)}catch(t){throw p("Failed to get run data"),t}}async function Op(t,e){let r=JSON.stringify(t,null,2);e.output?(await Jo(e.output),await(0,Pn.writeFile)(e.output,r,"utf-8"),T(`Successfully written to ${e.output}`)):process.stdout.write(r+`
22
+ `)}var Ss=require("axios"),$r=l(require("path"));var B=require("@commander-js/extra-typings");var bn=require("@commander-js/extra-typings");function Ie(t,e=[]){return t?e.concat(t.split(",").map(r=>r.trim())):e}function Nn(t){for(let e of t.options){let r=e.attributeName();if(!e.envVar||!e.isBoolean()||t.getOptionValueSource(r)!=="env")continue;let o=qo(process.env[e.envVar]);t.setOptionValueWithSource(r,o??e.defaultValue,o===void 0?"default":"env")}}function xp(t,e){if(!Array.isArray(t))return String(t)===e;let r=o=>o.map(n=>n.trim()).filter(Boolean).join(",");return r(t.map(String))===r(e.split(","))}function Ln(t){for(let e of t.options){let r=e.attributeName(),o=e.envVar?process.env[e.envVar]:void 0,n=t.getOptionValue(r);!o||e.isBoolean()||t.getOptionValueSource(r)!=="cli"||xp(n,o)||se(`${e.long} and ${e.envVar} are set to different values; using ${e.long}`)}}function Pt(){console.log=(...t)=>console.error(...t)}async function w(t,e){try{e.debug&&Bo(),await t(e),process.exit(0)}catch(r){C(r.message);let o=r instanceof bn.CommanderError?r.exitCode:1;process.exit(o)}}var vn="Without it the ID comes from the CI job: on GitHub Actions the repository, the run ID and --matrix-index; on GitLab the pipeline ID and the job name; on other CI the variables that identify the pipeline and the job, and --matrix-index. When no CI job is detected the ID is random, so pass --id",Bn=new B.Option("--id <id>",`the ID to save the files under. ${vn}`),Mn=new B.Option("--id <id>",`the ID the files were saved under. ${vn}`),Fn=new B.Option("--path <path>",'comma-separated paths or glob patterns of the files to save, inside the current folder; quote globs, e.g. "dist/**/*". At most 50 MB zipped').argParser(Ie),qt=(e=>(e.lastRun="last-run",e))(qt||{}),kn=new B.Option("--preset <preset-name>",'"last-run" saves the Playwright .last-run.json files of --pw-output-dir, to rerun only the failed tests').choices(Object.values(qt)),Gn=new B.Option("--preset <preset-name>",'"last-run" restores the saved .last-run.json files and writes the Playwright options for the rerun to --preset-output').choices(Object.values(qt)),jn=new B.Option("--output-dir <folder>","the folder to restore the files to; by default the current folder"),$n=new B.Option("--pw-output-dir <folder>","the Playwright output folder that holds .last-run.json").default("test-results"),zt=".currents_env",Kn=new B.Option("--preset-output <path>",'the file the "last-run" preset writes, relative to the current folder. On GitHub Actions and CircleCI it holds options for "playwright test"; on GitLab the shell variables EXTRA_PW_FLAGS, EXTRA_PWCP_FLAGS and RUN_ATTEMPT, to source. Nothing is written on other CI').default(zt),Pr=new B.Option("--matrix-index <number>","the index of this job among parallel jobs, from 1; each job has its own cache. Pass it when the CI does not tell the jobs apart, as in a GitHub Actions matrix").default(1).argParser(Hn),br=new B.Option("--matrix-total <number>","GitHub Actions only: the number of jobs in the matrix, for the shards that the last-run preset writes").default(1).argParser(Hn);function Hn(t){let e=parseInt(t,10);if(isNaN(e)||e<=0||!Number.isInteger(e))throw new B.InvalidArgumentError("A positive integer is expected.");return e}var Jn=new B.Option("--continue","exit with 0 when the cache is not found").default(!1),Vn=new B.Option("--continue","exit with 0 when no files are found, and save the cache without files").default(!1);var Ap={recordKey:_.recordKey,debug:_.debug},Sp={id:{name:"Cache id",cli:"--id"},preset:{name:"Preset",cli:"--preset"},pwOutputDir:{name:"Playwright output folder",cli:"--pw-output-dir"},presetOutput:{name:"Preset output path",cli:"--preset-output"},path:{name:"Paths to cache",cli:"--path"},matrixIndex:{name:"Matrix index",cli:"--matrix-index"},matrixTotal:{name:"Matrix total",cli:"--matrix-total"},continue:{name:"Continue when upload path missing",cli:"--continue"}},Up={id:{name:"Cache id",cli:"--id"},preset:{name:"Preset",cli:"--preset"},outputDir:{name:"Output folder",cli:"--output-dir"},matrixIndex:{name:"Matrix index",cli:"--matrix-index"},matrixTotal:{name:"Matrix total",cli:"--matrix-total"},continue:{name:"Continue on cache miss",cli:"--continue"}},Nr={...Ap,...Sp,...Up};var Yn=p.extend("config"),Wn=["recordKey"],Ct;function qn(t){Ct={type:"SET_COMMAND_CONFIG",values:U(Nr,Wn,t)},Yn("Resolved config: %o",{...Ct,values:h(Ct.values)})}function zn(t){Ct={type:"GET_COMMAND_CONFIG",values:U(Nr,Wn,t)},Yn("Resolved config: %o",{...Ct,values:h(Ct.values)})}function dt(){return Ct}function Qn(t){return{recordKey:t.key,id:t.id,preset:t.preset,outputDir:t.outputDir,presetOutput:t.presetOutput,debug:t.debug,matrixIndex:t.matrixIndex,matrixTotal:t.matrixTotal,continue:t.continue}}function Xn(t){return{recordKey:t.key,id:t.id,preset:t.preset,pwOutputDir:t.pwOutputDir,path:t.path,debug:t.debug,matrixIndex:t.matrixIndex,matrixTotal:t.matrixTotal,continue:t.continue}}var R=require("lodash");var Ce=p.extend("ci"),Dp=(t,e)=>(0,R.set)(t,(0,R.camelCase)(e),process.env[e]),D=t=>(0,R.transform)(t,Dp,{}),Pp=()=>process.env.TF_BUILD&&process.env.AZURE_HTTP_USER_AGENT,bp=()=>(0,R.some)(process.env,(t,e)=>/^CODEBUILD_/.test(e)),Np=()=>process.env.bamboo_buildNumber,Lp=()=>(0,R.some)(process.env,(t,e)=>/^CONCOURSE_/.test(e)),vp=()=>process.env.GITLAB_CI||process.env.CI_SERVER_NAME&&/^GitLab/.test(process.env.CI_SERVER_NAME),Bp=()=>!!(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),Mp=()=>process.env.JENKINS_URL||process.env.JENKINS_HOME||process.env.JENKINS_VERSION||process.env.HUDSON_URL||process.env.HUDSON_HOME,Fp={appveyor:"APPVEYOR",azure:Pp,awsCodeBuild:bp,bamboo:Np,bitbucket:"BITBUCKET_BUILD_NUMBER",buildkite:"BUILDKITE",circle:"CIRCLECI",concourse:Lp,codeFresh:"CF_BUILD_ID",drone:"DRONE",githubActions:"GITHUB_ACTIONS",gitlab:vp,goCD:"GO_JOB_NAME",jenkins:Mp,googleCloud:Bp,semaphore:"SEMAPHORE",teamcity:"TEAMCITY_VERSION",travis:"TRAVIS",netlify:"NETLIFY"};function kp(){let{env:t}=process;return(0,R.findKey)(Fp,e=>{if((0,R.isString)(e))return t[e];if((0,R.isFunction)(e))return e()})}var Zn=()=>({appveyor:D(["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:D(["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:D(["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:D(["bamboo_buildNumber","bamboo_buildResultsUrl","bamboo_planRepository_repositoryUrl","bamboo_buildKey"]),bitbucket:D(["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:D(["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:D(["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:D(["BUILD_ID","BUILD_NAME","BUILD_JOB_NAME","BUILD_PIPELINE_NAME","BUILD_TEAM_NAME","ATC_EXTERNAL_URL"]),codeFresh:D(["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:D(["DRONE_BUILD_LINK","DRONE_BUILD_NUMBER","DRONE_PULL_REQUEST"]),githubActions:D(["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:D(["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:D(["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:D(["BUILD_ID","PROJECT_ID","REPO_NAME","BRANCH_NAME","TAG_NAME","COMMIT_SHA","SHORT_SHA"]),jenkins:D(["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:D(["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:D(["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:D(["BUILD_ID","CONTEXT","URL","DEPLOY_URL","DEPLOY_PRIME_URL","DEPLOY_ID"])}),Gp=t=>{let e=ts();return e?(0,R.chain)(t()).get(e).value():{}};function jp(){return(0,R.chain)(Zn()).omitBy(R.isNull).keys().value()}function $p(t){return t&&jp().includes(t)}function ts(){let t=kp();return Ce("detected CI provider name: %s",t),t||null}function Kp(){let t=Gp(Zn);return(0,R.mapValues)(t,e=>(0,R.isString)(e)?_r(e):e)}function rt(t){let e=Kp(),r=ts(),o=Hp(t,r);return Ce("detected CI provider: %s",r),Ce("detected CI params: %O",e),Ce("detected CI build ID: %o",o),{params:e,provider:r,ciBuildId:o}}function Hp(t,e){return t?{source:"user",value:t}:$p(e)?{source:"server",value:null}:{source:"random",value:`auto:${Rr()}`}}var es=l(require("archiver")),rs=l(require("fs-extra")),Lr=l(require("path")),os=l(require("unzipper"));var Jp=50*1024*1024;async function ns(t,e=Jp){return new Promise((r,o)=>{let n=(0,es.default)("zip",{zlib:{level:9}}),s=[],i=0;n.on("data",d=>{s.push(d),i+=d.length,i>e&&o(new Error(`Zip size exceeded the limit of ${e} bytes`))}),n.on("warning",d=>{d.code==="ENOENT"?E(d):o(d)}),n.on("error",d=>o(d)),n.on("end",()=>{let d=Buffer.concat(s);r(d)});let c=async d=>{let f=process.cwd(),u=Lr.default.normalize(d),I=Lr.default.relative(f,u),g=await rs.default.stat(d);g.isDirectory()?n.directory(d,I):n.file(d,{name:I,stats:g})};(async d=>{for(let f of d)await c(f);await n.finalize()})(t).catch(o)})}async function ss(t,e){return os.default.Open.buffer(t).then(r=>r.extract({path:e,concurrency:3}))}var is=require("lodash");var Vp={githubActions:[],gitlab:[],appveyor:["APPVEYOR_ACCOUNT_NAME","APPVEYOR_PROJECT_SLUG","APPVEYOR_BUILD_NUMBER"],azure:["SYSTEM_COLLECTIONID","BUILD_BUILDID"],awsCodeBuild:["CODEBUILD_BUILD_ID"],bamboo:["bamboo_buildKey","bamboo_buildNumber"],bitbucket:["BITBUCKET_PIPELINE_UUID"],buildkite:["BUILDKITE_BUILD_ID"],circle:["CIRCLE_WORKFLOW_WORKSPACE_ID"],concourse:["BUILD_ID"],codeFresh:["CF_BUILD_ID"],drone:["DRONE_BUILD_LINK"],goCD:["GO_PIPELINE_NAME","GO_PIPELINE_COUNTER"],googleCloud:["BUILD_ID"],jenkins:["JOB_NAME","BUILD_NUMBER"],semaphore:["SEMAPHORE_PIPELINE_ID"],travis:["TRAVIS_JOB_ID"],netlify:["BUILD_ID"]};function Yp({provider:t,params:e}){let r=t?Vp[t]:null;return!r||!e?!1:r.every(o=>!!e[(0,is.camelCase)(o)])}function Te(t,e){e||Yp(t)||se("No CI job detected: without --id the cache ID is random, so cache get does not find what cache set saved. Pass --id to save and restore the same cache.")}var ms=l(require("async-retry")),us=l(require("fs")),ls=require("stream"),Qt=require("axios");var as=l(require("axios")),cs=require("https-proxy-agent"),ps=l(require("proxy-from-env"));var Wp=p.extend("axios");function vr(t={}){let e=as.default.create(t);return e.interceptors.request.use(r=>{let o={...r},n=e.getUri(r),s=ps.default.getProxyForUrl(n);return s&&(Wp("Using HTTP proxy %s for %s",At(s),At(n)),o.proxy=!1,o.httpsAgent=qp(s)),o}),e}var ye=null;function qp(t){return ye||(ye=new cs.HttpsProxyAgent(t),ye)}var Xt=p.extend("upload"),Re=5;async function Br(t,e,r){return Xt("Uploading buffer %s",t.name,{buffer:Buffer.byteLength(t.buffer)}),Is(t.buffer,t.uploadUrl,e,r,t.headers,gs(Buffer.byteLength(t.buffer)))}var zp=256*1024,Qp=120*1e3;async function fs(t){return Xt("Uploading file %s",t.name,{bytes:t.sizeBytes}),Is(()=>t.sizeBytes>0?us.default.createReadStream(t.path,{end:t.sizeBytes-1}):ls.Readable.from([]),t.uploadUrl,t.contentType,void 0,{...t.headers??{"Content-Type":t.contentType},"Content-Length":String(t.sizeBytes)},gs(t.sizeBytes))}function gs(t){return Qp+Math.ceil(t/zp)*1e3}async function Xp(t,e,r,o,n,s){return vr().request({method:"put",url:e,timeout:s,data:typeof t=="function"?t():t,...typeof t=="function"&&{maxRedirects:0},onUploadProgress:o,headers:n??{"Content-Disposition":"inline","Content-Type":r}})}async function Mr(t,e){try{let r=await vr().get(t,{responseType:"arraybuffer",onDownloadProgress:e});return Buffer.isBuffer(r.data)?r.data:Buffer.from(r.data)}catch(r){throw(0,Qt.isAxiosError)(r)&&Xt("Failed to download %s: %s",At(t),r.message),r}}var Zp=["RequestTimeout","OperationAborted","SlowDown"];function hs(t){if(t)return t.replace(/[\u0000-\u001f\u007f-\u009f]/g,"").replace(/\b[a-z][a-z0-9+.-]*:\/\/\S+/gi,e=>At(e)).slice(0,200)}function Es(t){let e=(0,Qt.isAxiosError)(t)?t.response?.data:void 0,r=typeof e=="string"?e:"";return{code:r.match(/<Code>([^<]*)<\/Code>/)?.[1],message:hs(r.match(/<Message>([^<]*)<\/Message>/)?.[1])}}function td(t){let e=(0,Qt.isAxiosError)(t)?t.response?.status:void 0;if(e===void 0||e<400||e>=500||e===408||e===429)return!1;let{code:r}=Es(t);return!(r&&Zp.includes(r))}function ed(t){if(!(0,Qt.isAxiosError)(t)||!t.response)return t instanceof Error?t:new Error(String(t));let{code:e,message:r}=Es(t),o=[hs(e),r].filter(Boolean).join(": ");return new Error(`storage answered ${t.response.status}${o?` ${o}`:""}`)}async function Is(...t){try{await rd(t)}catch(e){throw ed(e)}}async function rd(t){await(0,ms.default)(async e=>{try{await Xp(...t)}catch(r){if(td(r)){e(r);return}throw r}},{retries:Re,onRetry:(e,r)=>{if(Xt("Upload failed %d out of %d attempts: %s",r,Re,e.message),r===Re){C(`Cannot upload after ${r} times: ${e.message}`);return}E(`Upload failed ${r} out of ${Re} attempts: ${e.message}`)}})}var Fr=t=>({total:e,loaded:r})=>{Xt("Uploading %s: %d / %d",t,ds(r),ds(e??0))};function ds(t){return t/1e3/1e3}var jr=l(require("lodash"));var ot=l(require("path")),Gr=l(require("globby"));var Cs=require("lodash");function kr({config:t,cacheId:e,orgId:r,path:o,ci:n,cacheKey:s,metaCacheKey:i}){let c={id:e,orgId:r,config:(0,Cs.omit)(t,"recordKey"),path:o,ci:n,createdAt:new Date().toISOString(),cacheKey:s,metaCacheKey:i};return Buffer.from(JSON.stringify(c))}function Ts(t,e){t instanceof Error?gt("%s. %s.",e,t.message):gt("%s. %s.",e,"Unknown error")}var ys=async t=>{let e=ot.default.resolve(t??"./test-results"),r=[ot.default.posix.join(e.replace(/\\/g,"/"),"**/.last-run.json"),ot.default.posix.join(e.replace(/\\/g,"/"),".last-run.json")];return Gr.sync(r)},Rs=async(t=[])=>{let e=od(t);return e.length===0?[]:Gr.sync(e.map(r=>r.replace(/\\/g,"/")))};function od(t){let e=process.cwd();return t.filter(r=>{let o=ot.default.relative(e,ot.default.resolve(r));return o===".."||o.startsWith(`..${ot.default.sep}`)||ot.default.isAbsolute(o)?(Ts(null,`Invalid path: "${r}". Path traversal detected. The path was skipped.`),!1):!0})}function _e(t){return t?t.path.some(e=>ot.default.basename(e)===".last-run.json"):!1}async function _s(t,e){switch(e.provider){case"githubActions":await xs(t,e);break;case"gitlab":await Os(t,e);break;case"circle":await As(t,e);break;default:break}}async function ws(t,e,r){switch(e.provider){case"githubActions":await xs(t,e,r);break;case"gitlab":await Os(t,e,r);break;case"circle":await As(t,e,r);break;default:break}}async function Os(t,e,r=null){let o=e.params,n=r?.ci.params,i=(n?bt(n.runAttempt,0):0)+1,c=bt(o.ciNodeIndex,1),m=bt(o.ciNodeTotal,1),d=_e(r),f=i>1&&d,u=f?"--last-failed":"",I="";m>1&&(I=f?"--shard=1/1":`--shard=${c}/${m}`);let g=[u,I].filter(Boolean).join(" ");await Et(t.presetOutput??zt,`EXTRA_PW_FLAGS="${g}"
23
23
  EXTRA_PWCP_FLAGS="${u}"
24
24
  RUN_ATTEMPT=${i}
25
- `)}async function _s(t,e,r=null){let{matrixIndex:o,matrixTotal:n}=t,s=e.params,i=bt(s.githubRunAttempt,1),c=_e(r),m=i>1&&c,d=m?"--last-failed":"",f="";n>1&&(f=m?"--shard=1/1":`--shard=${o}/${n}`);let u=[d,f].filter(Boolean).join(" "),I=t.presetOutput??zt;await Et(I,u),p('Dumped PW config: "%s" for GHA to %s',u,I)}async function ws(t,e,r=null){let o=e.params,n=r?.ci.params,s=n?.circleWorkflowId,i=n?.circleWorkflowWorkspaceId,c=bt(o.circleNodeIndex,0),m=bt(o.circleNodeTotal,1),d=i==o.circleWorkflowWorkspaceId&&s!==o.circleWorkflowId,f=_e(r),u=d&&f,I=u?"--last-failed":"",g="";m>1&&(g=u?"--shard=1/1":`--shard=${c+1}/${m}`);let S=[I,g].filter(Boolean).join(" "),J=t.presetOutput??zt;await Et(J,S),p('Dumped PW config: "%s" for Circle to %s',S,J)}var bt=(t,e)=>{let r=kr.default.toNumber(t);return kr.default.isNaN(r)?e:r};async function $r(){let t=dt();if(t.type!=="GET_COMMAND_CONFIG"||!t.values)throw new Error("Config is missing!");let{recordKey:e,id:r,preset:o,matrixIndex:n,matrixTotal:s,continue:i}=t.values,c=t.values.outputDir,m=rt();Te(m,r),o==="last-run"&&await Ts(t.values,m);let{cacheId:d,refMetaReadUrl:f}=await fn({recordKey:e,ci:m,id:r,config:{matrixIndex:n,matrixTotal:s}});try{let u=await ed(f),{readUrl:I}=await ln({recordKey:e,cacheKey:u.cacheKey}),g=await Zp({readUrl:I,outputDir:c});o==="last-run"&&await ys(t.values,m,u),T(x("- restoring cache to"),g),ie("Cache restored. Cache ID: %s",d)}catch(u){if((0,Os.isAxiosError)(u)&&(u.response?.status===403||u.response?.status===404)){let I=`Cache with ID "${d}" not found`;if(i){gt(I);return}throw new Error(I)}throw u}}async function Zp({readUrl:t,outputDir:e}){let r=await Br(t),o=td(e);return await rs(r,o),p("Cache downloaded",{readUrl:t,destination:o}),o}function td(t){let e=t??process.cwd();return Gr.default.isAbsolute(e)?e:Gr.default.resolve(process.cwd(),e)}async function ed(t){let e=await Br(t),r=JSON.parse(e.toString("utf-8"));return p("Meta file downloaded: %O",r),r}var As=require("lodash");async function Kr(){let t=dt();if(t.type!=="SET_COMMAND_CONFIG"||!t.values)throw new Error("Config is missing!");let{recordKey:e,id:r,preset:o,pwOutputDir:n,matrixIndex:s,matrixTotal:i,continue:c}=t.values,m=await Cs(t.values.path),d=t.values.path||[],f=rt();if(Te(f,r),o==="last-run"&&(d.push(n),m.push(...await Is(n))),m.length===0){let J=`No files available to upload: ${d.filter(Boolean).join(",")}`;if(!c)throw new Error(J);gt(J)}let u=await un({recordKey:e,ci:f,id:r,config:{matrixIndex:s,matrixTotal:i}});p("Cache upload url created",{result:u});let I=od(f),g=m.length>0?await es(m):null,S=[];g&&S.push(rd({archive:g,cacheId:u.cacheId,uploadUrl:u.uploadUrl}).then(()=>{nd(m),p("Cache archive uploaded",{uploadUrl:u.uploadUrl})})),S.push(xs({meta:Mr({cacheId:u.cacheId,config:t.values,ci:I,orgId:u.orgId,path:m}),cacheId:u.cacheId,uploadUrl:u.metaUploadUrl}).then(()=>p("Meta uploaded",{uploadUrl:u.metaUploadUrl})),xs({meta:Mr({cacheId:u.cacheId,config:t.values,ci:I,orgId:u.orgId,path:m,cacheKey:u.cacheKey,metaCacheKey:u.metaCacheKey}),cacheId:u.cacheId,uploadUrl:u.refMetaUploadUrl}).then(()=>p("Ref meta uploaded",{uploadUrl:u.refMetaUploadUrl}))),await Promise.all(S),ie("Cache uploaded. Cache ID: %s",u.cacheId)}async function rd({archive:t,cacheId:e,uploadUrl:r}){try{let o="application/zip";await Lr({buffer:t,contentType:o,name:e,uploadUrl:r},o,vr(e)),p("Cache archive uploaded",{cacheId:e})}catch(o){throw p("Failed to upload cache archive",o),o}}async function xs({meta:t,cacheId:e,uploadUrl:r}){try{let o=`${e}_meta`,n="application/json";await Lr({buffer:t,contentType:n,name:o,uploadUrl:r},n,vr(o)),p("Cache meta uploaded",{cacheId:e})}catch(o){throw p("Failed to upload cache meta",o),o}}function od(t){return t.ciBuildId.source==="server"||t.ciBuildId.source==="random"?(0,As.omit)(t,"ciBuildId"):t}function nd(t){T(`Cache upload paths:
25
+ `)}async function xs(t,e,r=null){let{matrixIndex:o,matrixTotal:n}=t,s=e.params,i=bt(s.githubRunAttempt,1),c=_e(r),m=i>1&&c,d=m?"--last-failed":"",f="";n>1&&(f=m?"--shard=1/1":`--shard=${o}/${n}`);let u=[d,f].filter(Boolean).join(" "),I=t.presetOutput??zt;await Et(I,u),p('Dumped PW config: "%s" for GHA to %s',u,I)}async function As(t,e,r=null){let o=e.params,n=r?.ci.params,s=n?.circleWorkflowId,i=n?.circleWorkflowWorkspaceId,c=bt(o.circleNodeIndex,0),m=bt(o.circleNodeTotal,1),d=i==o.circleWorkflowWorkspaceId&&s!==o.circleWorkflowId,f=_e(r),u=d&&f,I=u?"--last-failed":"",g="";m>1&&(g=u?"--shard=1/1":`--shard=${c+1}/${m}`);let S=[I,g].filter(Boolean).join(" "),V=t.presetOutput??zt;await Et(V,S),p('Dumped PW config: "%s" for Circle to %s',S,V)}var bt=(t,e)=>{let r=jr.default.toNumber(t);return jr.default.isNaN(r)?e:r};async function Kr(){let t=dt();if(t.type!=="GET_COMMAND_CONFIG"||!t.values)throw new Error("Config is missing!");let{recordKey:e,id:r,preset:o,matrixIndex:n,matrixTotal:s,continue:i}=t.values,c=t.values.outputDir,m=rt();Te(m,r),o==="last-run"&&await _s(t.values,m);let{cacheId:d,refMetaReadUrl:f}=await En({recordKey:e,ci:m,id:r,config:{matrixIndex:n,matrixTotal:s}});try{let u=await id(f),{readUrl:I}=await hn({recordKey:e,cacheKey:u.cacheKey}),g=await nd({readUrl:I,outputDir:c});o==="last-run"&&await ws(t.values,m,u),T(x("- restoring cache to"),g),ie("Cache restored. Cache ID: %s",d)}catch(u){if((0,Ss.isAxiosError)(u)&&(u.response?.status===403||u.response?.status===404)){let I=`Cache with ID "${d}" not found`;if(i){gt(I);return}throw new Error(I)}throw u}}async function nd({readUrl:t,outputDir:e}){let r=await Mr(t),o=sd(e);return await ss(r,o),p("Cache downloaded",{readUrl:t,destination:o}),o}function sd(t){let e=t??process.cwd();return $r.default.isAbsolute(e)?e:$r.default.resolve(process.cwd(),e)}async function id(t){let e=await Mr(t),r=JSON.parse(e.toString("utf-8"));return p("Meta file downloaded: %O",r),r}var Ds=require("lodash");async function Hr(){let t=dt();if(t.type!=="SET_COMMAND_CONFIG"||!t.values)throw new Error("Config is missing!");let{recordKey:e,id:r,preset:o,pwOutputDir:n,matrixIndex:s,matrixTotal:i,continue:c}=t.values,m=await Rs(t.values.path),d=t.values.path||[],f=rt();if(Te(f,r),o==="last-run"&&(d.push(n),m.push(...await ys(n))),m.length===0){let V=`No files available to upload: ${d.filter(Boolean).join(",")}`;if(!c)throw new Error(V);gt(V)}let u=await gn({recordKey:e,ci:f,id:r,config:{matrixIndex:s,matrixTotal:i}});p("Cache upload url created",{result:u});let I=cd(f),g=m.length>0?await ns(m):null,S=[];g&&S.push(ad({archive:g,cacheId:u.cacheId,uploadUrl:u.uploadUrl}).then(()=>{pd(m),p("Cache archive uploaded",{uploadUrl:u.uploadUrl})})),S.push(Us({meta:kr({cacheId:u.cacheId,config:t.values,ci:I,orgId:u.orgId,path:m}),cacheId:u.cacheId,uploadUrl:u.metaUploadUrl}).then(()=>p("Meta uploaded",{uploadUrl:u.metaUploadUrl})),Us({meta:kr({cacheId:u.cacheId,config:t.values,ci:I,orgId:u.orgId,path:m,cacheKey:u.cacheKey,metaCacheKey:u.metaCacheKey}),cacheId:u.cacheId,uploadUrl:u.refMetaUploadUrl}).then(()=>p("Ref meta uploaded",{uploadUrl:u.refMetaUploadUrl}))),await Promise.all(S),ie("Cache uploaded. Cache ID: %s",u.cacheId)}async function ad({archive:t,cacheId:e,uploadUrl:r}){try{let o="application/zip";await Br({buffer:t,contentType:o,name:e,uploadUrl:r},o,Fr(e)),p("Cache archive uploaded",{cacheId:e})}catch(o){throw p("Failed to upload cache archive",o),o}}async function Us({meta:t,cacheId:e,uploadUrl:r}){try{let o=`${e}_meta`,n="application/json";await Br({buffer:t,contentType:n,name:o,uploadUrl:r},n,Fr(o)),p("Cache meta uploaded",{cacheId:e})}catch(o){throw p("Failed to upload cache meta",o),o}}function cd(t){return t.ciBuildId.source==="server"||t.ciBuildId.source==="random"?(0,Ds.omit)(t,"ciBuildId"):t}function pd(t){T(`Cache upload paths:
26
26
  `+t.map(e=>`${x("- uploading")} ${e}`).join(`
27
- `))}var{recordKey:sd,projectId:id,ciBuildId:ad,debug:cd}=_,Q={recordKey:sd,projectId:id,ciBuildId:ad,runId:{name:"Run ID",env:"CURRENTS_RUN_ID",cli:"--run-id"},debug:cd};var pd=p.extend("config"),dd=["recordKey","projectId"];function md(t){if(!(t.runId||t.ciBuildId))throw C(`${me(Q,"runId")} or ${me(Q,"ciBuildId")} is required: pass ${x(de(Q,"runId"))} or ${x(de(Q,"ciBuildId"))}, or set ${x(N(Q,"runId"))} or ${x(N(Q,"ciBuildId"))}`),new W("Missing required config variable")}var Hr=null;function Ss(t){Hr=U(Q,dd,t,md),pd("Resolved config: %o",h(Hr))}function we(){return Hr}async function jr(){let t=we();if(!t)throw new Error("Config is missing!");let e=t.runId?`runId: ${t.runId}`:`ciBuildId: ${t.ciBuildId}`;try{let r=await gn({recordKey:t.recordKey,projectId:t.projectId,ciBuildId:t.ciBuildId,runId:t.runId});return r.data.runId?T('Run "%s" (%s) is cancelled',r.data.runId,e):T('No run to cancel (%s) in project "%s"',e,t.projectId),r}catch(r){throw p("Failed to cancel the run"),r}}var Us=require("@currents/commit-info"),Ds=require("lodash");var ud=p.extend("git"),ld=async()=>{let t=await(0,Us.commitInfo)();return ud("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}},Oe=(0,Ds.memoize)(ld);var Ps=l(require("getos")),bs=require("lodash"),H=require("os"),Ns=require("util"),fd=async()=>{if((0,H.platform)()==="linux")try{let t=await(0,Ns.promisify)(Ps.default)();return"dist"in t&&"release"in t?[t.dist,t.release].join(" - "):(0,H.release)()}catch{return(0,H.release)()}return(0,H.release)()},gd=async()=>{let t=await fd();return{osName:(0,H.platform)(),osVersion:t,osCpus:[],osMemory:{free:(0,H.freemem)(),total:(0,H.totalmem)()}}},Ls=(0,bs.memoize)(gd);var Ti=l(require("axios")),Zr=l(require("fs-extra")),Ne=l(require("path")),yi=l(require("semver"));var{debug:hd,ciBuildId:Ed,recordKey:Id,projectId:Cd,machineId:Td}=_,nt={debug:hd,ciBuildId:Ed,recordKey:Id,projectId:Cd,machineId:Td,tag:{..._.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 yd=p.extend("config"),Rd=["projectId","recordKey"],Vr=null;function Bs(t){Vr=U(nt,Rd,t),yd("Resolved Currents config: %o",h(Vr))}function xe(){return Vr}function vs(t){return{ciBuildId:t.ciBuildId,projectId:t.projectId,recordKey:t.key,tag:t.tag,removeTitleTags:t.removeTitleTags,disableTitleTags:t.disableTitleTags,debug:t.debug,machineId:t.machineId,reportDir:t.reportDir}}var qr=l(require("fs-extra")),st=require("path");var Ms=l(require("path")),Jr={".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"}},Yr=t=>Jr[Ms.default.extname(t).toLowerCase()];var Fs=l(require("fs-extra")),ks=require("path"),Wr=p.extend("detox"),_d="detox.json";function Gs(t){return[...t].sort((e,r)=>(e.session??0)-(r.session??0)||e.invocations-r.invocations)}async function $s(t){let e=(0,ks.join)(t,_d);try{let r=await Fs.default.readJson(e);if(typeof r?.artifactsRootDir!="string"||!Array.isArray(r?.tests)){Wr("Unexpected Detox manifest contents at %s",e);return}return Wr("Detox manifest: %o",r),r}catch{Wr("No Detox manifest at %s",e);return}}var Ae=require("path"),wd=p.extend("detox"),Ks=255,Od=/[/\\?<>:*|"$\u0000-\u001f]/g,Hs=4;function js(t){return xd(t)??Ad(t)}function xd({rootDir:t,fullName:e,status:r,invocations:o}){try{let n=require.resolve("detox/src/artifacts/utils/ArtifactPathBuilder",{paths:[process.cwd()]}),s=require(n),i=new s({rootDir:t});return(0,Ae.dirname)(i.buildPathForTestArtifact("test.mp4",{fullName:e,status:r,invocations:o}))}catch(n){wd("Detox path builder is not available: %o",n);return}}function Ad({rootDir:t,fullName:e,status:r,invocations:o}){let n=Ud(r),s=o>1?` (${o})`:"",i=e.slice(-Ks+n.length+s.length),c=`${n}${i}${s}`.replace(Od,"_");return(0,Ae.join)(t,Sd(c,Ks))}function Sd(t,e){let r=Buffer.from(t,"utf8");return r.length<=e?t:r.subarray(0,e).toString("utf8").replace(/\uFFFD$/,"")}function Ud(t){switch(t){case"passed":return"\u2713 ";case"failed":return"\u2717 ";default:return""}}var Js=l(require("fs-extra")),Ys=require("path"),Vs=p.extend("detox"),Se="detox.trace.json",Dd="ws-client-invocation";async function Ws(t){let e=(0,Ys.join)(t,Se),r=new Map,o;try{o=await Js.default.readJson(e)}catch{return Vs("No Detox trace at %s",e),r}if(!Array.isArray(o))return Vs("Unexpected Detox trace contents at %s",e),r;let n=Pd(o);return Nd(o).forEach(({pid:i,ts:c,step:m})=>{n.filter(f=>f.pid===i&&c>=f.startTs&&c<=f.endTs).sort((f,u)=>f.startTs-u.startTs).pop()?.steps.push(m)}),n.forEach(({fullName:i,invocations:c,steps:m})=>{let d=r.get(i)??[];d.push({fullName:i,invocations:c,steps:m.sort((f,u)=>+new Date(f.startTime)-+new Date(u.startTime))}),r.set(i,d)}),r}function Pd(t){let e=new Map,r=[];t.forEach(n=>{let s=`${n.pid}:${n.tid}`,i=e.get(s)??[];if(e.set(s,i),n.ph==="B"){i.push(bd(n));return}if(n.ph==="E"){let c=i.pop();c&&r.push({...c,endTs:Number(n.ts)})}});let o=[...e.values()].flatMap(n=>n.filter(s=>s!==void 0));return[...r,...o]}function bd(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 Nd(t){let e=new Map,r=[];return t.forEach(o=>{if(!o.cat?.includes(Dd))return;let n=`${o.pid}:${o.tid}`,s=e.get(n)??[];if(o.ph==="B"){s.push({name:o.name??"action",cat:o.cat,ts:Number(o.ts)}),e.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 Zt=p.extend("detox"),qs="artifacts",Ld=[".mp4",".png",".jpg",".log",".txt",".json",".viewhierarchy"],Bd=t=>{let e=(0,st.extname)(t);return Ld.includes(e)?Jr[e]:void 0};async function zs({instances:t,reportDir:e,manifest:r}){let o=Md(r),n=await Ws(r.artifactsRootDir),s=await It((0,st.join)(e,qs)),i={artifacts:0,steps:0};for(let c of t)for(let m of c.results.tests){let d=o.get(m.testId);if(!d){Zt("No Detox manifest entry for %s",m.testId);continue}await Fd({test:m,manifestTest:d,rootDir:r.artifactsRootDir,artifactsDir:s,traceSlices:n.get(d.fullName)??[],result:i})}return i.artifacts+=await vd({instances:t,rootDir:r.artifactsRootDir,artifactsDir:s}),i}async function vd({instances:t,rootDir:e,artifactsDir:r}){if(!await qr.default.pathExists((0,st.join)(e,Se)))return 0;let[o]=await Qs(e,[Se],r),n=t.map(s=>s.results.tests[0]).filter(s=>s!==void 0);return n.forEach(s=>{s.artifacts=[...s.artifacts??[],o]}),n.length}function Md(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 o=e.get(r.fullName)?.length===1;return o||Zt("Ambiguous Detox test name, skipping: %s",r.fullName),o}).map(r=>[r.testId,r]))}async function Fd({test:t,manifestTest:e,rootDir:r,artifactsDir:o,traceSlices:n,result:s}){let i=[...t.attempts].sort((d,f)=>d.attempt-f.attempt),c=Gs(e.attempts),m=1;for(let[d,f]of c.entries()){let u=i[d];if(!u){Zt("No reported attempt %d of %s",d,e.fullName);continue}let I=await kd({fullName:e.fullName,status:f.status,rootDir:r,artifactsDir:o,fromInvocation:m});I&&(m=I.invocation+1,u.artifacts=[...u.artifacts??[],...I.artifacts],s.artifacts+=I.artifacts.length);let g=$d(n,d,I?.invocation);g.length&&(u.steps=[...u.steps??[],...g],s.steps+=g.length)}}async function kd({fullName:t,status:e,rootDir:r,artifactsDir:o,fromInvocation:n}){for(let s=n;s<n+Hs;s++){let i=js({rootDir:r,fullName:t,status:e,invocations:s}),c=await Gd(i);if(c)return{invocation:s,artifacts:await Qs(i,c,o)}}Zt("No Detox artifacts for %s [%s]",t,e)}async function Gd(t){try{return(await qr.default.readdir(t)).sort()}catch{return}}async function Qs(t,e,r){let o=[];for(let n of e){let s=Bd(n);if(!s){Zt("Skipping unsupported Detox artifact %s",n);continue}let i=(0,st.join)(t,n),c=`${et(i)}${(0,st.extname)(n)}`;await ce(i,(0,st.join)(r,c)),o.push({...s,path:(0,st.join)(qs,c),name:n})}return o}function $d(t,e,r){return((r===void 0?void 0:t.find(s=>s.invocations===r))??[...t].sort((s,i)=>s.invocations-i.invocations)[e])?.steps??[]}var mt=class{constructor(e){this.config=e}async getFullTestSuite(){return[]}};var ci=l(require("fs-extra")),pi=require("jest-cli"),di=l(require("tmp"));var ii=require("lodash");function Xs(t){let e=[];for(let[r,o]of Object.entries(t))r==="_"||r==="$0"||r.includes("-")||(typeof o=="boolean"?o&&e.push(`--${r}`):Array.isArray(o)?o.forEach(n=>{e.push(`--${r}=${n}`)}):e.push(`--${r}=${o}`));return e.join(" ")}var Zs=require("lodash"),Kd=["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 ti(t){return(0,Zs.omit)(t,...Kd)}var oi=l(require("fs")),ni=require("jest-config"),zr=require("lodash"),Qr=l(require("path"));function Ue(t,e){return(...r)=>new Promise((o,n)=>{let s=0,i=()=>{s++;try{let c=t(...r);o(c)}catch(c){if(s>=e.length)n(c);else{let m=e[s-1];setTimeout(i,m)}}};i()})}var ei=l(require("fs-extra")),Hd=l(require("path"));async function De(t){let e=await ei.default.pathExists(t);if(!e)throw new Error("File does not exist");return e}var ri=p.extend("jest-discovery");async function si(t){try{let{config:e,configPath:r}=await(0,ni.readInitialOptions)(t),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,zr.omit)(e,o);if(s.projects&&(s.projects=s.projects.map(m=>typeof m!="string"?(0,zr.omit)(m,n):m)),s.rootDir&&Object.keys(s).length===1)return null;let i=Qr.default.resolve(r?Qr.default.dirname(r):process.cwd(),`.jest-scanner-${new Date().getTime()}.config.cjs`),c=`module.exports=${JSON.stringify(s,null,2)}`;return ri("configFileContent: %O",c),oi.default.writeFileSync(i,c),await Ue(De,[200,200,200,200,200,1e3])(i),i}catch(e){return C("Failed to recreate the config file"),ri("error %o",e),null}}async function ai(t){let e="!!##ThisPatternWillNotMatchAnyTestName##!!",r=t.options,o=ti(r),n=Xs(o),s=r.config,i=await si(s);return{cliArgs:[n,"--testNamePattern",e,"--reporters","@currents/cmd/discovery/jest","--shard=1/1",i?`--config=${i}`:"",...t.args].filter(m=>!(0,ii.isEmpty)(m)),configFilePath:i}}var jd=p.extend("jest-discovery");async function mi(t,e){console.time(x("@currents/jest:fullTestSuite-ready"));let{cliArgs:r,configFilePath:o}=await ai(e);try{let n=di.default.fileSync({postfix:".json"});return jd("running scanner: %o",r),process.env.CURRENTS_DISCOVERY_PATH=n.name,await(0,pi.run)(r.concat(["--openHandlesTimeout=0"])),await Ue(De,Array.from({length:300},()=>100))(n.name),console.timeEnd(x("@currents/jest:fullTestSuite-ready")),await ht(n.name)}catch(n){return C("Failed to obtain the jest full test suite:",n),[]}finally{o&&ci.default.unlinkSync(o)}}var Pe=class extends mt{constructor(e){super(e)}async getFullTestSuite(){return mi(this.config.frameworkConfig,this.config.cliArgs)}};var li=l(require("fs-extra"));var ui=l(require("path"));function Tt(t){return ui.default.join(t,"fullTestSuite.json")}var Vd=p.extend("junit-discovery");async function fi(t){console.time(x("@currents/junit:fullTestSuite-ready"));try{Vd("running scanner: %o",t);let e=Tt(t);process.env.CURRENTS_DISCOVERY_PATH=e;let r=li.default.readFileSync(e,"utf-8");return JSON.parse(r)}catch(e){return C("Failed to obtain the junit full test suite:",e),[]}}var be=class extends mt{constructor(e,r){super(e),this.reportDir=r}async getFullTestSuite(){return fi(this.reportDir)}};function gi(t,e){switch(t.framework){case"jest":return new Pe(t);case"junit":return new be(t,e);default:return new mt(t)}}var ut=l(require("fs-extra")),it=l(require("path"));async function hi(t){let e=await Jd(t?.reportDir);return{reportDir:e,configFilePath:t?.configFilePath??it.default.join(e,"config.json")}}async function Jd(t){if(t){if(!await ut.default.pathExists(t))throw new Error(`No reports found: the folder "${t}" does not exist.`);return t}let e=(0,it.join)(process.cwd(),".currents"),r=await ut.default.pathExists(e)?await Yd(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 Yd(t){let e=await ut.default.readdir(t),r=null;for(let o of e){let n=it.default.join(t,o),s=await ut.default.stat(n);s.isDirectory()&&(!r||s.birthtime>r.birthtime)&&(r={name:o,birthtime:s.birthtime})}return r?(0,it.resolve)(t,r.name):null}async function Xr(t){try{return await ut.default.pathExists(t)}catch{return C("Error checking if path exists:",C),!1}}async function Ei(t){let e=it.default.join(t,"instances");return Wd(e)}async function Wd(t){let e=await ut.default.readdir(t),r=[];for(let o of e){let n=it.default.join(t,o);(await ut.default.stat(n)).isFile()&&r.push(n)}return r}var qd=t=>Buffer.byteLength(JSON.stringify(t),"utf8"),Ii=(t,e=1048576)=>{let r=[],o=[],n=0;for(let s of t){let i=qd(s);n+i>e&&(r.push(o),o=[],n=0),o.push(s),n+=i}return o.length>0&&r.push(o),r};var zd=3e4;async function to(){let t=xe();if(!t)throw new Error("Currents config is missing!");let e=await hi(t);Lo(Xd(e.reportDir)),p("Reporter options: %o",e),T("Report directory: %s",e.reportDir);let r=await ht(e.configFilePath);p("Report config: %o",r);let o=await Ei(e.reportDir);p("Found %d instance results in the reportDir: %s",o.length,e.reportDir);let n=Qd(e.reportDir),s=await Xr(n),i=Tt(e.reportDir),c=null;if(s){let M=await ht(n);E("Marker file detected. The report was already uploaded: %o",{runUrl:M.response.runUrl,isoDate:M.isoDate})}if(await Xr(i)&&(c=await ht(i),p("Full test suite file detected: %s",i)),c)p("The discovery stage was skipped");else{if(c=await gi(r,e.reportDir).getFullTestSuite(),Zd(c))throw new Error("Failed to discover the full test suite!");await Et(i,JSON.stringify(c))}let d=c.length===1?c[0].name:null,f={currents:t},u={type:r.framework,version:r.frameworkVersion,clientVersion:xt,frameworkConfig:{originFramework:r.frameworkConfig?.originFramework,originFrameworkVersion:r.frameworkConfig?.originFrameworkVersion}},I=pe.userFacingNanoid(),g=rt(t.ciBuildId),S={};for await(let M of o){let $=await ht(M);S[$.groupId]||(S[$.groupId]=[]),S[$.groupId].push($)}let J=await $s(e.reportDir);if(J){let M=await zs({instances:Object.values(S).flat(),reportDir:e.reportDir,manifest:J});T("[currents] Attached %d Detox artifacts and %d steps",M.artifacts,M.steps)}let Ot=new Map;Object.values(S).forEach(M=>{M.forEach($=>{$.artifacts?.forEach(K=>{K&&Ot.set(K.path,K.contentType)}),$.results.tests.forEach(K=>{K.artifacts?.forEach(k=>{k&&Ot.set(k.path,k.contentType)}),K.attempts.forEach(k=>{k.artifacts?.forEach(ft=>{ft&&Ot.set(ft.path,ft.contentType)})})})})});for await(let M of Object.keys(S)){let $=S[M],K=M;d&&(p("Default group found: %s, overwriting the group in the results",d),K=d,$=$.map(k=>({...k,groupId:d})));try{let k=Ii($),ft=await Ci({ci:g,group:K,instances:[],fullTestSuite:c,config:f,machineId:I,framework:u});for(let mr=0;mr<k.length;mr++){let ur=await Ci({ci:g,group:K,instances:k[mr],fullTestSuite:[],config:f,machineId:I,framework:u});ur.artifactUploadUrls&&ur.artifactUploadUrls.length>0&&await tm(ur.artifactUploadUrls,e.reportDir,Ot)}p("Api response: %o",ft),T("[%s] Run created: %s",K,ft.runUrl);let Bc={response:ft,isoDate:new Date().toISOString()};await Et(n,JSON.stringify(Bc)),p("Marker file %s: %s",s?"overwritten":"created",n)}catch(k){throw p("Failed to upload the results to the dashboard"),k}}}async function Ci({ci:t,group:e,instances:r,fullTestSuite:o,config:n,machineId:s,framework:i}){let c=await Oe(),m=await Ls(),d={browserName:"node",browserVersion:yi.default.coerce(process.version)?.version},{currents:f}=n,I={platform:{...d,...m},ci:t,commit:c,group:e,fullTestSuite:o,config:n,projectId:f.projectId,recordKey:f.recordKey,ciBuildId:t.ciBuildId.value??void 0,tags:f.tag??[],machineId:f.machineId??s,framework:i,instances:r,previousCiBuildId:process.env.CURRENTS_PREVIOUS_CI_BUILD_ID};return p("Creating run: %o",h(I)),Cn(I)}function Qd(t){return Ne.default.join(t,"upload.marker.json")}function Xd(t){return Ne.default.join(t,`.debug-${new Date().toISOString()}.log`)}function Zd(t){return t.length===0||t.some(e=>e.tests.length===0)}async function tm(t,e,r){p("Uploading %d artifacts",t.length),await Promise.all(t.map(o=>{let n=Ne.default.join(e,o.path),s=r.get(o.path)||"application/octet-stream";return em(n,s,o.uploadUrl)}))}var em=async(t,e,r)=>{try{if(!await Zr.default.pathExists(t)){E("Artifact file not found: %s",t);return}let o=await Zr.default.readFile(t);await Ti.default.put(r,o,{headers:{"Content-Type":e},timeout:zd})}catch(o){p("Failed to upload artifact %s: %o",t,o)}};var rm=p.extend("cli");async function Ri(t,e){await w(async r=>{r.output||Pt(),e.getOptionValueSource("ciBuildId")==="env"&&(r.branch||r.tag)&&(r={...r,ciBuildId:void 0}),Yo(r);let n=le();rm("Config: %o",h(n)),await Sr()},t)}var X=require("@commander-js/extra-typings");var Oi=require("axios"),xi=l(require("fs-extra"));var om=p.extend("api");function nm(t){if(/^[a-z][a-z0-9+.-]*:\/\//i.test(t))throw new Error(`Pass a path such as /v1/runs/<run-id>, not a URL. The CLI sends requests to ${Jt()}`);let e=t.replace(/^\/+/,""),r=o=>/^(\.|%2e){1,2}$/i.test(o);if(e.split(/[?#]/)[0].split("/").some(r))throw new Error(`The path cannot hold "." or ".." segments: ${t}`);return/^v1(\/|\?|$)/.test(e)?e:`v1/${e}`}function sm(t){let e=Object.create(null);for(let[r,o]of t)if(r.endsWith("[]")){let n=r.slice(0,-2);e[n]=[...Array.isArray(e[n])?e[n]:[],o]}else e[r]=o;return e}function im(t){let e=new URLSearchParams;for(let[r,o]of t)e.append(r,String(o));return e}async function am(t){let e=t==="-"?await new Promise((r,o)=>{let n="";process.stdin.setEncoding("utf8"),process.stdin.on("data",s=>n+=s),process.stdin.on("end",()=>r(n)),process.stdin.on("error",o)}):await xi.default.readFile(t,"utf8");try{return JSON.parse(e)}catch(r){throw new Error(`--input ${t} is not valid JSON: ${r.message}`)}}async function cm(t,e){let r=[...e.field??[],...e.rawField??[]],o=e.input!==void 0,n=e.method??(o||r.length>0?"POST":"GET"),s=o||n==="GET"||n==="HEAD";return{method:n,url:nm(t),params:s&&r.length>0?im(r):void 0,data:o?JSON.stringify(await am(e.input)):!s&&r.length>0?JSON.stringify(sm(r)):void 0,headers:Object.fromEntries(e.header??[])}}function _i(t){let e=Object.entries(t.headers).map(([r,o])=>`${r}: ${Array.isArray(o)?o.join(", "):o}`);return[`HTTP/1.1 ${t.status} ${t.statusText}`,...e,"",""].join(`
28
- `)}function wi(t,e){let r=t.data??"",o=String(t.headers["content-type"]??"").toLowerCase().includes("json");if(!e||!o||!r)return r;try{return JSON.stringify(JSON.parse(r),null,2)+`
29
- `}catch{return r}}async function Ai(t,e){let{apiKey:r}=U(_,["apiKey"],e),o=s=>s?.map(([i])=>i);om("Options: %o",h({...e,field:o(e.field),rawField:o(e.rawField),header:o(e.header)}));let n=await cm(t,e);try{let s=await An(r,n);e.include&&process.stdout.write(_i(s)),process.stdout.write(wi(s,!!process.stdout.isTTY))}catch(s){if(!(0,Oi.isAxiosError)(s))throw s;let i=s.response;if(!i)throw new Error(`Could not reach the REST API at ${Jt()}: ${s.message}`);e.include&&process.stderr.write(_i(i));let c=wi(i,!!process.stderr.isTTY);throw c&&process.stderr.write(c.endsWith(`
27
+ `))}var{recordKey:dd,projectId:md,ciBuildId:ud,debug:ld}=_,Q={recordKey:dd,projectId:md,ciBuildId:ud,runId:{name:"Run ID",env:"CURRENTS_RUN_ID",cli:"--run-id"},debug:ld};var fd=p.extend("config"),gd=["recordKey","projectId"];function hd(t){if(!(t.runId||t.ciBuildId))throw C(`${me(Q,"runId")} or ${me(Q,"ciBuildId")} is required: pass ${x(de(Q,"runId"))} or ${x(de(Q,"ciBuildId"))}, or set ${x(N(Q,"runId"))} or ${x(N(Q,"ciBuildId"))}`),new W("Missing required config variable")}var Jr=null;function Ps(t){Jr=U(Q,gd,t,hd),fd("Resolved config: %o",h(Jr))}function we(){return Jr}async function Vr(){let t=we();if(!t)throw new Error("Config is missing!");let e=t.runId?`runId: ${t.runId}`:`ciBuildId: ${t.ciBuildId}`;try{let r=await In({recordKey:t.recordKey,projectId:t.projectId,ciBuildId:t.ciBuildId,runId:t.runId});return r.data.runId?T('Run "%s" (%s) is cancelled',r.data.runId,e):T('No run to cancel (%s) in project "%s"',e,t.projectId),r}catch(r){throw p("Failed to cancel the run"),r}}var bs=require("@currents/commit-info"),Ns=require("lodash");var Ed=p.extend("git"),Id=async()=>{let t=await(0,bs.commitInfo)();return Ed("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}},Oe=(0,Ns.memoize)(Id);var Ls=l(require("getos")),vs=require("lodash"),K=require("os"),Bs=require("util"),Cd=async()=>{if((0,K.platform)()==="linux")try{let t=await(0,Bs.promisify)(Ls.default)();return"dist"in t&&"release"in t?[t.dist,t.release].join(" - "):(0,K.release)()}catch{return(0,K.release)()}return(0,K.release)()},Td=async()=>{let t=await Cd();return{osName:(0,K.platform)(),osVersion:t,osCpus:[],osMemory:{free:(0,K.freemem)(),total:(0,K.totalmem)()}}},Ms=(0,vs.memoize)(Td);var Oi=l(require("axios")),ro=l(require("fs-extra")),ve=l(require("path")),xi=l(require("semver"));var{debug:yd,ciBuildId:Rd,recordKey:_d,projectId:wd,machineId:Od}=_,nt={debug:yd,ciBuildId:Rd,recordKey:_d,projectId:wd,machineId:Od,tag:{..._.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 xd=p.extend("config"),Ad=["projectId","recordKey"],Yr=null;function Fs(t){Yr=U(nt,Ad,t),xd("Resolved Currents config: %o",h(Yr))}function xe(){return Yr}function ks(t){return{ciBuildId:t.ciBuildId,projectId:t.projectId,recordKey:t.key,tag:t.tag,removeTitleTags:t.removeTitleTags,disableTitleTags:t.disableTitleTags,debug:t.debug,machineId:t.machineId,reportDir:t.reportDir}}var Qr=l(require("fs-extra")),st=require("path");var Gs=l(require("path")),Wr={".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"}},qr=t=>Wr[Gs.default.extname(t).toLowerCase()];var js=l(require("fs-extra")),$s=require("path"),zr=p.extend("detox"),Sd="detox.json";function Ks(t){return[...t].sort((e,r)=>(e.session??0)-(r.session??0)||e.invocations-r.invocations)}async function Hs(t){let e=(0,$s.join)(t,Sd);try{let r=await js.default.readJson(e);if(typeof r?.artifactsRootDir!="string"||!Array.isArray(r?.tests)){zr("Unexpected Detox manifest contents at %s",e);return}return zr("Detox manifest: %o",r),r}catch{zr("No Detox manifest at %s",e);return}}var Ae=require("path"),Ud=p.extend("detox"),Js=255,Dd=/[/\\?<>:*|"$\u0000-\u001f]/g,Vs=4;function Ys(t){return Pd(t)??bd(t)}function Pd({rootDir:t,fullName:e,status:r,invocations:o}){try{let n=require.resolve("detox/src/artifacts/utils/ArtifactPathBuilder",{paths:[process.cwd()]}),s=require(n),i=new s({rootDir:t});return(0,Ae.dirname)(i.buildPathForTestArtifact("test.mp4",{fullName:e,status:r,invocations:o}))}catch(n){Ud("Detox path builder is not available: %o",n);return}}function bd({rootDir:t,fullName:e,status:r,invocations:o}){let n=Ld(r),s=o>1?` (${o})`:"",i=e.slice(-Js+n.length+s.length),c=`${n}${i}${s}`.replace(Dd,"_");return(0,Ae.join)(t,Nd(c,Js))}function Nd(t,e){let r=Buffer.from(t,"utf8");return r.length<=e?t:r.subarray(0,e).toString("utf8").replace(/\uFFFD$/,"")}function Ld(t){switch(t){case"passed":return"\u2713 ";case"failed":return"\u2717 ";default:return""}}var qs=l(require("fs-extra")),zs=require("path"),Ws=p.extend("detox"),Se="detox.trace.json",vd="ws-client-invocation";async function Qs(t){let e=(0,zs.join)(t,Se),r=new Map,o;try{o=await qs.default.readJson(e)}catch{return Ws("No Detox trace at %s",e),r}if(!Array.isArray(o))return Ws("Unexpected Detox trace contents at %s",e),r;let n=Bd(o);return Fd(o).forEach(({pid:i,ts:c,step:m})=>{n.filter(f=>f.pid===i&&c>=f.startTs&&c<=f.endTs).sort((f,u)=>f.startTs-u.startTs).pop()?.steps.push(m)}),n.forEach(({fullName:i,invocations:c,steps:m})=>{let d=r.get(i)??[];d.push({fullName:i,invocations:c,steps:m.sort((f,u)=>+new Date(f.startTime)-+new Date(u.startTime))}),r.set(i,d)}),r}function Bd(t){let e=new Map,r=[];t.forEach(n=>{let s=`${n.pid}:${n.tid}`,i=e.get(s)??[];if(e.set(s,i),n.ph==="B"){i.push(Md(n));return}if(n.ph==="E"){let c=i.pop();c&&r.push({...c,endTs:Number(n.ts)})}});let o=[...e.values()].flatMap(n=>n.filter(s=>s!==void 0));return[...r,...o]}function Md(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 Fd(t){let e=new Map,r=[];return t.forEach(o=>{if(!o.cat?.includes(vd))return;let n=`${o.pid}:${o.tid}`,s=e.get(n)??[];if(o.ph==="B"){s.push({name:o.name??"action",cat:o.cat,ts:Number(o.ts)}),e.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 Zt=p.extend("detox"),Xs="artifacts",kd=[".mp4",".png",".jpg",".log",".txt",".json",".viewhierarchy"],Gd=t=>{let e=(0,st.extname)(t);return kd.includes(e)?Wr[e]:void 0};async function Zs({instances:t,reportDir:e,manifest:r}){let o=$d(r),n=await Qs(r.artifactsRootDir),s=await It((0,st.join)(e,Xs)),i={artifacts:0,steps:0};for(let c of t)for(let m of c.results.tests){let d=o.get(m.testId);if(!d){Zt("No Detox manifest entry for %s",m.testId);continue}await Kd({test:m,manifestTest:d,rootDir:r.artifactsRootDir,artifactsDir:s,traceSlices:n.get(d.fullName)??[],result:i})}return i.artifacts+=await jd({instances:t,rootDir:r.artifactsRootDir,artifactsDir:s}),i}async function jd({instances:t,rootDir:e,artifactsDir:r}){if(!await Qr.default.pathExists((0,st.join)(e,Se)))return 0;let[o]=await ti(e,[Se],r),n=t.map(s=>s.results.tests[0]).filter(s=>s!==void 0);return n.forEach(s=>{s.artifacts=[...s.artifacts??[],o]}),n.length}function $d(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 o=e.get(r.fullName)?.length===1;return o||Zt("Ambiguous Detox test name, skipping: %s",r.fullName),o}).map(r=>[r.testId,r]))}async function Kd({test:t,manifestTest:e,rootDir:r,artifactsDir:o,traceSlices:n,result:s}){let i=[...t.attempts].sort((d,f)=>d.attempt-f.attempt),c=Ks(e.attempts),m=1;for(let[d,f]of c.entries()){let u=i[d];if(!u){Zt("No reported attempt %d of %s",d,e.fullName);continue}let I=await Hd({fullName:e.fullName,status:f.status,rootDir:r,artifactsDir:o,fromInvocation:m});I&&(m=I.invocation+1,u.artifacts=[...u.artifacts??[],...I.artifacts],s.artifacts+=I.artifacts.length);let g=Vd(n,d,I?.invocation);g.length&&(u.steps=[...u.steps??[],...g],s.steps+=g.length)}}async function Hd({fullName:t,status:e,rootDir:r,artifactsDir:o,fromInvocation:n}){for(let s=n;s<n+Vs;s++){let i=Ys({rootDir:r,fullName:t,status:e,invocations:s}),c=await Jd(i);if(c)return{invocation:s,artifacts:await ti(i,c,o)}}Zt("No Detox artifacts for %s [%s]",t,e)}async function Jd(t){try{return(await Qr.default.readdir(t)).sort()}catch{return}}async function ti(t,e,r){let o=[];for(let n of e){let s=Gd(n);if(!s){Zt("Skipping unsupported Detox artifact %s",n);continue}let i=(0,st.join)(t,n),c=`${et(i)}${(0,st.extname)(n)}`;await ce(i,(0,st.join)(r,c)),o.push({...s,path:(0,st.join)(Xs,c),name:n})}return o}function Vd(t,e,r){return((r===void 0?void 0:t.find(s=>s.invocations===r))??[...t].sort((s,i)=>s.invocations-i.invocations)[e])?.steps??[]}var mt=class{constructor(e){this.config=e}async getFullTestSuite(){return[]}};var fi=l(require("fs-extra")),gi=l(require("tmp"));var ui=require("lodash");function ei(t){let e=[];for(let[r,o]of Object.entries(t))r==="_"||r==="$0"||r.includes("-")||(typeof o=="boolean"?o&&e.push(`--${r}`):Array.isArray(o)?o.forEach(n=>{e.push(`--${r}=${n}`)}):e.push(`--${r}=${o}`));return e.join(" ")}var ri=require("lodash"),Yd=["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 oi(t){return(0,ri.omit)(t,...Yd)}var di=l(require("fs")),Zr=require("lodash"),to=l(require("path"));var Xr=l(require("fs")),Ue=require("module"),De=l(require("path")),ni=l(require("semver")),Wd=">=29.5.0";function qd(){let t=(0,Ue.createRequire)(De.default.join(process.cwd(),"package.json"));if(zd(t)==="jest-cli")return t.resolve("jest-cli");try{return(0,Ue.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 zd(t){for(let e of t.resolve.paths("jest")??[]){if(Xr.default.existsSync(De.default.join(e,"jest","package.json")))return"jest";if(Xr.default.existsSync(De.default.join(e,"jest-cli","package.json")))return"jest-cli"}return null}function si(){let t=(0,Ue.createRequire)(qd()),{version:e}=t("jest-cli/package.json");if(!ni.default.satisfies(e,Wd,{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 ii(){return si()("jest-cli")}function ai(){return si()("jest-config")}function Pe(t,e){return(...r)=>new Promise((o,n)=>{let s=0,i=()=>{s++;try{let c=t(...r);o(c)}catch(c){if(s>=e.length)n(c);else{let m=e[s-1];setTimeout(i,m)}}};i()})}var ci=l(require("fs-extra")),Qd=l(require("path"));async function be(t){let e=await ci.default.pathExists(t);if(!e)throw new Error("File does not exist");return e}var pi=p.extend("jest-discovery");async function mi(t){try{let{readInitialOptions:e}=ai(),{config:r,configPath:o}=await e(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"],s=["collectCoverageFrom","coverageDirectory","coveragePathIgnorePatterns","detectLeaks","detectOpenHandles","errorOnDeprecated","forceCoverageMatch","openHandlesTimeout","runner","watchPathIgnorePatterns"],i=(0,Zr.omit)(r,n);if(i.projects&&(i.projects=i.projects.map(d=>typeof d!="string"?(0,Zr.omit)(d,s):d)),i.rootDir&&Object.keys(i).length===1)return null;let c=to.default.resolve(o?to.default.dirname(o):process.cwd(),`.jest-scanner-${new Date().getTime()}.config.cjs`),m=`module.exports=${JSON.stringify(i,null,2)}`;return pi("configFileContent: %O",m),di.default.writeFileSync(c,m),await Pe(be,[200,200,200,200,200,1e3])(c),c}catch(e){return C("Failed to recreate the config file"),pi("error %o",e),null}}async function li(t){let e="!!##ThisPatternWillNotMatchAnyTestName##!!",r=t.options,o=oi(r),n=ei(o),s=r.config,i=await mi(s);return{cliArgs:[n,"--testNamePattern",e,"--reporters","@currents/cmd/discovery/jest","--shard=1/1",i?`--config=${i}`:"",...t.args].filter(m=>!(0,ui.isEmpty)(m)),configFilePath:i}}var Xd=p.extend("jest-discovery");async function hi(t,e){console.time(x("@currents/jest:fullTestSuite-ready"));let{run:r}=ii(),{cliArgs:o,configFilePath:n}=await li(e);try{let s=gi.default.fileSync({postfix:".json"});return Xd("running scanner: %o",o),process.env.CURRENTS_DISCOVERY_PATH=s.name,await r(o.concat(["--openHandlesTimeout=0"])),await Pe(be,Array.from({length:300},()=>100))(s.name),console.timeEnd(x("@currents/jest:fullTestSuite-ready")),await ht(s.name)}catch(s){return C("Failed to obtain the jest full test suite:",s),[]}finally{n&&fi.default.unlinkSync(n)}}var Ne=class extends mt{constructor(e){super(e)}async getFullTestSuite(){return hi(this.config.frameworkConfig,this.config.cliArgs)}};var Ii=l(require("fs-extra"));var Ei=l(require("path"));function Tt(t){return Ei.default.join(t,"fullTestSuite.json")}var Zd=p.extend("junit-discovery");async function Ci(t){console.time(x("@currents/junit:fullTestSuite-ready"));try{Zd("running scanner: %o",t);let e=Tt(t);process.env.CURRENTS_DISCOVERY_PATH=e;let r=Ii.default.readFileSync(e,"utf-8");return JSON.parse(r)}catch(e){return C("Failed to obtain the junit full test suite:",e),[]}}var Le=class extends mt{constructor(e,r){super(e),this.reportDir=r}async getFullTestSuite(){return Ci(this.reportDir)}};function Ti(t,e){switch(t.framework){case"jest":return new Ne(t);case"junit":return new Le(t,e);default:return new mt(t)}}var ut=l(require("fs-extra")),it=l(require("path"));async function yi(t){let e=await tm(t?.reportDir);return{reportDir:e,configFilePath:t?.configFilePath??it.default.join(e,"config.json")}}async function tm(t){if(t){if(!await ut.default.pathExists(t))throw new Error(`No reports found: the folder "${t}" does not exist.`);return t}let e=(0,it.join)(process.cwd(),".currents"),r=await ut.default.pathExists(e)?await em(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 em(t){let e=await ut.default.readdir(t),r=null;for(let o of e){let n=it.default.join(t,o),s=await ut.default.stat(n);s.isDirectory()&&(!r||s.birthtime>r.birthtime)&&(r={name:o,birthtime:s.birthtime})}return r?(0,it.resolve)(t,r.name):null}async function eo(t){try{return await ut.default.pathExists(t)}catch{return C("Error checking if path exists:",C),!1}}async function Ri(t){let e=it.default.join(t,"instances");return rm(e)}async function rm(t){let e=await ut.default.readdir(t),r=[];for(let o of e){let n=it.default.join(t,o);(await ut.default.stat(n)).isFile()&&r.push(n)}return r}var om=t=>Buffer.byteLength(JSON.stringify(t),"utf8"),_i=(t,e=1048576)=>{let r=[],o=[],n=0;for(let s of t){let i=om(s);n+i>e&&(r.push(o),o=[],n=0),o.push(s),n+=i}return o.length>0&&r.push(o),r};var nm=3e4;async function oo(){let t=xe();if(!t)throw new Error("Currents config is missing!");let e=await yi(t);Mo(im(e.reportDir)),p("Reporter options: %o",e),T("Report directory: %s",e.reportDir);let r=await ht(e.configFilePath);p("Report config: %o",r);let o=await Ri(e.reportDir);p("Found %d instance results in the reportDir: %s",o.length,e.reportDir);let n=sm(e.reportDir),s=await eo(n),i=Tt(e.reportDir),c=null;if(s){let M=await ht(n);E("Marker file detected. The report was already uploaded: %o",{runUrl:M.response.runUrl,isoDate:M.isoDate})}if(await eo(i)&&(c=await ht(i),p("Full test suite file detected: %s",i)),c)p("The discovery stage was skipped");else{if(c=await Ti(r,e.reportDir).getFullTestSuite(),am(c))throw new Error("Failed to discover the full test suite!");await Et(i,JSON.stringify(c))}let d=c.length===1?c[0].name:null,f={currents:t},u={type:r.framework,version:r.frameworkVersion,clientVersion:xt,frameworkConfig:{originFramework:r.frameworkConfig?.originFramework,originFrameworkVersion:r.frameworkConfig?.originFrameworkVersion}},I=pe.userFacingNanoid(),g=rt(t.ciBuildId),S={};for await(let M of o){let j=await ht(M);S[j.groupId]||(S[j.groupId]=[]),S[j.groupId].push(j)}let V=await Hs(e.reportDir);if(V){let M=await Zs({instances:Object.values(S).flat(),reportDir:e.reportDir,manifest:V});T("[currents] Attached %d Detox artifacts and %d steps",M.artifacts,M.steps)}let Ot=new Map;Object.values(S).forEach(M=>{M.forEach(j=>{j.artifacts?.forEach($=>{$&&Ot.set($.path,$.contentType)}),j.results.tests.forEach($=>{$.artifacts?.forEach(k=>{k&&Ot.set(k.path,k.contentType)}),$.attempts.forEach(k=>{k.artifacts?.forEach(ft=>{ft&&Ot.set(ft.path,ft.contentType)})})})})});for await(let M of Object.keys(S)){let j=S[M],$=M;d&&(p("Default group found: %s, overwriting the group in the results",d),$=d,j=j.map(k=>({...k,groupId:d})));try{let k=_i(j),ft=await wi({ci:g,group:$,instances:[],fullTestSuite:c,config:f,machineId:I,framework:u});for(let lr=0;lr<k.length;lr++){let fr=await wi({ci:g,group:$,instances:k[lr],fullTestSuite:[],config:f,machineId:I,framework:u});fr.artifactUploadUrls&&fr.artifactUploadUrls.length>0&&await cm(fr.artifactUploadUrls,e.reportDir,Ot)}p("Api response: %o",ft),T("[%s] Run created: %s",$,ft.runUrl);let Gc={response:ft,isoDate:new Date().toISOString()};await Et(n,JSON.stringify(Gc)),p("Marker file %s: %s",s?"overwritten":"created",n)}catch(k){throw p("Failed to upload the results to the dashboard"),k}}}async function wi({ci:t,group:e,instances:r,fullTestSuite:o,config:n,machineId:s,framework:i}){let c=await Oe(),m=await Ms(),d={browserName:"node",browserVersion:xi.default.coerce(process.version)?.version},{currents:f}=n,I={platform:{...d,...m},ci:t,commit:c,group:e,fullTestSuite:o,config:n,projectId:f.projectId,recordKey:f.recordKey,ciBuildId:t.ciBuildId.value??void 0,tags:f.tag??[],machineId:f.machineId??s,framework:i,instances:r,previousCiBuildId:process.env.CURRENTS_PREVIOUS_CI_BUILD_ID};return p("Creating run: %o",h(I)),Rn(I)}function sm(t){return ve.default.join(t,"upload.marker.json")}function im(t){return ve.default.join(t,`.debug-${new Date().toISOString()}.log`)}function am(t){return t.length===0||t.some(e=>e.tests.length===0)}async function cm(t,e,r){p("Uploading %d artifacts",t.length),await Promise.all(t.map(o=>{let n=ve.default.join(e,o.path),s=r.get(o.path)||"application/octet-stream";return pm(n,s,o.uploadUrl)}))}var pm=async(t,e,r)=>{try{if(!await ro.default.pathExists(t)){E("Artifact file not found: %s",t);return}let o=await ro.default.readFile(t);await Oi.default.put(r,o,{headers:{"Content-Type":e},timeout:nm})}catch(o){p("Failed to upload artifact %s: %o",t,o)}};var dm=p.extend("cli");async function Ai(t,e){await w(async r=>{r.output||Pt(),e.getOptionValueSource("ciBuildId")==="env"&&(r.branch||r.tag)&&(r={...r,ciBuildId:void 0}),zo(r);let n=le();dm("Config: %o",h(n)),await Dr()},t)}var X=require("@commander-js/extra-typings");var Di=require("axios"),Pi=l(require("fs-extra"));var mm=p.extend("api");function um(t){if(/^[a-z][a-z0-9+.-]*:\/\//i.test(t))throw new Error(`Pass a path such as /v1/runs/<run-id>, not a URL. The CLI sends requests to ${Vt()}`);let e=t.replace(/^\/+/,""),r=o=>/^(\.|%2e){1,2}$/i.test(o);if(e.split(/[?#]/)[0].split("/").some(r))throw new Error(`The path cannot hold "." or ".." segments: ${t}`);return/^v1(\/|\?|$)/.test(e)?e:`v1/${e}`}function lm(t){let e=Object.create(null);for(let[r,o]of t)if(r.endsWith("[]")){let n=r.slice(0,-2);e[n]=[...Array.isArray(e[n])?e[n]:[],o]}else e[r]=o;return e}function fm(t){let e=new URLSearchParams;for(let[r,o]of t)e.append(r,String(o));return e}async function gm(t){let e=t==="-"?await new Promise((r,o)=>{let n="";process.stdin.setEncoding("utf8"),process.stdin.on("data",s=>n+=s),process.stdin.on("end",()=>r(n)),process.stdin.on("error",o)}):await Pi.default.readFile(t,"utf8");try{return JSON.parse(e)}catch(r){throw new Error(`--input ${t} is not valid JSON: ${r.message}`)}}async function hm(t,e){let r=[...e.field??[],...e.rawField??[]],o=e.input!==void 0,n=e.method??(o||r.length>0?"POST":"GET"),s=o||n==="GET"||n==="HEAD";return{method:n,url:um(t),params:s&&r.length>0?fm(r):void 0,data:o?JSON.stringify(await gm(e.input)):!s&&r.length>0?JSON.stringify(lm(r)):void 0,headers:Object.fromEntries(e.header??[])}}function Si(t){let e=Object.entries(t.headers).map(([r,o])=>`${r}: ${Array.isArray(o)?o.join(", "):o}`);return[`HTTP/1.1 ${t.status} ${t.statusText}`,...e,"",""].join(`
28
+ `)}function Ui(t,e){let r=t.data??"",o=String(t.headers["content-type"]??"").toLowerCase().includes("json");if(!e||!o||!r)return r;try{return JSON.stringify(JSON.parse(r),null,2)+`
29
+ `}catch{return r}}async function bi(t,e){let{apiKey:r}=U(_,["apiKey"],e),o=s=>s?.map(([i])=>i);mm("Options: %o",h({...e,field:o(e.field),rawField:o(e.rawField),header:o(e.header)}));let n=await hm(t,e);try{let s=await Dn(r,n);e.include&&process.stdout.write(Si(s)),process.stdout.write(Ui(s,!!process.stdout.isTTY))}catch(s){if(!(0,Di.isAxiosError)(s))throw s;let i=s.response;if(!i)throw new Error(`Could not reach the REST API at ${Vt()}: ${s.message}`);e.include&&process.stderr.write(Si(i));let c=Ui(i,!!process.stderr.isTTY);throw c&&process.stderr.write(c.endsWith(`
30
30
  `)?c:`${c}
31
- `),new Error(`${n.method} ${n.url.split("?")[0]} failed: the REST API answered ${i.status} ${i.statusText}`)}}var Si=["GET","POST","PUT","PATCH","DELETE","HEAD"];function eo(t,e){let r=t.indexOf(e),o=r<0?"":t.slice(0,r).trim();if(!o)throw new X.InvalidArgumentError(`Expected key${e}value.`);let n=t.slice(r+1);return[o,e===":"?n.trim():n]}function pm(t){if(t==="true")return!0;if(t==="false")return!1;if(t==="null")return null;if(/^-?\d+(\.\d+)?$/.test(t)){let e=Number(t);if(t.includes(".")?Number.isFinite(e):Number.isSafeInteger(e))return e}return t}var dm=(t,e=[])=>{let[r,o]=eo(t,"=");return[...e,[r,pm(o)]]},mm=(t,e=[])=>[...e,eo(t,"=")],um=(t,e=[])=>[...e,eo(t,":")],Ui=new X.Option("-X, --method <method>","the HTTP method; GET by default, POST when --field, --raw-field or --input is given").argParser(t=>{let e=t.toUpperCase();if(!Si.includes(e))throw new X.InvalidArgumentError(`Use one of ${Si.join(", ")}.`);return e}),Di=new X.Option("-f, --field <key=value>","a request parameter; repeat for more. Sent in the query string of a GET and in the JSON body otherwise. true, false, null and numbers are sent as JSON values; in a JSON body, key[]=value adds the value to an array").argParser(dm),Pi=new X.Option("-F, --raw-field <key=value>","like --field, but the value is always a string").argParser(mm),bi=new X.Option("--input <file>",'send the JSON in this file as the body, or the JSON from stdin with "-"; fields then go to the query string'),Ni=new X.Option("-H, --header <key:value>","an HTTP header to send; repeat for more").argParser(um),Li=new X.Option("-i, --include","print the HTTP status line and the response headers before the body");async function Bi(t,e){await w(async r=>{Pt(),await Ai(t,r)},e)}var yt=require("@commander-js/extra-typings");var ro="(required)",at=(t=ro)=>new yt.Option("-k, --key <record-key>",`the record key from the Currents dashboard ${t}`).env(_.recordKey.env),ct=(t=ro)=>new yt.Option("--api-key <api-key>",`an API key from the Currents dashboard ${t}`).env(_.apiKey.env),Z=()=>new yt.Option("-p, --project-id <id>",`the project ID from the Currents dashboard ${ro}`).env(_.projectId.env),Nt=t=>new yt.Option("--ci-build-id <id>",`the CI build ID the run was recorded with${t}`).env(_.ciBuildId.env),Lt=t=>new yt.Option("-t, --tag <tag>",`${t}; comma-separated or repeated`).argParser(Ie),P=()=>new yt.Option("--debug","print debug logs; keys are hidden in them").env(_.debug.env).default(!1);var Le=require("@commander-js/extra-typings");var vi=new Le.Option("-o, --output <path>","write the JSON to this file instead of stdout").env(N(ue,"output")),Mi=Nt("; cannot be combined with --branch or --tag. The environment variable is ignored when --branch or --tag is set"),Fi=Lt("find the last run with these tags"),ki=new Le.Option("-b, --branch <branch>","find the last run of this git branch"),Gi=new Le.Option("--pw-last-run","print only the status and the failed tests of the run, in the format of Playwright's .last-run.json");var Be="get",oo="run",so=t=>[{comment:"Get the data of the run recorded under a CI build ID",commands:[`${t} ${oo} ${Be} --api-key <api-key> --project-id <project-id> --ci-build-id <ci-build-id>`]},{comment:"Get the data of the last run of a branch with the tags tagA and tagB",commands:[`${t} ${oo} ${Be} --api-key <api-key> --project-id <project-id> --branch <branch> --tag tagA,tagB`]},{comment:'Save the failed tests of a run where Playwright reads them, for "playwright test --last-failed"',commands:[`${t} ${oo} ${Be} --api-key <api-key> --project-id <project-id> --ci-build-id <ci-build-id> --pw-last-run --output test-results/.last-run.json`]}],lm=t=>[{comment:"Get a run, with the API key in CURRENTS_API_KEY",commands:[`${t} api /v1/runs/<run-id>`]},{comment:"List the failed runs of the main branch of a project",commands:[`${t} api /v1/projects/<project-id>/runs -X GET -f "branches[]=main" -f status=FAILED -f limit=20`]},{comment:"Cancel a run",commands:[`${t} api /v1/runs/<run-id>/cancel -X PUT`]},{comment:"Create a webhook from the JSON in webhook.json",commands:[`${t} api /v1/webhooks -X POST -F projectId=<project-id> --input webhook.json`]}],$i=t=>new no.Command().name("api").summary("Make an authenticated request to the Currents REST API").description(`Make an authenticated request to the Currents REST API and print the response body. The path is a REST API route, such as /v1/runs/<run-id>; v1/runs/<run-id> and runs/<run-id> are the same route. A response that is not 2xx prints its body on stderr and exits with 1.
31
+ `),new Error(`${n.method} ${n.url.split("?")[0]} failed: the REST API answered ${i.status} ${i.statusText}`)}}var Ni=["GET","POST","PUT","PATCH","DELETE","HEAD"];function no(t,e){let r=t.indexOf(e),o=r<0?"":t.slice(0,r).trim();if(!o)throw new X.InvalidArgumentError(`Expected key${e}value.`);let n=t.slice(r+1);return[o,e===":"?n.trim():n]}function Em(t){if(t==="true")return!0;if(t==="false")return!1;if(t==="null")return null;if(/^-?\d+(\.\d+)?$/.test(t)){let e=Number(t);if(t.includes(".")?Number.isFinite(e):Number.isSafeInteger(e))return e}return t}var Im=(t,e=[])=>{let[r,o]=no(t,"=");return[...e,[r,Em(o)]]},Cm=(t,e=[])=>[...e,no(t,"=")],Tm=(t,e=[])=>[...e,no(t,":")],Li=new X.Option("-X, --method <method>","the HTTP method; GET by default, POST when --field, --raw-field or --input is given").argParser(t=>{let e=t.toUpperCase();if(!Ni.includes(e))throw new X.InvalidArgumentError(`Use one of ${Ni.join(", ")}.`);return e}),vi=new X.Option("-f, --field <key=value>","a request parameter; repeat for more. Sent in the query string of a GET and in the JSON body otherwise. true, false, null and numbers are sent as JSON values; in a JSON body, key[]=value adds the value to an array").argParser(Im),Bi=new X.Option("-F, --raw-field <key=value>","like --field, but the value is always a string").argParser(Cm),Mi=new X.Option("--input <file>",'send the JSON in this file as the body, or the JSON from stdin with "-"; fields then go to the query string'),Fi=new X.Option("-H, --header <key:value>","an HTTP header to send; repeat for more").argParser(Tm),ki=new X.Option("-i, --include","print the HTTP status line and the response headers before the body");async function Gi(t,e){await w(async r=>{Pt(),await bi(t,r)},e)}var yt=require("@commander-js/extra-typings");var so="(required)",at=(t=so)=>new yt.Option("-k, --key <record-key>",`the record key from the Currents dashboard ${t}`).env(_.recordKey.env),ct=(t=so)=>new yt.Option("--api-key <api-key>",`an API key from the Currents dashboard ${t}`).env(_.apiKey.env),Z=()=>new yt.Option("-p, --project-id <id>",`the project ID from the Currents dashboard ${so}`).env(_.projectId.env),Nt=t=>new yt.Option("--ci-build-id <id>",`the CI build ID the run was recorded with${t}`).env(_.ciBuildId.env),Lt=t=>new yt.Option("-t, --tag <tag>",`${t}; comma-separated or repeated`).argParser(Ie),P=()=>new yt.Option("--debug","print debug logs; keys are hidden in them").env(_.debug.env).default(!1);var Be=require("@commander-js/extra-typings");var ji=new Be.Option("-o, --output <path>","write the JSON to this file instead of stdout").env(N(ue,"output")),$i=Nt("; cannot be combined with --branch or --tag. The environment variable is ignored when --branch or --tag is set"),Ki=Lt("find the last run with these tags"),Hi=new Be.Option("-b, --branch <branch>","find the last run of this git branch"),Ji=new Be.Option("--pw-last-run","print only the status and the failed tests of the run, in the format of Playwright's .last-run.json");var Me="get",io="run",co=t=>[{comment:"Get the data of the run recorded under a CI build ID",commands:[`${t} ${io} ${Me} --api-key <api-key> --project-id <project-id> --ci-build-id <ci-build-id>`]},{comment:"Get the data of the last run of a branch with the tags tagA and tagB",commands:[`${t} ${io} ${Me} --api-key <api-key> --project-id <project-id> --branch <branch> --tag tagA,tagB`]},{comment:'Save the failed tests of a run where Playwright reads them, for "playwright test --last-failed"',commands:[`${t} ${io} ${Me} --api-key <api-key> --project-id <project-id> --ci-build-id <ci-build-id> --pw-last-run --output test-results/.last-run.json`]}],ym=t=>[{comment:"Get a run, with the API key in CURRENTS_API_KEY",commands:[`${t} api /v1/runs/<run-id>`]},{comment:"List the failed runs of the main branch of a project",commands:[`${t} api /v1/projects/<project-id>/runs -X GET -f "branches[]=main" -f status=FAILED -f limit=20`]},{comment:"Cancel a run",commands:[`${t} api /v1/runs/<run-id>/cancel -X PUT`]},{comment:"Create a webhook from the JSON in webhook.json",commands:[`${t} api /v1/webhooks -X POST -F projectId=<project-id> --input webhook.json`]}],Vi=t=>new ao.Command().name("api").summary("Make an authenticated request to the Currents REST API").description(`Make an authenticated request to the Currents REST API and print the response body. The path is a REST API route, such as /v1/runs/<run-id>; v1/runs/<run-id> and runs/<run-id> are the same route. A response that is not 2xx prints its body on stderr and exits with 1.
32
32
 
33
- The REST API routes: https://docs.currents.dev/resources/api/api-resources`).usage("<path> [options]").argument("<path>","the REST API route, such as /v1/runs/<run-id>").enablePositionalOptions().helpCommand(!1).addOption(ct()).addOption(Ui).addOption(Di).addOption(Pi).addOption(bi).addOption(Ni).addOption(Li).addOption(P()).addHelpText("after",y(lm(t))).showHelpAfterError("(add --help for additional information)").addCommand(io(t).name("get-run"),{hidden:!0}).action((r,o,n)=>r==="help"?n.help():Bi(r,o)),io=t=>new no.Command().name(Be).summary("Get the data of a run from the Currents API").description("Get the data of a run from the Currents API and print it as JSON, or write it to --output. Find the run by --ci-build-id, or the last run by --branch, --tag or both").addHelpText("after",y(so(t))).allowUnknownOption().addOption(ct()).addOption(P()).addOption(Mi).addOption(Z()).addOption(ki).addOption(Fi).addOption(vi).addOption(Gi).action(Ri);var ve=require("@commander-js/extra-typings");var fm=p.extend("cli");async function Ki(t){await w(async e=>{Yn(Wn(e));let r=dt();fm("Config: %o",h(r.values)),await $r()},t)}var gm=p.extend("cli");async function Hi(t){await w(async e=>{Jn(qn(e));let r=dt();gm("Config: %o",h(r.values)),await Kr()},t)}var Bt="cache",Me=t=>[{comment:"Save files to the cache under an ID",commands:[`${t} ${Bt} set --key <record-key> --id <id> --path <path-1,path-2,...path-n>`]},{comment:"Save Playwright's .last-run.json to the cache",commands:[`${t} ${Bt} set --key <record-key> --preset last-run`]}],Fe=t=>[{comment:"Restore the files saved in the cache under an ID",commands:[`${t} ${Bt} get --key <record-key> --id <id>`]},{comment:"Restore Playwright's .last-run.json from the cache, to rerun only the failed tests",commands:[`${t} ${Bt} get --key <record-key> --preset last-run`]},{comment:"Restore Playwright's .last-run.json to another folder",commands:[`${t} ${Bt} get --key <record-key> --preset last-run --output-dir <output-dir>`]}],ji=t=>new ve.Command().command(Bt).summary("Save files to the Currents cache and restore them").description("Save files to the Currents cache and restore them, e.g. in another CI job").addHelpText("after",y([...Me(t),...Fe(t)])).showHelpAfterError("(add --help for additional information)").allowUnknownOption().addCommand(hm(t)).addCommand(Em(t)),hm=t=>new ve.Command().name("set").description("Save files to the cache").addHelpText("after",y(Me(t))).allowUnknownOption().addOption(at()).addOption(Nn).addOption(vn).addOption(Bn).addOption(P()).addOption(kn).addOption(Ur).addOption(Dr).addOption(Hn).action(Hi),Em=t=>new ve.Command().name("get").description("Restore files from the cache").addHelpText("after",y(Fe(t))).allowUnknownOption().addOption(at()).addOption(Ln).addOption(Mn).addOption(Fn).addOption(Gn).addOption(P()).addOption(Ur).addOption(Dr).addOption(Kn).action(Ki);var qi=require("@commander-js/extra-typings");var Im=p.extend("cli");async function Vi(t){await w(async({key:e,...r})=>{Ss({...r,recordKey:e});let o=we();Im("Config: %o",h(o??{})),await jr()},t)}var Ji=require("@commander-js/extra-typings");var Yi=Nt(" (required unless --run-id is set)"),Wi=new Ji.Option("--run-id <id>","the ID of the run to cancel, as printed when the run was created; wins over --ci-build-id").env(N(Q,"runId"));var vt="cancel",ke="run",te=t=>[{comment:"Cancel the run recorded under a CI build ID",commands:[`${t} ${ke} ${vt} --key <record-key> --project-id <id> --ci-build-id <build-id>`]},{comment:"Cancel a run by its ID, as printed when the run was created",commands:[`${t} ${ke} ${vt} --key <record-key> --project-id <id> --run-id <run-id>`]},{comment:"Cancel the run when a GitHub Actions workflow is cancelled (workflow step). It reads CURRENTS_RECORD_KEY, CURRENTS_PROJECT_ID and CURRENTS_CI_BUILD_ID from the environment",commands:[`- if: \${{ cancelled() }}
34
- run: npx ${t} ${ke} ${vt}`]}],Ge=(t,{deprecated:e=!1}={})=>{let r=new qi.Command().name(vt).summary("Cancel a run in progress").description("Cancel a run in progress, e.g. when the CI job it belongs to is cancelled").addHelpText("after",y(te(t))).allowUnknownOption().addOption(at()).addOption(Z()).addOption(Yi).addOption(Wi).addOption(P()).action(Vi);return e&&r.hook("preAction",()=>{process.stderr.write(`'${t} ${vt}' is deprecated and will be removed in a future version. Use '${t} ${ke} ${vt}'.
35
- `)}),r};var Ea=require("@commander-js/extra-typings");var zi={debug:_.debug,inputFormat:{name:"Input format",cli:"--input-format"},inputFiles:{name:"Input file",cli:"--input-file"},outputDir:{name:"Output folder",cli:"--output-dir"},framework:{name:"Framework",cli:"--framework"},frameworkVersion:{name:"Framework version",cli:"--framework-version"}};var Cm=p.extend("config"),Tm=["inputFormat","inputFiles","framework"],ao=null;function Qi(t){ao=U(zi,Tm,t),Cm("Resolved config: %o",ao)}function $e(){return ao}function Xi(t){return{inputFiles:t.inputFile,inputFormat:t.inputFormat,outputDir:t.outputDir,framework:t.framework,frameworkVersion:t.frameworkVersion,debug:t.debug}}var ho=l(require("fs-extra")),L=require("path");var oa=require("lodash"),na=l(require("crypto"));var j=require("path"),He=async(t,e,r,o)=>{if(t)for(let n of t)try{let s=(0,j.resolve)(o,n.path),i=(0,j.relative)(o,s);if(i.startsWith("..")||(0,j.isAbsolute)(i)){p("Skipping artifact outside workspace: %s (resolved: %s)",n.path,s);continue}let c=`${et(e+n.path)}.${(0,j.extname)(n.path).slice(1)||"bin"}`;await ce(s,(0,j.join)(r,c)),n.path=(0,j.join)("artifacts",c)}catch(s){p("Failed to copy artifact %s: %o",n.path,s)}};function ta(t){let e=ra(t.properties?.property??t.property);return Ke(e,"currents.artifact.instance.","spec")}function ea(t){let e=ra(t.properties?.property),r=Ke(e,"currents.artifact.test.","test"),o=new Map;ym(e).forEach((i,c)=>{o.has(c)||o.set(c,[]),o.get(c).push(...i)});let s=Ke(e,"currents.artifact.attempt.","attempt");return s.length>0&&(o.has(0)||o.set(0,[]),o.get(0).push(...s)),{testArtifacts:r,attemptArtifacts:o}}function ym(t){let e=new Map,r=/^currents\.artifact\.attempt\.(\d+)\.(.+)$/,o=new Map;for(let n of t){let s=n.value??n._;if(!n.name||!s)continue;let i=n.name.match(r);if(!i)continue;let[,c,m]=i,d=parseInt(c,10);o.has(d)||o.set(d,[]),o.get(d).push({name:`currents.artifact.attempt.${m}`,value:s})}for(let[n,s]of o.entries()){let i=Ke(s,"currents.artifact.attempt.","attempt");i.length>0&&e.set(n,i)}return e}function Ke(t,e,r){let o=[],n={};for(let s of t){let i=s.value??s._;if(!s.name||!i||!s.name.startsWith(e))continue;let c=s.name.slice(e.length);/^\d+\./.test(c)||["path","type","contentType","name"].includes(c)&&(n[c]&&(Zi(n)&&o.push({...n,level:r}),n={}),n[c]=i)}return Zi(n)&&o.push({...n,level:r}),o}function Zi(t){return!!(t.path&&t.type&&t.contentType)}function ra(t){return t?Array.isArray(t)?t:[t]:[]}function sa(t,e,r,o){let n=Rt(t.failure),s=n.length>0,i=e?.timestamp??"",c="skipped"in t,m=c?"pending":s?"failed":"passed",{testArtifacts:d,attemptArtifacts:f}=ea(t);return{_t:je(i),testId:uo(ee(t.name,o).join(", "),o),title:ee(t.name,o),state:m,isFlaky:Rm(),expectedStatus:"passed",timeout:_m(),location:wm(e?.file??""),retries:Om(n),artifacts:d,attempts:xm(t,n,lo(i),r,f,c)}}function uo(t,e){let r=`${t}${e}`;return na.default.createHash("sha256").update(r).digest("hex").substring(0,16)}function je(t){return ia(t)?new Date(t).getTime():new Date().getTime()}function lo(t){return ia(t)?new Date(t).toISOString():new Date().toISOString()}function ia(t){let e=new Date(t);return!isNaN(e.getTime())}function ee(t,e){return[e,t].filter(Boolean)}function Rm(){return!1}function _m(){return 0}function wm(t){return{column:1,file:t,line:1}}function Om(t){let e=0;return t.forEach(r=>{typeof r!="string"&&e++}),e}function xm(t,e,r,o,n,s){let i=t.time?Ve(t.time):0;if(s)return[{_s:"pending",attempt:0,startTime:r,steps:[],duration:i,status:"skipped",stdout:co(t?.["system-out"]),stderr:po(t?.["system-err"]),artifacts:n.get(0),errors:[],error:void 0}];if(e.length===0){let c=[];return n.forEach(m=>{c.push(...m)}),[{_s:"passed",attempt:0,startTime:r,steps:[],duration:i,status:"passed",stdout:co(t?.["system-out"]),stderr:po(t?.["system-err"]),artifacts:c,errors:[],error:void 0}]}return e.reduce((c,m,d)=>{if(m!=="true"&&m!=="false"){let f=Am(m);c.push({_s:"failed",attempt:d,startTime:Sm(o,r),steps:[],duration:i,status:"failed",stdout:co(t?.["system-out"]),stderr:po(t?.["system-err"]),artifacts:n.get(d),errors:f,error:f[0]})}return c},[])}function co(t){return t?[t]:[]}function po(t){return t?[t]:[]}function Am(t){return t==="true"||t==="false"?[]:[typeof t=="string"?{message:t}:{message:t.message,stack:t._,value:t.type}]}function Sm(t,e){let r=je(e)+t;return new Date(r).toISOString()}function Rt(t){return t?Array.isArray(t)?t:[t]:[]}function Um(t){return Math.round(t*1e3)}function Ve(t){let e=parseFloat(t);return isNaN(e)?0:Um(e)}function Je(t,e,r){let o=(0,oa.isNumber)(r)&&r>0,n=!!t.id&&mo(e,"id",t.id);if(t.file){let s=mo(e,"file",t.file);return s&&!n?`${t.file} - ${t.id}`:s&&o?`${t.file} - ${r}`:t.file}if(t.name){let s=mo(e,"name",t.name);return s&&!n?`${t.name} - ${t.id}`:s&&o?`${t.name} - ${r}`:t.name}return t.id?n&&o?`${t.id} - ${r}`:t.id:o?`unknown - ${r}`:"unknown"}function mo(t,e,r){return t.filter(n=>n[e]===r).length>1}function aa(t){let e=[];return t.forEach(r=>{let o=Rt(r.testsuites?.testsuite),n={name:r.testsuites?.name??"No name",tags:[],tests:[]};o?.forEach(s=>{let i=Je(s,o);Rt(s?.testcase)?.forEach(m=>{let d={title:ee(m.name,i),spec:i,tags:[],testId:uo(ee(m.name,i).join(", "),i)};n.tests.push(d)})}),e.push(n)}),e}var lt=require("@commander-js/extra-typings"),ca=l(require("globby")),fo=(e=>(e.junit="junit",e))(fo||{}),Ye=t=>new lt.Option("--input-format <format>",["the format of the reports to convert",t].filter(Boolean).join(" ")).choices(Object.values(fo)),We=t=>new lt.Option("--input-file <patterns>",`comma-separated glob patterns of the report files, e.g. "reports/*.xml,other.xml"; quote them so that the shell does not expand them ${t}`).argParser(Dm),qe=new lt.Option("-o, --output-dir <folder>","the folder to save the converted reports to; it must be empty, not exist, or hold only the reports being converted"),go=(n=>(n.postman="postman",n.node="node",n.vitest="vitest",n.wdio="wdio",n))(go||{}),ze=t=>new lt.Option("--framework <framework>",`the test framework that wrote the reports ${t}`).choices(Object.values(go)),Qe=new lt.Option("--framework-version <version>","the version of the test framework that wrote the reports");function Dm(t){let e=t.split(",").map(o=>o.trim()),r=ca.sync(e);if(r.length===0)throw new lt.InvalidArgumentError("No files found with the provided patterns");return r}async function V(t){let e=new Map;return t.forEach(r=>{let o=Rt(r.testsuites?.testsuite),n=r.testsuites?.name??"No name";o.forEach((s,i)=>{let c=Je(s,o,i),m=Pm(s,n,c),d=et(n+c);m.results.tests.length!==0&&e.set(d,m)})}),e}function Pm(t,e,r){let o=lo(t.timestamp??""),n=t.time?Ve(t.time):0,s=new Date(je(t.timestamp??"")+n),i=Rt(t.testcase),c=[t["system-out"],t["system-err"],...i.flatMap(g=>[g["system-out"],g["system-err"]])].filter(g=>g).join(`
36
- `),m=0,d=i.filter(g=>"failure"in g).length,f=i.filter(g=>"skipped"in g).length,u=i.length-d-f;return{groupId:e,spec:r,startTime:o,artifacts:ta(t),_stdout:c,results:{stats:{suites:1,tests:i.length,passes:u,pending:f,skipped:0,failures:d,flaky:0,wallClockStartedAt:o,wallClockEndedAt:s.toISOString(),wallClockDuration:n},tests:i?.map(g=>(i[0]?.time&&(m+=Ve(i[0].time)),sa(g,t,m,r)))}}}async function pa({inputFormat:t,framework:e,parsedXMLArray:r}){return t==="junit"?bm(e,r):new Map}async function bm(t,e){switch(t){case"node":return V(e);case"postman":return V(e);case"vitest":return V(e);case"wdio":return V(e);default:return E("Unsupported framework: %s",t),new Map}}var da=require("fs-extra"),ma=require("xml2js");async function ua(t){let e=await Promise.all(t.map(o=>(0,da.readFile)(o,"utf-8"))),r=(await Promise.all(e.map(Nm))).filter(Boolean);return e.length!==r.length&&E("Some files could not be parsed. Enable debug logging for more details"),r}async function Nm(t){let e=t.trim();if(!e)return null;try{return await(0,ma.parseStringPromise)(e,{explicitArray:!1,mergeAttrs:!0})||null}catch(r){return p("Error parsing XML input",r),null}}function la(t){return{framework:t.inputFormat,frameworkVersion:t.frameworkVersion??null,frameworkConfig:{originFramework:t.framework,originFrameworkVersion:t.frameworkVersion}}}async function fa(){try{let t=$e();if(!t)throw new Error("Config is missing!");t.outputDir&&await Lm(t.outputDir,t.inputFiles);let e=t.outputDir?await It(t.outputDir):await Ho(process.cwd(),".currents"),r=await It((0,L.join)(e,"instances")),o=la(t);p("Report config:",o),T("[currents] Convertion files: %s",t.inputFiles.join(", ")),await Vt((0,L.join)(e,"config.json"),JSON.stringify(o));let n=await ua(t.inputFiles);if(n.length===0)throw new Error("No valid XML JUnit report was found.");let s=aa(n);await Vt(Tt(e),JSON.stringify(s));let i=await pa({inputFormat:t.inputFormat,framework:t.framework,parsedXMLArray:n}),c=await It((0,L.join)(e,"artifacts")),m=process.cwd();return await Promise.all(Array.from(i.values()).map(async d=>{if(await He(d.artifacts,d.spec,c,m),d._stdout){let f=`${et(d.spec)}.stdout.txt`;await Vt((0,L.join)(c,f),d._stdout),d.artifacts||(d.artifacts=[]),d.artifacts.push({path:(0,L.join)("artifacts",f),type:"stdout",contentType:"text/plain",level:"spec"}),delete d._stdout}for(let f of d.results.tests){await He(f.artifacts,f.testId,c,m);for(let u of f.attempts)await He(u.artifacts,f.testId+u.attempt,c,m)}})),await Promise.all(Array.from(i.entries()).map(([d,f])=>Vt((0,L.join)(r,`${et(d)}.json`),JSON.stringify(f)))),T("[currents] Conversion completed, report saved to: %s",e),e}catch(t){throw p("Failed to convert: %o",t),t}}async function Lm(t,e){let r=(0,L.resolve)(t),o=new Set(e.map(c=>(0,L.resolve)(c))),n=[(0,L.join)(r,"config.json"),Tt(r),(0,L.join)(r,"instances"),(0,L.join)(r,"artifacts")],s=[...o].find(c=>n.some(m=>c===m||c.startsWith(m+L.sep)));if(s)throw new Error(`The report "${s}" is where the conversion writes its own files. Move the reports out of "${t}", or leave out --output-dir to convert into a new folder in .currents.`);if(await ho.default.pathExists(r)?await ga(r,o):void 0)throw new Error(`The folder "${t}" is not empty. Reports already in it would be uploaded with the converted ones. Remove the folder, or leave out --output-dir to convert into a new folder in .currents.`)}async function ga(t,e){for(let r of await ho.default.readdir(t,{withFileTypes:!0})){let o=(0,L.join)(t,r.name),n=r.isDirectory()?await ga(o,e):e.has(o)?void 0:o;if(n)return n}}var Bm=p.extend("cli");async function Eo(t){return Qi(Xi(t)),Bm("Config: %o",$e()),fa()}async function ha(t){await w(async e=>{await Eo(e)},t)}var Io="convert",vm=t=>[{comment:"Convert JUnit test reports to the Currents format, to check the result before an upload",commands:[`${t} ${Io} --input-format junit --input-file "./*.xml" --framework postman`]}],Ia=t=>new Ea.Command().name(Io).command(Io).showHelpAfterError("(add --help for additional information)").allowUnknownOption().summary("Convert JUnit XML reports to the Currents format").description("Convert JUnit XML reports to the Currents format, without uploading them. The converted reports are saved to --output-dir or a new folder in .currents").addHelpText("after",y(vm(t))).addOption(P()).addOption(Ye("(required)")).addOption(We("(required)")).addOption(qe).addOption(ze("(required)")).addOption(Qe).action(r=>ha(r));var Do=require("@commander-js/extra-typings");var{apiKey:Mm,recordKey:Fm,projectId:km,ciBuildId:Gm,machineId:$m,debug:Km}=_,F={apiKey:Mm,recordKey:Fm,projectId:km,ciBuildId:Gm,machineId:$m,sessionId:{name:"Session ID",env:"CURRENTS_SESSION_ID",cli:"--session-id"},title:{name:"Title",cli:"--title"},debug:Km};var Xe=p.extend("config");function Ca(t){let e=U(F,["apiKey","projectId","title"],t);return Xe("Resolved config: %o",h(e)),e}function Ta(t){let e=U(F,["apiKey"],t);return Xe("Resolved config: %o",h(e)),e}function ya(t){let e=U(F,["apiKey"],t);return Xe("Resolved config: %o",h(e)),e}function Ra(t){let e=U(F,["projectId"],t,Hm);return Xe("Resolved config: %o",h(e)),e}function Hm(t){if(!(t.recordKey||t.apiKey))throw new W(`${F.recordKey.name} or ${F.apiKey.name} is required. Set ${F.recordKey.env} or ${F.apiKey.env}, or pass ${F.recordKey.cli} or ${F.apiKey.cli}`)}var Mt=l(require("fs-extra")),tr=l(require("path"));var wa=l(require("path"));var _a=["trace","screenshot","video","attachment"];var jm=["image/png","image/jpeg","image/webp","image/gif"],Oa=t=>wa.default.extname(t).toLowerCase()===".zip";function xa(t){return _a.includes(t)}function Co(t){return Oa(t)?"application/zip":Yr(t)?.contentType??"application/octet-stream"}function Vm(t){return Oa(t)?"trace":Yr(t)?.type??"attachment"}function To(t,e){let r=Vm(t);return e.includes(r)?r:"attachment"}function Aa(t,e,r){if(!r.includes(e))throw new Error(`Cannot attach "${t}" as type "${e}" here. The target takes: ${r.join(", ")}`)}function Sa(t,e){let r=Co(t);if(!(e==="attachment"||e==="trace"&&r==="application/zip"||e==="screenshot"&&jm.includes(r)||e==="video"&&r.startsWith("video/")))throw new Error(`Cannot attach "${t}" as type "${e}": its content type is ${r}`)}var Ua=l(require("archiver")),_t=l(require("fs-extra")),Ze=l(require("path")),Da=l(require("unzipper")),Pa=require("tmp-promise");async function ba(t){try{return(await Da.default.Open.file(t)).files.some(r=>r.path==="trace.trace")}catch{return!1}}var Na=/^trace-.*\.trace$/,Jm=/^trace-.*\.network$/;async function yo(t){return(await _t.default.readdir(t)).some(r=>Na.test(r))}function Ym(t){if(!t)return!1;try{let e=JSON.parse(t),r=e.snapshot?.response;if(e.type!=="resource-snapshot"||!r)return!0;let o=r.status>=200&&r.status<400,n=/javascript|ecmascript/i.test(r.content?.mimeType??"");return!(o&&n)}catch{return!0}}async function La(t,e){return(await _t.default.readdir(t)).filter(o=>e.test(o)).sort().map(o=>Ze.default.join(t,o))}async function Wm(t){return(await Promise.all((await La(t,Na)).map(r=>_t.default.readFile(r,"utf8")))).map(r=>r.endsWith(`
33
+ The REST API routes: https://docs.currents.dev/resources/api/api-resources`).usage("<path> [options]").argument("<path>","the REST API route, such as /v1/runs/<run-id>").enablePositionalOptions().helpCommand(!1).addOption(ct()).addOption(Li).addOption(vi).addOption(Bi).addOption(Mi).addOption(Fi).addOption(ki).addOption(P()).addHelpText("after",y(ym(t))).showHelpAfterError("(add --help for additional information)").addCommand(po(t).name("get-run"),{hidden:!0}).action((r,o,n)=>r==="help"?n.help():Gi(r,o)),po=t=>new ao.Command().name(Me).summary("Get the data of a run from the Currents API").description("Get the data of a run from the Currents API and print it as JSON, or write it to --output. Find the run by --ci-build-id, or the last run by --branch, --tag or both").addHelpText("after",y(co(t))).allowUnknownOption().addOption(ct()).addOption(P()).addOption($i).addOption(Z()).addOption(Hi).addOption(Ki).addOption(ji).addOption(Ji).action(Ai);var Fe=require("@commander-js/extra-typings");var Rm=p.extend("cli");async function Yi(t){await w(async e=>{zn(Qn(e));let r=dt();Rm("Config: %o",h(r.values)),await Kr()},t)}var _m=p.extend("cli");async function Wi(t){await w(async e=>{qn(Xn(e));let r=dt();_m("Config: %o",h(r.values)),await Hr()},t)}var vt="cache",ke=t=>[{comment:"Save files to the cache under an ID",commands:[`${t} ${vt} set --key <record-key> --id <id> --path <path-1,path-2,...path-n>`]},{comment:"Save Playwright's .last-run.json to the cache",commands:[`${t} ${vt} set --key <record-key> --preset last-run`]}],Ge=t=>[{comment:"Restore the files saved in the cache under an ID",commands:[`${t} ${vt} get --key <record-key> --id <id>`]},{comment:"Restore Playwright's .last-run.json from the cache, to rerun only the failed tests",commands:[`${t} ${vt} get --key <record-key> --preset last-run`]},{comment:"Restore Playwright's .last-run.json to another folder",commands:[`${t} ${vt} get --key <record-key> --preset last-run --output-dir <output-dir>`]}],qi=t=>new Fe.Command().command(vt).summary("Save files to the Currents cache and restore them").description("Save files to the Currents cache and restore them, e.g. in another CI job").addHelpText("after",y([...ke(t),...Ge(t)])).showHelpAfterError("(add --help for additional information)").allowUnknownOption().addCommand(wm(t)).addCommand(Om(t)),wm=t=>new Fe.Command().name("set").description("Save files to the cache").addHelpText("after",y(ke(t))).allowUnknownOption().addOption(at()).addOption(Bn).addOption(kn).addOption(Fn).addOption(P()).addOption($n).addOption(Pr).addOption(br).addOption(Vn).action(Wi),Om=t=>new Fe.Command().name("get").description("Restore files from the cache").addHelpText("after",y(Ge(t))).allowUnknownOption().addOption(at()).addOption(Mn).addOption(Gn).addOption(jn).addOption(Kn).addOption(P()).addOption(Pr).addOption(br).addOption(Jn).action(Yi);var ta=require("@commander-js/extra-typings");var xm=p.extend("cli");async function zi(t){await w(async({key:e,...r})=>{Ps({...r,recordKey:e});let o=we();xm("Config: %o",h(o??{})),await Vr()},t)}var Qi=require("@commander-js/extra-typings");var Xi=Nt(" (required unless --run-id is set)"),Zi=new Qi.Option("--run-id <id>","the ID of the run to cancel, as printed when the run was created; wins over --ci-build-id").env(N(Q,"runId"));var Bt="cancel",je="run",te=t=>[{comment:"Cancel the run recorded under a CI build ID",commands:[`${t} ${je} ${Bt} --key <record-key> --project-id <id> --ci-build-id <build-id>`]},{comment:"Cancel a run by its ID, as printed when the run was created",commands:[`${t} ${je} ${Bt} --key <record-key> --project-id <id> --run-id <run-id>`]},{comment:"Cancel the run when a GitHub Actions workflow is cancelled (workflow step). It reads CURRENTS_RECORD_KEY, CURRENTS_PROJECT_ID and CURRENTS_CI_BUILD_ID from the environment",commands:[`- if: \${{ cancelled() }}
34
+ run: npx ${t} ${je} ${Bt}`]}],$e=(t,{deprecated:e=!1}={})=>{let r=new ta.Command().name(Bt).summary("Cancel a run in progress").description("Cancel a run in progress, e.g. when the CI job it belongs to is cancelled").addHelpText("after",y(te(t))).allowUnknownOption().addOption(at()).addOption(Z()).addOption(Xi).addOption(Zi).addOption(P()).action(zi);return e&&r.hook("preAction",()=>{process.stderr.write(`'${t} ${Bt}' is deprecated and will be removed in a future version. Use '${t} ${je} ${Bt}'.
35
+ `)}),r};var Ra=require("@commander-js/extra-typings");var ea={debug:_.debug,inputFormat:{name:"Input format",cli:"--input-format"},inputFiles:{name:"Input file",cli:"--input-file"},outputDir:{name:"Output folder",cli:"--output-dir"},framework:{name:"Framework",cli:"--framework"},frameworkVersion:{name:"Framework version",cli:"--framework-version"}};var Am=p.extend("config"),Sm=["inputFormat","inputFiles","framework"],mo=null;function ra(t){mo=U(ea,Sm,t),Am("Resolved config: %o",mo)}function Ke(){return mo}function oa(t){return{inputFiles:t.inputFile,inputFormat:t.inputFormat,outputDir:t.outputDir,framework:t.framework,frameworkVersion:t.frameworkVersion,debug:t.debug}}var Co=l(require("fs-extra")),L=require("path");var ca=require("lodash"),pa=l(require("crypto"));var H=require("path"),Je=async(t,e,r,o)=>{if(t)for(let n of t)try{let s=(0,H.resolve)(o,n.path),i=(0,H.relative)(o,s);if(i.startsWith("..")||(0,H.isAbsolute)(i)){p("Skipping artifact outside workspace: %s (resolved: %s)",n.path,s);continue}let c=`${et(e+n.path)}.${(0,H.extname)(n.path).slice(1)||"bin"}`;await ce(s,(0,H.join)(r,c)),n.path=(0,H.join)("artifacts",c)}catch(s){p("Failed to copy artifact %s: %o",n.path,s)}};function sa(t){let e=aa(t.properties?.property??t.property);return He(e,"currents.artifact.instance.","spec")}function ia(t){let e=aa(t.properties?.property),r=He(e,"currents.artifact.test.","test"),o=new Map;Um(e).forEach((i,c)=>{o.has(c)||o.set(c,[]),o.get(c).push(...i)});let s=He(e,"currents.artifact.attempt.","attempt");return s.length>0&&(o.has(0)||o.set(0,[]),o.get(0).push(...s)),{testArtifacts:r,attemptArtifacts:o}}function Um(t){let e=new Map,r=/^currents\.artifact\.attempt\.(\d+)\.(.+)$/,o=new Map;for(let n of t){let s=n.value??n._;if(!n.name||!s)continue;let i=n.name.match(r);if(!i)continue;let[,c,m]=i,d=parseInt(c,10);o.has(d)||o.set(d,[]),o.get(d).push({name:`currents.artifact.attempt.${m}`,value:s})}for(let[n,s]of o.entries()){let i=He(s,"currents.artifact.attempt.","attempt");i.length>0&&e.set(n,i)}return e}function He(t,e,r){let o=[],n={};for(let s of t){let i=s.value??s._;if(!s.name||!i||!s.name.startsWith(e))continue;let c=s.name.slice(e.length);/^\d+\./.test(c)||["path","type","contentType","name"].includes(c)&&(n[c]&&(na(n)&&o.push({...n,level:r}),n={}),n[c]=i)}return na(n)&&o.push({...n,level:r}),o}function na(t){return!!(t.path&&t.type&&t.contentType)}function aa(t){return t?Array.isArray(t)?t:[t]:[]}function da(t,e,r,o){let n=Rt(t.failure),s=n.length>0,i=e?.timestamp??"",c="skipped"in t,m=c?"pending":s?"failed":"passed",{testArtifacts:d,attemptArtifacts:f}=ia(t);return{_t:Ve(i),testId:go(ee(t.name,o).join(", "),o),title:ee(t.name,o),state:m,isFlaky:Dm(),expectedStatus:"passed",timeout:Pm(),location:bm(e?.file??""),retries:Nm(n),artifacts:d,attempts:Lm(t,n,ho(i),r,f,c)}}function go(t,e){let r=`${t}${e}`;return pa.default.createHash("sha256").update(r).digest("hex").substring(0,16)}function Ve(t){return ma(t)?new Date(t).getTime():new Date().getTime()}function ho(t){return ma(t)?new Date(t).toISOString():new Date().toISOString()}function ma(t){let e=new Date(t);return!isNaN(e.getTime())}function ee(t,e){return[e,t].filter(Boolean)}function Dm(){return!1}function Pm(){return 0}function bm(t){return{column:1,file:t,line:1}}function Nm(t){let e=0;return t.forEach(r=>{typeof r!="string"&&e++}),e}function Lm(t,e,r,o,n,s){let i=t.time?Ye(t.time):0;if(s)return[{_s:"pending",attempt:0,startTime:r,steps:[],duration:i,status:"skipped",stdout:uo(t?.["system-out"]),stderr:lo(t?.["system-err"]),artifacts:n.get(0),errors:[],error:void 0}];if(e.length===0){let c=[];return n.forEach(m=>{c.push(...m)}),[{_s:"passed",attempt:0,startTime:r,steps:[],duration:i,status:"passed",stdout:uo(t?.["system-out"]),stderr:lo(t?.["system-err"]),artifacts:c,errors:[],error:void 0}]}return e.reduce((c,m,d)=>{if(m!=="true"&&m!=="false"){let f=vm(m);c.push({_s:"failed",attempt:d,startTime:Bm(o,r),steps:[],duration:i,status:"failed",stdout:uo(t?.["system-out"]),stderr:lo(t?.["system-err"]),artifacts:n.get(d),errors:f,error:f[0]})}return c},[])}function uo(t){return t?[t]:[]}function lo(t){return t?[t]:[]}function vm(t){return t==="true"||t==="false"?[]:[typeof t=="string"?{message:t}:{message:t.message,stack:t._,value:t.type}]}function Bm(t,e){let r=Ve(e)+t;return new Date(r).toISOString()}function Rt(t){return t?Array.isArray(t)?t:[t]:[]}function Mm(t){return Math.round(t*1e3)}function Ye(t){let e=parseFloat(t);return isNaN(e)?0:Mm(e)}function We(t,e,r){let o=(0,ca.isNumber)(r)&&r>0,n=!!t.id&&fo(e,"id",t.id);if(t.file){let s=fo(e,"file",t.file);return s&&!n?`${t.file} - ${t.id}`:s&&o?`${t.file} - ${r}`:t.file}if(t.name){let s=fo(e,"name",t.name);return s&&!n?`${t.name} - ${t.id}`:s&&o?`${t.name} - ${r}`:t.name}return t.id?n&&o?`${t.id} - ${r}`:t.id:o?`unknown - ${r}`:"unknown"}function fo(t,e,r){return t.filter(n=>n[e]===r).length>1}function ua(t){let e=[];return t.forEach(r=>{let o=Rt(r.testsuites?.testsuite),n={name:r.testsuites?.name??"No name",tags:[],tests:[]};o?.forEach(s=>{let i=We(s,o);Rt(s?.testcase)?.forEach(m=>{let d={title:ee(m.name,i),spec:i,tags:[],testId:go(ee(m.name,i).join(", "),i)};n.tests.push(d)})}),e.push(n)}),e}var lt=require("@commander-js/extra-typings"),la=l(require("globby")),Eo=(e=>(e.junit="junit",e))(Eo||{}),qe=t=>new lt.Option("--input-format <format>",["the format of the reports to convert",t].filter(Boolean).join(" ")).choices(Object.values(Eo)),ze=t=>new lt.Option("--input-file <patterns>",`comma-separated glob patterns of the report files, e.g. "reports/*.xml,other.xml"; quote them so that the shell does not expand them ${t}`).argParser(Fm),Qe=new lt.Option("-o, --output-dir <folder>","the folder to save the converted reports to; it must be empty, not exist, or hold only the reports being converted"),Io=(n=>(n.postman="postman",n.node="node",n.vitest="vitest",n.wdio="wdio",n))(Io||{}),Xe=t=>new lt.Option("--framework <framework>",`the test framework that wrote the reports ${t}`).choices(Object.values(Io)),Ze=new lt.Option("--framework-version <version>","the version of the test framework that wrote the reports");function Fm(t){let e=t.split(",").map(o=>o.trim()),r=la.sync(e);if(r.length===0)throw new lt.InvalidArgumentError("No files found with the provided patterns");return r}async function J(t){let e=new Map;return t.forEach(r=>{let o=Rt(r.testsuites?.testsuite),n=r.testsuites?.name??"No name";o.forEach((s,i)=>{let c=We(s,o,i),m=km(s,n,c),d=et(n+c);m.results.tests.length!==0&&e.set(d,m)})}),e}function km(t,e,r){let o=ho(t.timestamp??""),n=t.time?Ye(t.time):0,s=new Date(Ve(t.timestamp??"")+n),i=Rt(t.testcase),c=[t["system-out"],t["system-err"],...i.flatMap(g=>[g["system-out"],g["system-err"]])].filter(g=>g).join(`
36
+ `),m=0,d=i.filter(g=>"failure"in g).length,f=i.filter(g=>"skipped"in g).length,u=i.length-d-f;return{groupId:e,spec:r,startTime:o,artifacts:sa(t),_stdout:c,results:{stats:{suites:1,tests:i.length,passes:u,pending:f,skipped:0,failures:d,flaky:0,wallClockStartedAt:o,wallClockEndedAt:s.toISOString(),wallClockDuration:n},tests:i?.map(g=>(i[0]?.time&&(m+=Ye(i[0].time)),da(g,t,m,r)))}}}async function fa({inputFormat:t,framework:e,parsedXMLArray:r}){return t==="junit"?Gm(e,r):new Map}async function Gm(t,e){switch(t){case"node":return J(e);case"postman":return J(e);case"vitest":return J(e);case"wdio":return J(e);default:return E("Unsupported framework: %s",t),new Map}}var ga=require("fs-extra"),ha=require("xml2js");async function Ea(t){let e=await Promise.all(t.map(o=>(0,ga.readFile)(o,"utf-8"))),r=(await Promise.all(e.map(jm))).filter(Boolean);return e.length!==r.length&&E("Some files could not be parsed. Enable debug logging for more details"),r}async function jm(t){let e=t.trim();if(!e)return null;try{return await(0,ha.parseStringPromise)(e,{explicitArray:!1,mergeAttrs:!0})||null}catch(r){return p("Error parsing XML input",r),null}}function Ia(t){return{framework:t.inputFormat,frameworkVersion:t.frameworkVersion??null,frameworkConfig:{originFramework:t.framework,originFrameworkVersion:t.frameworkVersion}}}async function Ca(){try{let t=Ke();if(!t)throw new Error("Config is missing!");t.outputDir&&await $m(t.outputDir,t.inputFiles);let e=t.outputDir?await It(t.outputDir):await Vo(process.cwd(),".currents"),r=await It((0,L.join)(e,"instances")),o=Ia(t);p("Report config:",o),T("[currents] Convertion files: %s",t.inputFiles.join(", ")),await Jt((0,L.join)(e,"config.json"),JSON.stringify(o));let n=await Ea(t.inputFiles);if(n.length===0)throw new Error("No valid XML JUnit report was found.");let s=ua(n);await Jt(Tt(e),JSON.stringify(s));let i=await fa({inputFormat:t.inputFormat,framework:t.framework,parsedXMLArray:n}),c=await It((0,L.join)(e,"artifacts")),m=process.cwd();return await Promise.all(Array.from(i.values()).map(async d=>{if(await Je(d.artifacts,d.spec,c,m),d._stdout){let f=`${et(d.spec)}.stdout.txt`;await Jt((0,L.join)(c,f),d._stdout),d.artifacts||(d.artifacts=[]),d.artifacts.push({path:(0,L.join)("artifacts",f),type:"stdout",contentType:"text/plain",level:"spec"}),delete d._stdout}for(let f of d.results.tests){await Je(f.artifacts,f.testId,c,m);for(let u of f.attempts)await Je(u.artifacts,f.testId+u.attempt,c,m)}})),await Promise.all(Array.from(i.entries()).map(([d,f])=>Jt((0,L.join)(r,`${et(d)}.json`),JSON.stringify(f)))),T("[currents] Conversion completed, report saved to: %s",e),e}catch(t){throw p("Failed to convert: %o",t),t}}async function $m(t,e){let r=(0,L.resolve)(t),o=new Set(e.map(c=>(0,L.resolve)(c))),n=[(0,L.join)(r,"config.json"),Tt(r),(0,L.join)(r,"instances"),(0,L.join)(r,"artifacts")],s=[...o].find(c=>n.some(m=>c===m||c.startsWith(m+L.sep)));if(s)throw new Error(`The report "${s}" is where the conversion writes its own files. Move the reports out of "${t}", or leave out --output-dir to convert into a new folder in .currents.`);if(await Co.default.pathExists(r)?await Ta(r,o):void 0)throw new Error(`The folder "${t}" is not empty. Reports already in it would be uploaded with the converted ones. Remove the folder, or leave out --output-dir to convert into a new folder in .currents.`)}async function Ta(t,e){for(let r of await Co.default.readdir(t,{withFileTypes:!0})){let o=(0,L.join)(t,r.name),n=r.isDirectory()?await Ta(o,e):e.has(o)?void 0:o;if(n)return n}}var Km=p.extend("cli");async function To(t){return ra(oa(t)),Km("Config: %o",Ke()),Ca()}async function ya(t){await w(async e=>{await To(e)},t)}var yo="convert",Hm=t=>[{comment:"Convert JUnit test reports to the Currents format, to check the result before an upload",commands:[`${t} ${yo} --input-format junit --input-file "./*.xml" --framework postman`]}],_a=t=>new Ra.Command().name(yo).command(yo).showHelpAfterError("(add --help for additional information)").allowUnknownOption().summary("Convert JUnit XML reports to the Currents format").description("Convert JUnit XML reports to the Currents format, without uploading them. The converted reports are saved to --output-dir or a new folder in .currents").addHelpText("after",y(Hm(t))).addOption(P()).addOption(qe("(required)")).addOption(ze("(required)")).addOption(Qe).addOption(Xe("(required)")).addOption(Ze).action(r=>ya(r));var No=require("@commander-js/extra-typings");var{apiKey:Jm,recordKey:Vm,projectId:Ym,ciBuildId:Wm,machineId:qm,debug:zm}=_,F={apiKey:Jm,recordKey:Vm,projectId:Ym,ciBuildId:Wm,machineId:qm,sessionId:{name:"Session ID",env:"CURRENTS_SESSION_ID",cli:"--session-id"},title:{name:"Title",cli:"--title"},debug:zm};var tr=p.extend("config");function wa(t){let e=U(F,["apiKey","projectId","title"],t);return tr("Resolved config: %o",h(e)),e}function Oa(t){let e=U(F,["apiKey"],t);return tr("Resolved config: %o",h(e)),e}function xa(t){let e=U(F,["apiKey"],t);return tr("Resolved config: %o",h(e)),e}function Aa(t){let e=U(F,["projectId"],t,Qm);return tr("Resolved config: %o",h(e)),e}function Qm(t){if(!(t.recordKey||t.apiKey))throw new W(`${F.recordKey.name} or ${F.apiKey.name} is required. Set ${F.recordKey.env} or ${F.apiKey.env}, or pass ${F.recordKey.cli} or ${F.apiKey.cli}`)}var Mt=l(require("fs-extra")),rr=l(require("path"));var Ua=l(require("path"));var Sa=["trace","screenshot","video","attachment"];var Xm=["image/png","image/jpeg","image/webp","image/gif"],Da=t=>Ua.default.extname(t).toLowerCase()===".zip";function Pa(t){return Sa.includes(t)}function Ro(t){return Da(t)?"application/zip":qr(t)?.contentType??"application/octet-stream"}function Zm(t){return Da(t)?"trace":qr(t)?.type??"attachment"}function _o(t,e){let r=Zm(t);return e.includes(r)?r:"attachment"}function ba(t,e,r){if(!r.includes(e))throw new Error(`Cannot attach "${t}" as type "${e}" here. The target takes: ${r.join(", ")}`)}function Na(t,e){let r=Ro(t);if(!(e==="attachment"||e==="trace"&&r==="application/zip"||e==="screenshot"&&Xm.includes(r)||e==="video"&&r.startsWith("video/")))throw new Error(`Cannot attach "${t}" as type "${e}": its content type is ${r}`)}var La=l(require("archiver")),_t=l(require("fs-extra")),er=l(require("path")),va=l(require("unzipper")),Ba=require("tmp-promise");async function Ma(t){try{return(await va.default.Open.file(t)).files.some(r=>r.path==="trace.trace")}catch{return!1}}var Fa=/^trace-.*\.trace$/,tu=/^trace-.*\.network$/;async function wo(t){return(await _t.default.readdir(t)).some(r=>Fa.test(r))}function eu(t){if(!t)return!1;try{let e=JSON.parse(t),r=e.snapshot?.response;if(e.type!=="resource-snapshot"||!r)return!0;let o=r.status>=200&&r.status<400,n=/javascript|ecmascript/i.test(r.content?.mimeType??"");return!(o&&n)}catch{return!0}}async function ka(t,e){return(await _t.default.readdir(t)).filter(o=>e.test(o)).sort().map(o=>er.default.join(t,o))}async function ru(t){return(await Promise.all((await ka(t,Fa)).map(r=>_t.default.readFile(r,"utf8")))).map(r=>r.endsWith(`
37
37
  `)?r:r+`
38
- `).join("")}async function qm(t){let e=await La(t,Jm),r=[];for(let o of e)r.push(...(await _t.default.readFile(o,"utf8")).split(`
39
- `));return r.filter(Ym).join(`
40
- `)}async function Ba(t){let{path:e,cleanup:r}=await(0,Pa.dir)({unsafeCleanup:!0}),o=Ze.default.join(e,"trace.zip");try{let n=(0,Ua.default)("zip",{zlib:{level:9}}),s=_t.default.createWriteStream(o),i=new Promise((c,m)=>{s.on("close",()=>c()),s.on("error",m),n.on("error",m)});n.pipe(s),n.append(await Wm(t),{name:"trace.trace"}),n.append(await qm(t),{name:"trace.network"});for(let c of["screencast","resources"]){let m=Ze.default.join(t,c);await _t.default.pathExists(m)&&n.directory(m,c)}await n.finalize(),await i}catch(n){throw await r(),n}return{zipPath:o,cleanup:r}}var zm=1024**3,va=/^\.env($|[._-])|^\.envrc$|\.env$/i,Qm=/\.(pem|key)$|^id_(rsa|ed25519|ecdsa|dsa)/i;function Xm(t){if(va.test(t))throw new Error(`"${t}" looks like an environment file with secrets and is not attached`)}async function Ro(t,e,r){Xm(e);let o=r.type??To(e,r.allowedTypes);r.type?(Sa(e,r.type),Aa(e,r.type,r.allowedTypes)):o==="trace"&&!await ba(t)&&(o="attachment");let n=await Mt.default.stat(t);if(n.size>zm)throw new Error(`"${e}" is larger than 1 GiB`);if(n.size===0)throw new Error(`"${e}" is empty`);return{path:t,name:e,type:o,contentType:Co(e),sizeBytes:n.size}}async function Zm(t,e,r){let o=[];for(let n of await Mt.default.readdir(t,{withFileTypes:!0})){let s=tr.default.join(t,n.name);if(n.name.startsWith("."))E(`Skipping the hidden file "${s}"`);else if(Qm.test(n.name)||va.test(n.name))E(`Skipping "${s}", which looks like a key or secrets file`);else if(n.isSymbolicLink())E(`Skipping the link "${s}"`);else if(n.isDirectory()){if(s===r)continue;E(`Skipping the folder "${s}"`)}else if(n.isFile()){if((await Mt.default.stat(s)).size===0){E(`Skipping the empty file "${s}"`);continue}o.push(await Ro(s,n.name,e))}}return o}async function Ma(t,e){let r=[],o=[],n=async()=>{await Promise.all(o.map(i=>i()))},s=async i=>{let c=await Ba(i);o.push(c.cleanup),r.push(await Ro(c.zipPath,`trace-${Cr(8)}.zip`,{...e,type:e.type??To("trace.zip",e.allowedTypes)}))};try{for(let i of t){let c=await Mt.default.stat(i).catch(()=>null);if(!c)throw new Error(`"${i}" does not exist`);if(!c.isDirectory()){r.push(await Ro(i,tr.default.basename(i),e));continue}if(await yo(i)){await s(i);continue}let m=tr.default.join(i,"traces"),d;await Mt.default.pathExists(m)&&await yo(m)&&(await s(m),d=m),r.push(...await Zm(i,e,d))}}catch(i){throw await n(),i}if(r.length===0)throw new Error("There are no files to attach");return{files:r,cleanup:n}}var Fa={run:["attachment"],instance:["attachment","video","screenshot"],test:["attachment"],attempt:["attachment","video","screenshot","trace"]},ka=["attachment","video","screenshot","trace"];function Ga(t){return t.testId||t.testTitle?t.attempt===void 0?"test":"attempt":t.instanceId||t.spec?"instance":"run"}var $a=4;async function Ka(t){let e=[];for(let r=0;r<t.length;r+=$a)e.push(...await Promise.all(t.slice(r,r+$a).map(async({file:o,uploadUrl:n,uploadHeaders:s})=>{try{return await ms({name:o.name,path:o.path,sizeBytes:o.sizeBytes,uploadUrl:n,contentType:o.contentType,headers:s}),{file:o}}catch(i){return{file:o,error:i}}})));return e}var tu=p.extend("files");function eu(t=[]){let e=new Map;for(let r of t){let o=r.indexOf("=");if(o<1)throw new Error(`--meta expects key=value, got "${r}"`);let n=r.slice(0,o);if(!/^[A-Za-z0-9_-]{1,64}$/.test(n))throw new Error(`--meta key "${n}" can only hold up to 64 letters, digits, "_" and "-"`);let s=r.slice(o+1);if(s.length>256)throw new Error(`--meta value of "${n}" is longer than 256 characters`);e.set(n,s)}return e.size>0?Object.fromEntries(e):void 0}function ru(t){if(t!==void 0){if(!xa(t))throw new Error(`--type must be one of trace, screenshot, video, attachment, got "${t}"`);return t}}var ou=50,nu=100*1024**2,Ha=200;function su(t,e={count:ou,bytes:nu}){let r=[],o=0;for(let n of t){let s=r[r.length-1];!s||s.length>=e.count||o+n.sizeBytes>e.bytes?(r.push([n]),o=n.sizeBytes):(s.push(n),o+=n.sizeBytes)}return r}async function _o(t){if(!t.credentials.apiKey&&!t.credentials.recordKey)throw new Error("Pass an API key or a record key");let e=ru(t.type),r=eu(t.meta),o=t.target??{},n="sessionId"in t.owner?ka:Fa[Ga(o)],{files:s,cleanup:i}=await Ma(t.paths,{type:e,allowedTypes:n});s.length>Ha&&E(`Attaching ${s.length} files. An instance takes up to ${Ha} files through the API, so the rest may be refused`);let c=[],m=[];try{for(let d of su(s)){let f=d.map(g=>({name:g.name,type:g.type,contentType:g.contentType,sizeBytes:g.sizeBytes,caption:t.caption,meta:r})),u;try{u=await On(t.credentials,t.owner,o,f)}catch(g){throw new Error(`${g.message}
41
- ${c.length} of ${s.length} files were attached before this`)}if(tu("Created %d attachments at level %s",u.attachments.length,u.level??"session"),u.attachments.length!==d.length)throw new Error(`The API returned ${u.attachments.length} upload URLs for ${d.length} files`);let I=await Ka(d.map((g,S)=>{if(u.attachments[S].name!==g.name)throw new Error(`The API answered "${u.attachments[S].name}" where "${g.name}" was declared`);let{uploadUrl:J,uploadHeaders:Ot}=u.attachments[S];return{file:g,uploadUrl:J,uploadHeaders:Ot}}));for(let g of I)g.error?(C("Failed %s: %s",g.file.name,g.error.message),m.push(g)):(T("Attached %s (%s)",g.file.name,g.file.type),c.push(g.file))}}finally{await i().catch(d=>E("Could not remove temporary files: %s",d.message))}if(m.length>0)throw new Error(`${m.length} of ${s.length} files could not be uploaded`);return{files:c.map(({name:d,type:f,sizeBytes:u})=>({name:d,type:f,sizeBytes:u}))}}var wt=l(require("fs-extra")),re=l(require("path")),iu=".currents-session",ja=()=>re.default.join(process.cwd(),iu,"session.json");async function au(t){let e=re.default.join(t,".gitignore");await wt.default.pathExists(e)||await wt.default.writeFile(e,`*
42
- `)}async function Va(t){let e=ja();await wt.default.ensureDir(re.default.dirname(e)),await au(re.default.dirname(e)),await wt.default.writeJson(e,t,{spaces:2})}async function cu(){let t=ja();if(!await wt.default.pathExists(t))return null;let e=await wt.default.readJson(t),r=e?.sessionId||e?.runId;if(typeof r!="string"||!r.trim())return null;let o=typeof e.projectId=="string"?e.projectId:void 0;return{sessionId:r,projectId:o}}async function wo(t){if(t)return t;let e=await cu();if(!e)throw new Error('No session found. Run "currents session start" first, or pass --session-id');return e.sessionId}var pu=p.extend("session");async function du(){try{let{sha:t,branch:e,message:r,authorName:o,authorEmail:n,remoteOrigin:s}=await Oe();return{sha:t,branch:e,message:r,authorName:o,authorEmail:n,remoteOrigin:s}}catch(t){pu("No git info: %o",t);return}}function mu(t){if(t)return/^\d+$/.test(t)?{id:t}:{link:t}}function Ja(){let{provider:t,params:e}=rt();return{provider:t,params:e}}function uu(){if(rt().ciBuildId.source!=="server")throw new Error("The CI build ID is unknown. Pass --ci-build-id or set CURRENTS_CI_BUILD_ID to the value the run was recorded with")}async function Ya(t){let e=await wn(t.apiKey,{projectId:t.projectId,title:t.title,status:t.status,error:t.error,tags:t.tag,commit:await du(),ci:Ja(),pr:mu(t.pr)});return await Va({sessionId:e.sessionId,projectId:t.projectId}),t.json?process.stdout.write(JSON.stringify({sessionId:e.sessionId})+`
43
- `):T("Session started: %s",e.sessionId),e}async function Wa(t,e){let r=await wo(t.sessionId);return _o({credentials:{apiKey:t.apiKey},owner:{sessionId:r},paths:e,type:t.type,caption:t.caption,meta:t.meta})}async function qa(t){let e=await wo(t.sessionId),r=await xn(t.apiKey,{sessionId:e,purpose:"report",expiresInDays:t.expiresInDays});return T(r.pageUrl),T("Markdown: %s",r.url),r}async function za(t,e){if(t.testTitle&&!t.spec)throw new Error("--test-title needs --spec, the spec file of the test");if(t.attempt!==void 0&&!t.testTitle)throw new Error("--attempt needs --test-title");if(t.group&&!t.spec)throw new Error("--group needs --spec: it picks the spec file of a group");return t.ciBuildId||uu(),_o({credentials:{apiKey:t.apiKey,recordKey:t.recordKey},owner:t.ciBuildId?{projectId:t.projectId,ciBuildId:t.ciBuildId}:{projectId:t.projectId,ci:Ja()},target:{spec:t.spec,testTitle:t.testTitle,groupId:t.group,attempt:t.attempt,machineId:t.spec?void 0:t.machineId},paths:e,type:t.type,caption:t.caption,meta:t.meta})}var A=require("@commander-js/extra-typings");var Qa=t=>N(F,t),er="(required; needs write access)",Xa=Nt(". Leave it out only if the run was recorded without one, on a CI the reporters recognize"),Za=new A.Option("--machine-id <id>","the CI machine the files come from; run-level files are listed by machine when it is set").env(Qa("machineId")),xo=new A.Option("--session-id <id>",'the session to use instead of the one saved by "session start"').env(Qa("sessionId")),tc=new A.Option("--title <text>","what the session shows, used as the session title (required)"),ec=new A.Option("--status <status>","the result of the session").choices(["passed","failed"]).default("passed"),rc=new A.Option("--error <text>","what went wrong, for a failed session"),oc=Lt("tags to add to the session"),nc=new A.Option("--pr <url|number>","the pull request the session is about; by default taken from the CI environment"),sc=new A.Option("--json",'print the session ID as JSON on stdout, e.g. {"sessionId": "..."}'),ic=new A.Option("--spec <spec>","attach to this spec file of the run"),ac=new A.Option("--test-title <title>",'attach to this test of --spec: the full title joined with " > ", or its last part'),cc=new A.Option("--group <id>","the group of the spec file; a spec that runs once per Playwright project matches more than once without it"),pc=new A.Option("--attempt <n>","attach to this attempt of the test; the first attempt is 0").argParser(t=>{let e=Number(t);if(!Number.isInteger(e)||e<0)throw new Error("--attempt must be a whole number from 0");return e}),dc=["trace","screenshot","video","attachment"],mc="by default taken from the file: a .zip holding trace.trace is a trace; .png, .jpg, .jpeg, .webp and .gif are screenshots; .webm and .mp4 are videos; anything else is an attachment",uc=new A.Option("--type <type>",`the type of every file; ${mc}`).choices(dc),lc=new A.Option("--type <type>",`the type of every file; ${mc}. The whole run and a test take attachments only, a spec file also takes screenshots and videos, and an attempt (--attempt) takes all four types, including traces. A file of a type its target does not take is attached as an attachment, and a --type the target does not take is an error`).choices(dc),rr="files or folders to attach. A folder adds the files directly in it; hidden files, links, subfolders and empty files in it are skipped. A folder of Playwright MCP trace-*.trace files is packed into one trace and nothing else in it is attached; a folder with such a traces/ subfolder adds the packed trace and its own files. Files named .env or .env.* are refused, and each file can be at most 1 GiB",or=new A.Option("--caption <text>","a short description shown with each file"),lu=(t,e=[])=>[...e,t],nr=new A.Option("--meta <key=value>","a label for each file; repeat for more").argParser(lu),Oo=["1","3","7"],fc=new A.Option("--expires-in-days <days>","the number of days the link works").choices(Oo).default(7).argParser(t=>{if(!Oo.includes(t))throw new A.InvalidArgumentError(`Allowed choices are ${Oo.join(", ")}.`);return Number(t)});var xc=require("@commander-js/extra-typings");var Ft=require("@commander-js/extra-typings");var gc=new Ft.Option("--ci-build-id <id>","the CI build ID to record the run with; by default taken from the CI environment, or a random value").env(N(nt,"ciBuildId")),hc=Lt("tags to add to the run").env(N(nt,"tag")),Ec=new Ft.Option("--remove-title-tags","remove tags from test names in Currents, e.g. `Test name @smoke` becomes `Test name` in the dashboard").env(N(nt,"removeTitleTags")).default(!1),Ic=new Ft.Option("--disable-title-tags","do not read tags from test names, e.g. `Test name @smoke` is not tagged with `smoke` in the dashboard").env(N(nt,"disableTitleTags")).default(!1),Cc=new Ft.Option("--machine-id <id>","the ID of the machine that ran the tests; by default a random value").env(N(nt,"machineId")),Tc=new Ft.Option("--report-dir <folder>","the folder of the reports to upload; by default the newest folder in .currents").env(N(nt,"reportDir"));var So=require("path");var _c=l(require("fs"));var yc=require("tmp-promise"),Rc=async()=>{let{path:t}=await(0,yc.file)();return t};var Ao=p.extend("cli"),sr=class{constructor(e){this.configFilePath=null;this.cliOptions=e,Ao("CLI options: %o",h(this.cliOptions)),this.parsedConfig=vs(this.cliOptions),Ao("Parsed config from CLI options: %o",h(this.parsedConfig))}async getConfigFilePath(){if(this.configFilePath)return this.configFilePath;let e=await Rc();return _c.default.writeFileSync(e,JSON.stringify(this.parsedConfig)),Ao("CLI options temp file path: %s",e),this.configFilePath=e,e}};async function wc(t){await w(async e=>{let r=e.inputFormat?await fu(e):e.reportDir,o=new sr({...e,reportDir:r});Bs(o.parsedConfig);let n=xe();T("Currents config: %o",h(n)),await to()},t)}async function fu({inputFormat:t,inputFile:e,framework:r,frameworkVersion:o,outputDir:n,reportDir:s,debug:i}){if(n&&s&&(0,So.resolve)(n)!==(0,So.resolve)(s))throw new Error("--output-dir and --report-dir name different folders. With --input-format, the converted reports are saved to one folder and uploaded from it: pass one of the two options.");return Eo({inputFormat:t,inputFile:e,framework:r,frameworkVersion:o,outputDir:n??s,debug:i})}var kt="upload",Oc="(required with --input-format)",ir="run",Gt=t=>[{comment:"Upload test results to Currents",commands:[`${t} ${ir} ${kt} --key <record-key> --project-id <id> --ci-build-id <build-id>`]},{comment:"Convert JUnit XML reports to the Currents format, then upload them",commands:[`${t} ${ir} ${kt} --key <record-key> --project-id <id> --ci-build-id <build-id> --input-format junit --input-file "./*.xml" --framework postman`]},{comment:'Upload test results and add the tags "tagA" and "tagB" to the run',commands:[`${t} ${ir} ${kt} --key <record-key> --project-id <id> --ci-build-id <build-id> --tag tagA --tag tagB`]},{comment:"Upload test results from another folder",commands:[`${t} ${ir} ${kt} --key <record-key> --project-id <id> --ci-build-id <build-id> --report-dir <report-dir>`]}],ar=t=>new xc.Command().name(kt).command(kt).showHelpAfterError("(add --help for additional information)").allowUnknownOption().summary("Upload test results of Currents reporters or JUnit").description(`Upload test results created by Currents reporters to https://currents.dev
38
+ `).join("")}async function ou(t){let e=await ka(t,tu),r=[];for(let o of e)r.push(...(await _t.default.readFile(o,"utf8")).split(`
39
+ `));return r.filter(eu).join(`
40
+ `)}async function Ga(t){let{path:e,cleanup:r}=await(0,Ba.dir)({unsafeCleanup:!0}),o=er.default.join(e,"trace.zip");try{let n=(0,La.default)("zip",{zlib:{level:9}}),s=_t.default.createWriteStream(o),i=new Promise((c,m)=>{s.on("close",()=>c()),s.on("error",m),n.on("error",m)});n.pipe(s),n.append(await ru(t),{name:"trace.trace"}),n.append(await ou(t),{name:"trace.network"});for(let c of["screencast","resources"]){let m=er.default.join(t,c);await _t.default.pathExists(m)&&n.directory(m,c)}await n.finalize(),await i}catch(n){throw await r(),n}return{zipPath:o,cleanup:r}}var nu=1024**3,ja=/^\.env($|[._-])|^\.envrc$|\.env$/i,su=/\.(pem|key)$|^id_(rsa|ed25519|ecdsa|dsa)/i;function iu(t){if(ja.test(t))throw new Error(`"${t}" looks like an environment file with secrets and is not attached`)}async function Oo(t,e,r){iu(e);let o=r.type??_o(e,r.allowedTypes);r.type?(Na(e,r.type),ba(e,r.type,r.allowedTypes)):o==="trace"&&!await Ma(t)&&(o="attachment");let n=await Mt.default.stat(t);if(n.size>nu)throw new Error(`"${e}" is larger than 1 GiB`);if(n.size===0)throw new Error(`"${e}" is empty`);return{path:t,name:e,type:o,contentType:Ro(e),sizeBytes:n.size}}async function au(t,e,r){let o=[];for(let n of await Mt.default.readdir(t,{withFileTypes:!0})){let s=rr.default.join(t,n.name);if(n.name.startsWith("."))E(`Skipping the hidden file "${s}"`);else if(su.test(n.name)||ja.test(n.name))E(`Skipping "${s}", which looks like a key or secrets file`);else if(n.isSymbolicLink())E(`Skipping the link "${s}"`);else if(n.isDirectory()){if(s===r)continue;E(`Skipping the folder "${s}"`)}else if(n.isFile()){if((await Mt.default.stat(s)).size===0){E(`Skipping the empty file "${s}"`);continue}o.push(await Oo(s,n.name,e))}}return o}async function $a(t,e){let r=[],o=[],n=async()=>{await Promise.all(o.map(i=>i()))},s=async i=>{let c=await Ga(i);o.push(c.cleanup),r.push(await Oo(c.zipPath,`trace-${yr(8)}.zip`,{...e,type:e.type??_o("trace.zip",e.allowedTypes)}))};try{for(let i of t){let c=await Mt.default.stat(i).catch(()=>null);if(!c)throw new Error(`"${i}" does not exist`);if(!c.isDirectory()){r.push(await Oo(i,rr.default.basename(i),e));continue}if(await wo(i)){await s(i);continue}let m=rr.default.join(i,"traces"),d;await Mt.default.pathExists(m)&&await wo(m)&&(await s(m),d=m),r.push(...await au(i,e,d))}}catch(i){throw await n(),i}if(r.length===0)throw new Error("There are no files to attach");return{files:r,cleanup:n}}var Ka={run:["attachment"],instance:["attachment","video","screenshot"],test:["attachment"],attempt:["attachment","video","screenshot","trace"]},Ha=["attachment","video","screenshot","trace"];function Ja(t){return t.testId||t.testTitle?t.attempt===void 0?"test":"attempt":t.instanceId||t.spec?"instance":"run"}var Va=4;async function Ya(t){let e=[];for(let r=0;r<t.length;r+=Va)e.push(...await Promise.all(t.slice(r,r+Va).map(async({file:o,uploadUrl:n,uploadHeaders:s})=>{try{return await fs({name:o.name,path:o.path,sizeBytes:o.sizeBytes,uploadUrl:n,contentType:o.contentType,headers:s}),{file:o}}catch(i){return{file:o,error:i}}})));return e}var cu=p.extend("files");function pu(t=[]){let e=new Map;for(let r of t){let o=r.indexOf("=");if(o<1)throw new Error(`--meta expects key=value, got "${r}"`);let n=r.slice(0,o);if(!/^[A-Za-z0-9_-]{1,64}$/.test(n))throw new Error(`--meta key "${n}" can only hold up to 64 letters, digits, "_" and "-"`);let s=r.slice(o+1);if(s.length>256)throw new Error(`--meta value of "${n}" is longer than 256 characters`);e.set(n,s)}return e.size>0?Object.fromEntries(e):void 0}function du(t){if(t!==void 0){if(!Pa(t))throw new Error(`--type must be one of trace, screenshot, video, attachment, got "${t}"`);return t}}var mu=50,uu=100*1024**2,Wa=200;function lu(t,e={count:mu,bytes:uu}){let r=[],o=0;for(let n of t){let s=r[r.length-1];!s||s.length>=e.count||o+n.sizeBytes>e.bytes?(r.push([n]),o=n.sizeBytes):(s.push(n),o+=n.sizeBytes)}return r}async function xo(t){if(!t.credentials.apiKey&&!t.credentials.recordKey)throw new Error("Pass an API key or a record key");let e=du(t.type),r=pu(t.meta),o=t.target??{},n="sessionId"in t.owner?Ha:Ka[Ja(o)],{files:s,cleanup:i}=await $a(t.paths,{type:e,allowedTypes:n});s.length>Wa&&E(`Attaching ${s.length} files. An instance takes up to ${Wa} files through the API, so the rest may be refused`);let c=[],m=[];try{for(let d of lu(s)){let f=d.map(g=>({name:g.name,type:g.type,contentType:g.contentType,sizeBytes:g.sizeBytes,caption:t.caption,meta:r})),u;try{u=await Sn(t.credentials,t.owner,o,f)}catch(g){throw new Error(`${g.message}
41
+ ${c.length} of ${s.length} files were attached before this`)}if(cu("Created %d attachments at level %s",u.attachments.length,u.level??"session"),u.attachments.length!==d.length)throw new Error(`The API returned ${u.attachments.length} upload URLs for ${d.length} files`);let I=await Ya(d.map((g,S)=>{if(u.attachments[S].name!==g.name)throw new Error(`The API answered "${u.attachments[S].name}" where "${g.name}" was declared`);let{uploadUrl:V,uploadHeaders:Ot}=u.attachments[S];return{file:g,uploadUrl:V,uploadHeaders:Ot}}));for(let g of I)g.error?(C("Failed %s: %s",g.file.name,g.error.message),m.push(g)):(T("Attached %s (%s)",g.file.name,g.file.type),c.push(g.file))}}finally{await i().catch(d=>E("Could not remove temporary files: %s",d.message))}if(m.length>0)throw new Error(`${m.length} of ${s.length} files could not be uploaded`);return{files:c.map(({name:d,type:f,sizeBytes:u})=>({name:d,type:f,sizeBytes:u}))}}var wt=l(require("fs-extra")),re=l(require("path")),fu=".currents-session",qa=()=>re.default.join(process.cwd(),fu,"session.json");async function gu(t){let e=re.default.join(t,".gitignore");await wt.default.pathExists(e)||await wt.default.writeFile(e,`*
42
+ `)}async function za(t){let e=qa();await wt.default.ensureDir(re.default.dirname(e)),await gu(re.default.dirname(e)),await wt.default.writeJson(e,t,{spaces:2})}async function hu(){let t=qa();if(!await wt.default.pathExists(t))return null;let e=await wt.default.readJson(t),r=e?.sessionId||e?.runId;if(typeof r!="string"||!r.trim())return null;let o=typeof e.projectId=="string"?e.projectId:void 0;return{sessionId:r,projectId:o}}async function Ao(t){if(t)return t;let e=await hu();if(!e)throw new Error('No session found. Run "currents session start" first, or pass --session-id');return e.sessionId}var Eu=p.extend("session");async function Iu(){try{let{sha:t,branch:e,message:r,authorName:o,authorEmail:n,remoteOrigin:s}=await Oe();return{sha:t,branch:e,message:r,authorName:o,authorEmail:n,remoteOrigin:s}}catch(t){Eu("No git info: %o",t);return}}function Cu(t){if(t)return/^\d+$/.test(t)?{id:t}:{link:t}}function Qa(){let{provider:t,params:e}=rt();return{provider:t,params:e}}function Tu(){if(rt().ciBuildId.source!=="server")throw new Error("The CI build ID is unknown. Pass --ci-build-id or set CURRENTS_CI_BUILD_ID to the value the run was recorded with")}async function Xa(t){let e=await An(t.apiKey,{projectId:t.projectId,title:t.title,status:t.status,error:t.error,tags:t.tag,commit:await Iu(),ci:Qa(),pr:Cu(t.pr)});return await za({sessionId:e.sessionId,projectId:t.projectId}),t.json?process.stdout.write(JSON.stringify({sessionId:e.sessionId})+`
43
+ `):T("Session started: %s",e.sessionId),e}async function Za(t,e){let r=await Ao(t.sessionId);return xo({credentials:{apiKey:t.apiKey},owner:{sessionId:r},paths:e,type:t.type,caption:t.caption,meta:t.meta})}async function tc(t){let e=await Ao(t.sessionId),r=await Un(t.apiKey,{sessionId:e,purpose:"report",expiresInDays:t.expiresInDays});return T(r.pageUrl),T("Markdown: %s",r.url),r}async function ec(t,e){if(t.testTitle&&!t.spec)throw new Error("--test-title needs --spec, the spec file of the test");if(t.attempt!==void 0&&!t.testTitle)throw new Error("--attempt needs --test-title");if(t.group&&!t.spec)throw new Error("--group needs --spec: it picks the spec file of a group");return t.ciBuildId||Tu(),xo({credentials:{apiKey:t.apiKey,recordKey:t.recordKey},owner:t.ciBuildId?{projectId:t.projectId,ciBuildId:t.ciBuildId}:{projectId:t.projectId,ci:Qa()},target:{spec:t.spec,testTitle:t.testTitle,groupId:t.group,attempt:t.attempt,machineId:t.spec?void 0:t.machineId},paths:e,type:t.type,caption:t.caption,meta:t.meta})}var A=require("@commander-js/extra-typings");var rc=t=>N(F,t),or="(required; needs write access)",oc=Nt(". Leave it out only if the run was recorded without one, on a CI the reporters recognize"),nc=new A.Option("--machine-id <id>","the CI machine the files come from; run-level files are listed by machine when it is set").env(rc("machineId")),Uo=new A.Option("--session-id <id>",'the session to use instead of the one saved by "session start"').env(rc("sessionId")),sc=new A.Option("--title <text>","what the session shows, used as the session title (required)"),ic=new A.Option("--status <status>","the result of the session").choices(["passed","failed"]).default("passed"),ac=new A.Option("--error <text>","what went wrong, for a failed session"),cc=Lt("tags to add to the session"),pc=new A.Option("--pr <url|number>","the pull request the session is about; by default taken from the CI environment"),dc=new A.Option("--json",'print the session ID as JSON on stdout, e.g. {"sessionId": "..."}'),mc=new A.Option("--spec <spec>","attach to this spec file of the run"),uc=new A.Option("--test-title <title>",'attach to this test of --spec: the full title joined with " > ", or its last part'),lc=new A.Option("--group <id>","the group of the spec file; a spec that runs once per Playwright project matches more than once without it"),fc=new A.Option("--attempt <n>","attach to this attempt of the test; the first attempt is 0").argParser(t=>{let e=Number(t);if(!Number.isInteger(e)||e<0)throw new Error("--attempt must be a whole number from 0");return e}),gc=["trace","screenshot","video","attachment"],hc="by default taken from the file: a .zip holding trace.trace is a trace; .png, .jpg, .jpeg, .webp and .gif are screenshots; .webm and .mp4 are videos; anything else is an attachment",Ec=new A.Option("--type <type>",`the type of every file; ${hc}`).choices(gc),Ic=new A.Option("--type <type>",`the type of every file; ${hc}. The whole run and a test take attachments only, a spec file also takes screenshots and videos, and an attempt (--attempt) takes all four types, including traces. A file of a type its target does not take is attached as an attachment, and a --type the target does not take is an error`).choices(gc),nr="files or folders to attach. A folder adds the files directly in it; hidden files, links, subfolders and empty files in it are skipped. A folder of Playwright MCP trace-*.trace files is packed into one trace and nothing else in it is attached; a folder with such a traces/ subfolder adds the packed trace and its own files. Files named .env or .env.* are refused, and each file can be at most 1 GiB",sr=new A.Option("--caption <text>","a short description shown with each file"),yu=(t,e=[])=>[...e,t],ir=new A.Option("--meta <key=value>","a label for each file; repeat for more").argParser(yu),So=["1","3","7"],Cc=new A.Option("--expires-in-days <days>","the number of days the link works").choices(So).default(7).argParser(t=>{if(!So.includes(t))throw new A.InvalidArgumentError(`Allowed choices are ${So.join(", ")}.`);return Number(t)});var Pc=require("@commander-js/extra-typings");var Ft=require("@commander-js/extra-typings");var Tc=new Ft.Option("--ci-build-id <id>","the CI build ID to record the run with; by default taken from the CI environment, or a random value").env(N(nt,"ciBuildId")),yc=Lt("tags to add to the run").env(N(nt,"tag")),Rc=new Ft.Option("--remove-title-tags","remove tags from test names in Currents, e.g. `Test name @smoke` becomes `Test name` in the dashboard").env(N(nt,"removeTitleTags")).default(!1),_c=new Ft.Option("--disable-title-tags","do not read tags from test names, e.g. `Test name @smoke` is not tagged with `smoke` in the dashboard").env(N(nt,"disableTitleTags")).default(!1),wc=new Ft.Option("--machine-id <id>","the ID of the machine that ran the tests; by default a random value").env(N(nt,"machineId")),Oc=new Ft.Option("--report-dir <folder>","the folder of the reports to upload; by default the newest folder in .currents").env(N(nt,"reportDir"));var Po=require("path");var Sc=l(require("fs"));var xc=require("tmp-promise"),Ac=async()=>{let{path:t}=await(0,xc.file)();return t};var Do=p.extend("cli"),ar=class{constructor(e){this.configFilePath=null;this.cliOptions=e,Do("CLI options: %o",h(this.cliOptions)),this.parsedConfig=ks(this.cliOptions),Do("Parsed config from CLI options: %o",h(this.parsedConfig))}async getConfigFilePath(){if(this.configFilePath)return this.configFilePath;let e=await Ac();return Sc.default.writeFileSync(e,JSON.stringify(this.parsedConfig)),Do("CLI options temp file path: %s",e),this.configFilePath=e,e}};async function Uc(t){await w(async e=>{let r=e.inputFormat?await Ru(e):e.reportDir,o=new ar({...e,reportDir:r});Fs(o.parsedConfig);let n=xe();T("Currents config: %o",h(n)),await oo()},t)}async function Ru({inputFormat:t,inputFile:e,framework:r,frameworkVersion:o,outputDir:n,reportDir:s,debug:i}){if(n&&s&&(0,Po.resolve)(n)!==(0,Po.resolve)(s))throw new Error("--output-dir and --report-dir name different folders. With --input-format, the converted reports are saved to one folder and uploaded from it: pass one of the two options.");return To({inputFormat:t,inputFile:e,framework:r,frameworkVersion:o,outputDir:n??s,debug:i})}var kt="upload",Dc="(required with --input-format)",cr="run",Gt=t=>[{comment:"Upload test results to Currents",commands:[`${t} ${cr} ${kt} --key <record-key> --project-id <id> --ci-build-id <build-id>`]},{comment:"Convert JUnit XML reports to the Currents format, then upload them",commands:[`${t} ${cr} ${kt} --key <record-key> --project-id <id> --ci-build-id <build-id> --input-format junit --input-file "./*.xml" --framework postman`]},{comment:'Upload test results and add the tags "tagA" and "tagB" to the run',commands:[`${t} ${cr} ${kt} --key <record-key> --project-id <id> --ci-build-id <build-id> --tag tagA --tag tagB`]},{comment:"Upload test results from another folder",commands:[`${t} ${cr} ${kt} --key <record-key> --project-id <id> --ci-build-id <build-id> --report-dir <report-dir>`]}],pr=t=>new Pc.Command().name(kt).command(kt).showHelpAfterError("(add --help for additional information)").allowUnknownOption().summary("Upload test results of Currents reporters or JUnit").description(`Upload test results created by Currents reporters to https://currents.dev
44
44
 
45
45
  With --input-format, first convert the reports in --input-file to the Currents
46
46
  format, then upload the converted reports. They are saved to --output-dir, or
47
47
  --report-dir, or a new folder in .currents. A folder you name may hold only the
48
- reports being converted.`).addHelpText("after",y(Gt(t))).addOption(gc).addOption(at()).addOption(Z()).addOption(hc).addOption(Ec).addOption(Ic).addOption(Cc).addOption(P()).addOption(Tc).addOption(Ye()).addOption(We(Oc)).addOption(ze(Oc)).addOption(Qe).addOption(qe).action(r=>wc(r));var Uo="run",cr=t=>[{comment:"Attach the Docker logs of a CI machine to the run, after the tests finished",commands:[`${t} ${Uo} attach --key <record-key> --project-id <id> --ci-build-id <build-id> --machine-id shard-1 docker-logs.zip`]},{comment:"Attach a screenshot to the first attempt of a test",commands:[`${t} ${Uo} 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`]}],gu=t=>new Do.Command().name("attach").addHelpText("after",y(cr(t))).description("Upload files to a run recorded in CI").argument("<paths...>",rr).addOption(at("(required unless --api-key is set)")).addOption(ct("(used when --key is not set; needs write access)")).addOption(Z()).addOption(Xa).addOption(Za).addOption(ic).addOption(cc).addOption(ac).addOption(pc).addOption(lc).addOption(or).addOption(nr).addOption(P()).action(async(e,r)=>{await w(async({key:o,...n})=>{await za(Ra({...n,recordKey:o}),e)},r)}),Ac=t=>new Do.Command().name(Uo).summary("Upload test results, attach files, get or cancel a run").description("Upload test results to a run, attach files to it, get its data or cancel it").addHelpText("after",y([...Gt(t).slice(0,2),cr(t)[0],so(t)[0],te(t)[0]])).showHelpAfterError("(add --help for additional information)").addCommand(ar(t)).addCommand(gu(t)).addCommand(io(t)).addCommand(Ge(t));var oe=require("@commander-js/extra-typings");var pr="session",$t=t=>{let e=`${t} ${pr} start --api-key <api-key> --project-id <id> --title "Checkout fails on empty cart" --status failed`,r=`${t} ${pr} attach before.png .playwright-mcp/traces`,o=`${t} ${pr} share --expires-in-days 7`;return{session:[{comment:"Start a session, attach what you captured and get a link to share",commands:[e,r,o]}],start:[{comment:"Start a session for a failed check",commands:[e]}],attach:[{comment:"Attach a screenshot and a Playwright MCP trace folder",commands:[r]}],share:[{comment:"Print a link that expires in 7 days",commands:[o]}]}},hu=t=>new oe.Command().name("start").addHelpText("after",y($t(t).start)).summary("Create a session").description('Create a session and save its ID to .currents-session/session.json in the current folder, where "attach" and "share" read it').addOption(ct(er)).addOption(Z()).addOption(tc).addOption(ec).addOption(rc).addOption(oc).addOption(nc).addOption(sc).addOption(P()).action(async e=>{await w(async r=>{r.json&&Pt(),await Ya(Ca(r))},e)}),Eu=t=>new oe.Command().name("attach").summary("Upload screenshots, traces and other files").addHelpText("after",y($t(t).attach)).description("Upload files, folders or a Playwright MCP trace folder to the session").argument("<paths...>",rr).addOption(ct(er)).addOption(xo).addOption(uc).addOption(or).addOption(nr).addOption(P()).action(async(e,r)=>{await w(async o=>{await Wa(Ta(o),e)},r)}),Iu=t=>new oe.Command().name("share").addHelpText("after",y($t(t).share)).summary("Print a public link to the session page").description('Create a public link to the session page and print it. The second line, "Markdown: <url>", is the address of the same content as Markdown, for agents').addOption(ct(er)).addOption(xo).addOption(fc).addOption(P()).action(async e=>{await w(async r=>{await qa(ya(r))},e)}),Sc=t=>new oe.Command().name(pr).summary("Capture agent or browser sessions as evidence").description("Capture ad-hoc, one-off agent or browser sessions as evidence: a bug before and after a fix, or proof that something works. Create a session, attach screenshots, traces, videos and other files to it, and print a link to share it.").addHelpText("after",y($t(t).session)).showHelpAfterError("(add --help for additional information)").addCommand(hu(t)).addCommand(Eu(t)).addCommand(Iu(t));var Ht=require("@commander-js/extra-typings");var tt=l(require("fs-extra")),G=l(require("path")),pt="currents-cli",Kt=G.default.join(".agents","skills");function Uc(t=__dirname){let e=t;for(;;){let r=G.default.join(e,"skills",pt);if(tt.default.existsSync(G.default.join(r,"SKILL.md")))return r;let o=G.default.dirname(e);if(o===e)throw new Error(`The ${pt} skill is missing from this package`);e=o}}async function Po(t,e=""){let r=[];for(let o of await tt.default.readdir(G.default.join(t,e),{withFileTypes:!0})){let n=G.default.join(e,o.name);o.isDirectory()?r.push(...await Po(t,n)):r.push(n)}return r.sort()}async function Cu(t,e){let[r,o]=await Promise.all([Po(t),Po(e)]);if(r.join(`
48
+ reports being converted.`).addHelpText("after",y(Gt(t))).addOption(Tc).addOption(at()).addOption(Z()).addOption(yc).addOption(Rc).addOption(_c).addOption(wc).addOption(P()).addOption(Oc).addOption(qe()).addOption(ze(Dc)).addOption(Xe(Dc)).addOption(Ze).addOption(Qe).action(r=>Uc(r));var bo="run",dr=t=>[{comment:"Attach the Docker logs of a CI machine to the run, after the tests finished",commands:[`${t} ${bo} attach --key <record-key> --project-id <id> --ci-build-id <build-id> --machine-id shard-1 docker-logs.zip`]},{comment:"Attach a screenshot to the first attempt of a test",commands:[`${t} ${bo} 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`]}],_u=t=>new No.Command().name("attach").addHelpText("after",y(dr(t))).description("Upload files to a run recorded in CI").argument("<paths...>",nr).addOption(at("(required unless --api-key is set)")).addOption(ct("(used when --key is not set; needs write access)")).addOption(Z()).addOption(oc).addOption(nc).addOption(mc).addOption(lc).addOption(uc).addOption(fc).addOption(Ic).addOption(sr).addOption(ir).addOption(P()).action(async(e,r)=>{await w(async({key:o,...n})=>{await ec(Aa({...n,recordKey:o}),e)},r)}),bc=t=>new No.Command().name(bo).summary("Upload test results, attach files, get or cancel a run").description("Upload test results to a run, attach files to it, get its data or cancel it").addHelpText("after",y([...Gt(t).slice(0,2),dr(t)[0],co(t)[0],te(t)[0]])).showHelpAfterError("(add --help for additional information)").addCommand(pr(t)).addCommand(_u(t)).addCommand(po(t)).addCommand($e(t));var oe=require("@commander-js/extra-typings");var mr="session",jt=t=>{let e=`${t} ${mr} start --api-key <api-key> --project-id <id> --title "Checkout fails on empty cart" --status failed`,r=`${t} ${mr} attach before.png .playwright-mcp/traces`,o=`${t} ${mr} share --expires-in-days 7`;return{session:[{comment:"Start a session, attach what you captured and get a link to share",commands:[e,r,o]}],start:[{comment:"Start a session for a failed check",commands:[e]}],attach:[{comment:"Attach a screenshot and a Playwright MCP trace folder",commands:[r]}],share:[{comment:"Print a link that expires in 7 days",commands:[o]}]}},wu=t=>new oe.Command().name("start").addHelpText("after",y(jt(t).start)).summary("Create a session").description('Create a session and save its ID to .currents-session/session.json in the current folder, where "attach" and "share" read it').addOption(ct(or)).addOption(Z()).addOption(sc).addOption(ic).addOption(ac).addOption(cc).addOption(pc).addOption(dc).addOption(P()).action(async e=>{await w(async r=>{r.json&&Pt(),await Xa(wa(r))},e)}),Ou=t=>new oe.Command().name("attach").summary("Upload screenshots, traces and other files").addHelpText("after",y(jt(t).attach)).description("Upload files, folders or a Playwright MCP trace folder to the session").argument("<paths...>",nr).addOption(ct(or)).addOption(Uo).addOption(Ec).addOption(sr).addOption(ir).addOption(P()).action(async(e,r)=>{await w(async o=>{await Za(Oa(o),e)},r)}),xu=t=>new oe.Command().name("share").addHelpText("after",y(jt(t).share)).summary("Print a public link to the session page").description('Create a public link to the session page and print it. The second line, "Markdown: <url>", is the address of the same content as Markdown, for agents').addOption(ct(or)).addOption(Uo).addOption(Cc).addOption(P()).action(async e=>{await w(async r=>{await tc(xa(r))},e)}),Nc=t=>new oe.Command().name(mr).summary("Capture agent or browser sessions as evidence").description("Capture ad-hoc, one-off agent or browser sessions as evidence: a bug before and after a fix, or proof that something works. Create a session, attach screenshots, traces, videos and other files to it, and print a link to share it.").addHelpText("after",y(jt(t).session)).showHelpAfterError("(add --help for additional information)").addCommand(wu(t)).addCommand(Ou(t)).addCommand(xu(t));var Kt=require("@commander-js/extra-typings");var tt=l(require("fs-extra")),G=l(require("path")),pt="currents-cli",$t=G.default.join(".agents","skills");function Lc(t=__dirname){let e=t;for(;;){let r=G.default.join(e,"skills",pt);if(tt.default.existsSync(G.default.join(r,"SKILL.md")))return r;let o=G.default.dirname(e);if(o===e)throw new Error(`The ${pt} skill is missing from this package`);e=o}}async function Lo(t,e=""){let r=[];for(let o of await tt.default.readdir(G.default.join(t,e),{withFileTypes:!0})){let n=G.default.join(e,o.name);o.isDirectory()?r.push(...await Lo(t,n)):r.push(n)}return r.sort()}async function Au(t,e){let[r,o]=await Promise.all([Lo(t),Lo(e)]);if(r.join(`
49
49
  `)!==o.join(`
50
- `))return!1;for(let n of r){let[s,i]=await Promise.all([tt.default.readFile(G.default.join(t,n)),tt.default.readFile(G.default.join(e,n))]);if(!s.equals(i))return!1}return!0}async function Dc(){let t=await tt.default.readFile(G.default.join(Uc(),"SKILL.md"),"utf8");await new Promise((e,r)=>process.stdout.write(t,o=>o?r(o):e()))}async function Pc({dir:t=Kt,force:e=!1}){let r=Uc(),o=G.default.resolve(t,pt),n=G.default.relative(process.cwd(),o)||".";if(await tt.default.pathExists(o)){if(!(await tt.default.stat(o)).isDirectory())throw new Error(`${n} exists and is not a folder`);if(await Cu(r,o))return T("The %s skill is already in %s",pt,n),o;if(!e)throw new Error(`${n} exists and differs from the skill of this version. Pass --force to replace it`);await tt.default.remove(o)}return await tt.default.copy(r,o),T("Wrote the %s skill to %s",pt,n),o}var dr="skill",Tu=t=>[{comment:"Print the skill",commands:[`${t} ${dr}`]},{comment:`Add the skill to the project, in ${Kt}/${pt}`,commands:[`${t} ${dr} --install`]},{comment:"Add the skill for Claude Code",commands:[`${t} ${dr} --install --dir .claude/skills`]}],bc=t=>new Ht.Command().name(dr).summary("Print or install the agent skill for this CLI").description(`Print SKILL.md of the ${pt} skill, which tells coding agents how to use this CLI, or install the skill in the project. Install it to get the reference files too.
50
+ `))return!1;for(let n of r){let[s,i]=await Promise.all([tt.default.readFile(G.default.join(t,n)),tt.default.readFile(G.default.join(e,n))]);if(!s.equals(i))return!1}return!0}async function vc(){let t=await tt.default.readFile(G.default.join(Lc(),"SKILL.md"),"utf8");await new Promise((e,r)=>process.stdout.write(t,o=>o?r(o):e()))}async function Bc({dir:t=$t,force:e=!1}){let r=Lc(),o=G.default.resolve(t,pt),n=G.default.relative(process.cwd(),o)||".";if(await tt.default.pathExists(o)){if(!(await tt.default.stat(o)).isDirectory())throw new Error(`${n} exists and is not a folder`);if(await Au(r,o))return T("The %s skill is already in %s",pt,n),o;if(!e)throw new Error(`${n} exists and differs from the skill of this version. Pass --force to replace it`);await tt.default.remove(o)}return await tt.default.copy(r,o),T("Wrote the %s skill to %s",pt,n),o}var ur="skill",Su=t=>[{comment:"Print the skill",commands:[`${t} ${ur}`]},{comment:`Add the skill to the project, in ${$t}/${pt}`,commands:[`${t} ${ur} --install`]},{comment:"Add the skill for Claude Code",commands:[`${t} ${ur} --install --dir .claude/skills`]}],Mc=t=>new Kt.Command().name(ur).summary("Print or install the agent skill for this CLI").description(`Print SKILL.md of the ${pt} skill, which tells coding agents how to use this CLI, or install the skill in the project. Install it to get the reference files too.
51
51
 
52
52
  Agents read project skills from these folders:
53
- Codex, Cursor ${Kt}
54
- Claude Code .claude/skills`).addHelpText("after",y(Tu(t))).addOption(new Ht.Option("--install",`write the skill folder to <dir>/${pt}`)).addOption(new Ht.Option("--dir <path>","the skills folder to install to").default(Kt)).addOption(new Ht.Option("--force","replace an installed copy of the skill that differs from this version")).action(async e=>{await w(async r=>{if(!r.install&&(r.force||r.dir!==Kt))throw new Error("--dir and --force work with --install only");r.install?await Pc({dir:r.dir,force:r.force}):await Dc()},e)});var O="currents",Lc=()=>{let t=ar(O),e=new Nc.Command(O).version(xt).description("Currents CLI: upload test results and files to Currents, get and cancel runs, capture agent or browser sessions as evidence, and cache files between CI jobs").showHelpAfterError(`(run '${O} --help' for usage)`).enablePositionalOptions().hook("preAction",(i,c)=>{Dn(c),Pn(c)}).addCommand(t,{hidden:!0}).addCommand(Ia(O),{hidden:!0}).addCommand(Ge(O,{deprecated:!0}),{hidden:!0}).commandsGroup("Test runs:").addCommand(Ac(O)).commandsGroup("Evidence:").addCommand(Sc(O)).commandsGroup("CI utilities:").addCommand(ji(O)).commandsGroup("Other:").addCommand($i(O)).addCommand(bc(O)).helpCommand(!0).addHelpText("after",`${y([Gt(O)[0],Gt(O)[1],Me(O)[1],Fe(O)[1],te(O)[0],cr(O)[0],...$t(O).session])}
53
+ Codex, Cursor ${$t}
54
+ Claude Code .claude/skills`).addHelpText("after",y(Su(t))).addOption(new Kt.Option("--install",`write the skill folder to <dir>/${pt}`)).addOption(new Kt.Option("--dir <path>","the skills folder to install to").default($t)).addOption(new Kt.Option("--force","replace an installed copy of the skill that differs from this version")).action(async e=>{await w(async r=>{if(!r.install&&(r.force||r.dir!==$t))throw new Error("--dir and --force work with --install only");r.install?await Bc({dir:r.dir,force:r.force}):await vc()},e)});var O="currents",kc=()=>{let t=pr(O),e=new Fc.Command(O).version(xt).description("Currents CLI: upload test results and files to Currents, get and cancel runs, capture agent or browser sessions as evidence, and cache files between CI jobs").showHelpAfterError(`(run '${O} --help' for usage)`).enablePositionalOptions().hook("preAction",(i,c)=>{Nn(c),Ln(c)}).addCommand(t,{hidden:!0}).addCommand(_a(O),{hidden:!0}).addCommand($e(O,{deprecated:!0}),{hidden:!0}).commandsGroup("Test runs:").addCommand(bc(O)).commandsGroup("Evidence:").addCommand(Nc(O)).commandsGroup("CI utilities:").addCommand(qi(O)).commandsGroup("Other:").addCommand(Vi(O)).addCommand(Mc(O)).helpCommand(!0).addHelpText("after",`${y([Gt(O)[0],Gt(O)[1],ke(O)[1],Ge(O)[1],te(O)[0],dr(O)[0],...jt(O).session])}
55
55
  Run '${O} <command> --help' for the options and examples of a command.
56
56
 
57
57
  Agent skill: ${O} skill --install
58
58
  Documentation: https://docs.currents.dev
59
59
  Support: support@currents.dev
60
60
  `),r=`upload is no longer the default command. Run '${O} run upload ...' instead.`,o=t.options.flatMap(i=>[i.long,i.short]),n=e,s=n.unknownOption.bind(e);return n.unknownOption=i=>{if(!o.includes(i.split("=")[0]))return s(i);e.error(r)},e.addHelpText("before",({error:i})=>i&&(process.env.CURRENTS_RECORD_KEY||process.env.CURRENTS_PROJECT_ID)?`error: ${r}
61
- `:""),e};import("dotenv/config");function yu(){Lc().parse()}yu();
61
+ `:""),e};import("dotenv/config");function Uu(){kc().parse()}Uu();
62
62
  /*! For license information please see index.js.LEGAL.txt */
63
63
  //# sourceMappingURL=index.js.map
package/dist/index.js CHANGED
@@ -1,11 +1,11 @@
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,`
1
+ "use strict";var gr=Object.create;var j=Object.defineProperty;var Ir=Object.getOwnPropertyDescriptor;var _r=Object.getOwnPropertyNames;var Tr=Object.getPrototypeOf,Rr=Object.prototype.hasOwnProperty;var xt=(t,e)=>{for(var r in e)j(t,r,{get:e[r],enumerable:!0})},Pt=(t,e,r,n)=>{if(e&&typeof e=="object"||typeof e=="function")for(let o of _r(e))!Rr.call(t,o)&&o!==r&&j(t,o,{get:()=>e[o],enumerable:!(n=Ir(e,o))||n.enumerable});return t};var u=(t,e,r)=>(r=t!=null?gr(Tr(t)):{},Pt(e||!t||!t.__esModule?j(r,"default",{value:t,enumerable:!0}):r,t)),Cr=t=>Pt(j({},"__esModule",{value:!0}),t);var Xn={};xt(Xn,{handleCurrentsReport:()=>fr});module.exports=Cr(Xn);var wt=require("debug"),Ur=u(require("fs-extra")),c=(0,wt.debug)("currents"),hr=null;function Mt(t){hr=t}var Y={};xt(Y,{getNanoid:()=>Dr,userFacingNanoid:()=>Et});var mt=require("nanoid"),bt="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz",Dr=(t=16)=>(0,mt.customAlphabet)(bt,t)(),Et=(0,mt.customAlphabet)(bt,12);var E=require("lodash");function vt(t){return t.replace(/^([a-z][a-z0-9+.-]*:\/\/)[^/?#\s]*@/i,"$1")}var J=c.extend("ci"),Ar=(t,e)=>(0,E.set)(t,(0,E.camelCase)(e),process.env[e]),I=t=>(0,E.transform)(t,Ar,{}),Or=()=>process.env.TF_BUILD&&process.env.AZURE_HTTP_USER_AGENT,Sr=()=>(0,E.some)(process.env,(t,e)=>/^CODEBUILD_/.test(e)),yr=()=>process.env.bamboo_buildNumber,Nr=()=>(0,E.some)(process.env,(t,e)=>/^CONCOURSE_/.test(e)),Lr=()=>process.env.GITLAB_CI||process.env.CI_SERVER_NAME&&/^GitLab/.test(process.env.CI_SERVER_NAME),Br=()=>!!(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),xr=()=>process.env.JENKINS_URL||process.env.JENKINS_HOME||process.env.JENKINS_VERSION||process.env.HUDSON_URL||process.env.HUDSON_HOME,Pr={appveyor:"APPVEYOR",azure:Or,awsCodeBuild:Sr,bamboo:yr,bitbucket:"BITBUCKET_BUILD_NUMBER",buildkite:"BUILDKITE",circle:"CIRCLECI",concourse:Nr,codeFresh:"CF_BUILD_ID",drone:"DRONE",githubActions:"GITHUB_ACTIONS",gitlab:Lr,goCD:"GO_JOB_NAME",jenkins:xr,googleCloud:Br,semaphore:"SEMAPHORE",teamcity:"TEAMCITY_VERSION",travis:"TRAVIS",netlify:"NETLIFY"};function wr(){let{env:t}=process;return(0,E.findKey)(Pr,e=>{if((0,E.isString)(e))return t[e];if((0,E.isFunction)(e))return e()})}var Ft=()=>({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"])}),Mr=t=>{let e=Gt();return e?(0,E.chain)(t()).get(e).value():{}};function br(){return(0,E.chain)(Ft()).omitBy(E.isNull).keys().value()}function vr(t){return t&&br().includes(t)}function Gt(){let t=wr();return J("detected CI provider name: %s",t),t||null}function Fr(){let t=Mr(Ft);return(0,E.mapValues)(t,e=>(0,E.isString)(e)?vt(e):e)}function Ht(t){let e=Fr(),r=Gt(),n=Gr(t,r);return J("detected CI provider: %s",r),J("detected CI params: %O",e),J("detected CI build ID: %o",n),{params:e,provider:r,ciBuildId:n}}function Gr(t,e){return t?{source:"user",value:t}:vr(e)?{source:"server",value:null}:{source:"random",value:`auto:${Et()}`}}var kt=require("@currents/commit-info"),Kt=require("lodash");var Hr=c.extend("git"),kr=async()=>{let t=await(0,kt.commitInfo)();return Hr("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}},jt=(0,Kt.memoize)(kr);var Yt=u(require("getos")),Jt=require("lodash"),O=require("os"),$t=require("util"),Kr=async()=>{if((0,O.platform)()==="linux")try{let t=await(0,$t.promisify)(Yt.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)()},jr=async()=>{let t=await Kr();return{osName:(0,O.platform)(),osVersion:t,osCpus:[],osMemory:{free:(0,O.freemem)(),total:(0,O.totalmem)()}}},Vt=(0,Jt.memoize)(jr);var Wt={name:"@currents/cmd",version:"2.0.1",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 lt=u(require("lodash")),Jr=["apiKey","recordKey","key"];function qt(t,e){return lt.default.isPlainObject(t)?lt.default.mapValues(t,(r,n)=>e.includes(n)&&r!==void 0?"*****":qt(r,e)):t}function S(t){return qt(t,Jr)}var $r=[];function ft(t){$r.push(t)}var T=u(require("chalk")),b=u(require("util"));var Qt=[],Xt=[];var zt=(...t)=>{let e=b.default.format(...t);ft(e),console.log(e)},Vr=(...t)=>{let e=b.default.format(...t);ft(e),console.error(e)},V=zt,f=(...t)=>{let e=b.default.format(...t);return Xt.push(e),c("WARNING: ",e),zt(T.default.bgYellow.black(" WARNING "),e)};var d=(...t)=>{let e=b.default.format(...Wr(t));return Qt.push(e),c("ERROR: ",b.default.format(...t)),Vr(T.default.bgRed.white(" ERROR "),e)};var Wr=t=>t.map(e=>e instanceof Error?e.message:e),W=(t=2)=>console.log(Array(t).fill("").join(`
2
+ `)),Po=T.default.cyan,wo=T.default.blueBright,Mo=T.default.red,bo=T.default.yellow,vo=T.default.green,Fo=T.default.gray,Go=T.default.white,Ho=T.default.black,ko=T.default.magenta,v=T.default.dim,Ko=T.default.bold;var F=u(require("fs-extra")),dt=require("path"),Qr=require("uuid");async function w(t){try{return await F.default.readJson(t)}catch(e){throw d("Error while reading JSON file: %s",t,e),d}}async function gt(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 Zt(t){try{return await F.default.ensureDir(t),c("Folder created",t),t}catch(e){throw d(`Failed to create folder at ${t}:`,e),e}}async function te(t,e){try{return await F.default.ensureDir((0,dt.dirname)(e)),await F.default.copy(t,e),c("File copied from %s to %s",t,e),e}catch(r){throw d(`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 Er=u(require("axios")),Lt=u(require("fs-extra")),ct=u(require("path")),lr=u(require("semver"));var Re=u(require("lodash"));var Ee=u(require("axios")),le=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"),It=u(require("pretty-ms"));var ae=c.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)},Tt=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),Xr=["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 Xr.includes(t.config?.method?.toLowerCase()??"get")?Tt(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,It.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,It.default)(Q(t,e)??0),t,X())}var Rt=c.extend("http");var Ct={api:null,restApi:null};function zr(t){let e=t==="api"?ne():oe();Rt("client base url: %s",e);let r=Ee.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?Rt("network request retry: %o",me({...s,baseURL:e,isRetry:!0})):Rt("network request: %o",me(s)),n}),(0,le.default)(r,{retries:X(),retryCondition:t==="restApi"?pe:Tt,retryDelay:(n,o)=>Q(n,o),shouldResetTimeout:!0,onRetry:ue}),r}function z(t){return Ct[t]===null&&(Ct[t]=zr(t)),Ct[t]}function me(t){return{method:t.method,baseURL:t.baseURL,url:t.url,data:t.isRetry?"<retry>":Zr(t.data),params:t.isRetry?"<retry>":t.params,headers:{...t.headers,Authorization:"Bearer ***","x-currents-key":"***"}}}function Zr(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 Ut.default.isPlainObject(t)?S(t):t}var ge=require("axios"),Ie=u(require("lodash")),_=require("ts-pattern");function _e(t){(0,_.match)(t).when(ge.isAxiosError,tn).otherwise(()=>{f("Unexpected error while sending network request: %s",t)})}function tn(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=>{en(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 en(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,()=>{rn(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 rn(t,e){(0,_.match)(e).with({code:fe.MISSING_SUITE,message:_.P.string,errors:_.P.array(_.P.string)},async r=>{let{message:n,errors:o}=r;W(1),d(...de(n,o))}).with({code:fe.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(...de(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 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 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});
9
+ `]:["Unexpected network error"]}var Te=c.extend("http");async function G(t,e,r=z){try{let n=await r(t).request(e);return Te("network response: %o",{...Re.default.omit(n,"request","config"),url:n.config.url,method:n.config.method}),n}catch(n){let o=n;throw Te("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}),_e(o),o}}var Ks=c.extend("api");var qs=c.extend("api");var Ue=require("util"),he=require("zlib");var Ce=c.extend("api"),nn=(0,Ue.promisify)(he.gzip);async function De(t){try{Ce("Run params: %o",S(t));let e=await on(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 on(t){try{return await nn(t)}catch(e){throw d("Failed to compress run payload:",e),e}}var pi=c.extend("api");var sn=require("axios");var _i=c.extend("api");var ht={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:an,ciBuildId:cn,recordKey:pn,projectId:un,machineId:mn}=ht,En={debug:an,ciBuildId:cn,recordKey:pn,projectId:un,machineId:mn,tag:{...ht.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 qi=c.extend("config");var ln=null;function Oe(){return ln}var At=u(require("fs-extra")),y=require("path");var fn=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"),Dt=c.extend("detox"),dn="detox.json";function Le(t){return[...t].sort((e,r)=>(e.session??0)-(r.session??0)||e.invocations-r.invocations)}async function Be(t){let e=(0,Ne.join)(t,dn);try{let r=await ye.default.readJson(e);if(typeof r?.artifactsRootDir!="string"||!Array.isArray(r?.tests)){Dt("Unexpected Detox manifest contents at %s",e);return}return Dt("Detox manifest: %o",r),r}catch{Dt("No Detox manifest at %s",e);return}}var Z=require("path"),gn=c.extend("detox"),xe=255,In=/[/\\?<>:*|"$\u0000-\u001f]/g,Pe=4;function we(t){return _n(t)??Tn(t)}function _n({rootDir:t,fullName:e,status:r,invocations:n}){try{let o=require.resolve("detox/src/artifacts/utils/ArtifactPathBuilder",{paths:[process.cwd()]}),s=require(o),a=new s({rootDir:t});return(0,Z.dirname)(a.buildPathForTestArtifact("test.mp4",{fullName:e,status:r,invocations:n}))}catch(o){gn("Detox path builder is not available: %o",o);return}}function Tn({rootDir:t,fullName:e,status:r,invocations:n}){let o=Cn(r),s=n>1?` (${n})`:"",a=e.slice(-xe+o.length+s.length),p=`${o}${a}${s}`.replace(In,"_");return(0,Z.join)(t,Rn(p,xe))}function Rn(t,e){let r=Buffer.from(t,"utf8");return r.length<=e?t:r.subarray(0,e).toString("utf8").replace(/\uFFFD$/,"")}function Cn(t){switch(t){case"passed":return"\u2713 ";case"failed":return"\u2717 ";default:return""}}var be=u(require("fs-extra")),ve=require("path"),Me=c.extend("detox"),tt="detox.trace.json",Un="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=hn(n);return An(n).forEach(({pid:a,ts:p,step:l})=>{o.filter(g=>g.pid===a&&p>=g.startTs&&p<=g.endTs).sort((g,R)=>g.startTs-R.startTs).pop()?.steps.push(l)}),o.forEach(({fullName:a,invocations:p,steps:l})=>{let m=r.get(a)??[];m.push({fullName:a,invocations:p,steps:l.sort((g,R)=>+new Date(g.startTime)-+new Date(R.startTime))}),r.set(a,m)}),r}function hn(t){let e=new Map,r=[];t.forEach(o=>{let s=`${o.pid}:${o.tid}`,a=e.get(s)??[];if(e.set(s,a),o.ph==="B"){a.push(Dn(o));return}if(o.ph==="E"){let p=a.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 Dn(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 An(t){let e=new Map,r=[];return t.forEach(n=>{if(!n.cat?.includes(Un))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 a=s.pop();if(!a)return;r.push({pid:Number(n.pid),ts:a.ts,step:{title:a.name,category:"detox",startTime:new Date(a.ts/1e3).toISOString(),duration:Math.round((Number(n.ts)-a.ts)/1e3),steps:[]}})}}),r}var k=c.extend("detox"),Ge="artifacts",On=[".mp4",".png",".jpg",".log",".txt",".json",".viewhierarchy"],Sn=t=>{let e=(0,y.extname)(t);return On.includes(e)?Se[e]:void 0};async function He({instances:t,reportDir:e,manifest:r}){let n=Nn(r),o=await Fe(r.artifactsRootDir),s=await Zt((0,y.join)(e,Ge)),a={artifacts:0,steps:0};for(let p of t)for(let l of p.results.tests){let m=n.get(l.testId);if(!m){k("No Detox manifest entry for %s",l.testId);continue}await Ln({test:l,manifestTest:m,rootDir:r.artifactsRootDir,artifactsDir:s,traceSlices:o.get(m.fullName)??[],result:a})}return a.artifacts+=await yn({instances:t,rootDir:r.artifactsRootDir,artifactsDir:s}),a}async function yn({instances:t,rootDir:e,artifactsDir:r}){if(!await At.default.pathExists((0,y.join)(e,tt)))return 0;let[n]=await ke(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 Nn(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 Ln({test:t,manifestTest:e,rootDir:r,artifactsDir:n,traceSlices:o,result:s}){let a=[...t.attempts].sort((m,g)=>m.attempt-g.attempt),p=Le(e.attempts),l=1;for(let[m,g]of p.entries()){let R=a[m];if(!R){k("No reported attempt %d of %s",m,e.fullName);continue}let h=await Bn({fullName:e.fullName,status:g.status,rootDir:r,artifactsDir:n,fromInvocation:l});h&&(l=h.invocation+1,R.artifacts=[...R.artifacts??[],...h.artifacts],s.artifacts+=h.artifacts.length);let M=Pn(o,m,h?.invocation);M.length&&(R.steps=[...R.steps??[],...M],s.steps+=M.length)}}async function Bn({fullName:t,status:e,rootDir:r,artifactsDir:n,fromInvocation:o}){for(let s=o;s<o+Pe;s++){let a=we({rootDir:r,fullName:t,status:e,invocations:s}),p=await xn(a);if(p)return{invocation:s,artifacts:await ke(a,p,n)}}k("No Detox artifacts for %s [%s]",t,e)}async function xn(t){try{return(await At.default.readdir(t)).sort()}catch{return}}async function ke(t,e,r){let n=[];for(let o of e){let s=Sn(o);if(!s){k("Skipping unsupported Detox artifact %s",o);continue}let a=(0,y.join)(t,o),p=`${re(a)}${(0,y.extname)(o)}`;await te(a,(0,y.join)(r,p)),n.push({...s,path:(0,y.join)(Ge,p),name:o})}return n}function Pn(t,e,r){return((r===void 0?void 0:t.find(s=>s.invocations===r))??[...t].sort((s,a)=>s.invocations-a.invocations)[e])?.steps??[]}var L=class{constructor(e){this.config=e}async getFullTestSuite(){return[]}};var er=u(require("fs-extra")),rr=u(require("tmp"));var Ze=require("lodash");function Ke(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 je=require("lodash"),wn=["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 Ye(t){return(0,je.omit)(t,...wn)}var Xe=u(require("fs")),St=require("lodash"),yt=u(require("path"));var Ot=u(require("fs")),et=require("module"),rt=u(require("path")),Je=u(require("semver")),Mn=">=29.5.0";function bn(){let t=(0,et.createRequire)(rt.default.join(process.cwd(),"package.json"));if(vn(t)==="jest-cli")return t.resolve("jest-cli");try{return(0,et.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 vn(t){for(let e of t.resolve.paths("jest")??[]){if(Ot.default.existsSync(rt.default.join(e,"jest","package.json")))return"jest";if(Ot.default.existsSync(rt.default.join(e,"jest-cli","package.json")))return"jest-cli"}return null}function $e(){let t=(0,et.createRequire)(bn()),{version:e}=t("jest-cli/package.json");if(!Je.default.satisfies(e,Mn,{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 Ve(){return $e()("jest-cli")}function We(){return $e()("jest-config")}function nt(t,e){return(...r)=>new Promise((n,o)=>{let s=0,a=()=>{s++;try{let p=t(...r);n(p)}catch(p){if(s>=e.length)o(p);else{let l=e[s-1];setTimeout(a,l)}}};a()})}var qe=u(require("fs-extra")),Fn=u(require("path"));async function ot(t){let e=await qe.default.pathExists(t);if(!e)throw new Error("File does not exist");return e}var Qe=c.extend("jest-discovery");async function ze(t){try{let{readInitialOptions:e}=We(),{config:r,configPath:n}=await e(t),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"],s=["collectCoverageFrom","coverageDirectory","coveragePathIgnorePatterns","detectLeaks","detectOpenHandles","errorOnDeprecated","forceCoverageMatch","openHandlesTimeout","runner","watchPathIgnorePatterns"],a=(0,St.omit)(r,o);if(a.projects&&(a.projects=a.projects.map(m=>typeof m!="string"?(0,St.omit)(m,s):m)),a.rootDir&&Object.keys(a).length===1)return null;let p=yt.default.resolve(n?yt.default.dirname(n):process.cwd(),`.jest-scanner-${new Date().getTime()}.config.cjs`),l=`module.exports=${JSON.stringify(a,null,2)}`;return Qe("configFileContent: %O",l),Xe.default.writeFileSync(p,l),await nt(ot,[200,200,200,200,200,1e3])(p),p}catch(e){return d("Failed to recreate the config file"),Qe("error %o",e),null}}async function tr(t){let e="!!##ThisPatternWillNotMatchAnyTestName##!!",r=t.options,n=Ye(r),o=Ke(n),s=r.config,a=await ze(s);return{cliArgs:[o,"--testNamePattern",e,"--reporters","@currents/cmd/discovery/jest","--shard=1/1",a?`--config=${a}`:"",...t.args].filter(l=>!(0,Ze.isEmpty)(l)),configFilePath:a}}var Gn=c.extend("jest-discovery");async function nr(t,e){console.time(v("@currents/jest:fullTestSuite-ready"));let{run:r}=Ve(),{cliArgs:n,configFilePath:o}=await tr(e);try{let s=rr.default.fileSync({postfix:".json"});return Gn("running scanner: %o",n),process.env.CURRENTS_DISCOVERY_PATH=s.name,await r(n.concat(["--openHandlesTimeout=0"])),await nt(ot,Array.from({length:300},()=>100))(s.name),console.timeEnd(v("@currents/jest:fullTestSuite-ready")),await w(s.name)}catch(s){return d("Failed to obtain the jest full test suite:",s),[]}finally{o&&er.default.unlinkSync(o)}}var st=class extends L{constructor(e){super(e)}async getFullTestSuite(){return nr(this.config.frameworkConfig,this.config.cliArgs)}};var sr=u(require("fs-extra"));var or=u(require("path"));function it(t){return or.default.join(t,"fullTestSuite.json")}var Hn=c.extend("junit-discovery");async function ir(t){console.time(v("@currents/junit:fullTestSuite-ready"));try{Hn("running scanner: %o",t);let e=it(t);process.env.CURRENTS_DISCOVERY_PATH=e;let r=sr.default.readFileSync(e,"utf-8");return JSON.parse(r)}catch(e){return d("Failed to obtain the junit full test suite:",e),[]}}var at=class extends L{constructor(e,r){super(e),this.reportDir=r}async getFullTestSuite(){return ir(this.reportDir)}};function ar(t,e){switch(t.framework){case"jest":return new st(t);case"junit":return new at(t,e);default:return new L(t)}}var B=u(require("fs-extra")),N=u(require("path"));async function cr(t){let e=await kn(t?.reportDir);return{reportDir:e,configFilePath:t?.configFilePath??N.default.join(e,"config.json")}}async function kn(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,N.join)(process.cwd(),".currents"),r=await B.default.pathExists(e)?await Kn(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 Kn(t){let e=await B.default.readdir(t),r=null;for(let n of e){let o=N.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,N.resolve)(t,r.name):null}async function Nt(t){try{return await B.default.pathExists(t)}catch{return d("Error checking if path exists:",d),!1}}async function pr(t){let e=N.default.join(t,"instances");return jn(e)}async function jn(t){let e=await B.default.readdir(t),r=[];for(let n of e){let o=N.default.join(t,n);(await B.default.stat(o)).isFile()&&r.push(o)}return r}var Yn=t=>Buffer.byteLength(JSON.stringify(t),"utf8"),ur=(t,e=1048576)=>{let r=[],n=[],o=0;for(let s of t){let a=Yn(s);o+a>e&&(r.push(n),n=[],o=0),n.push(s),o+=a}return n.length>0&&r.push(n),r};var Jn=3e4;async function fr(){let t=Oe();if(!t)throw new Error("Currents config is missing!");let e=await cr(t);Mt(Vn(e.reportDir)),c("Reporter options: %o",e),V("Report directory: %s",e.reportDir);let r=await w(e.configFilePath);c("Report config: %o",r);let n=await pr(e.reportDir);c("Found %d instance results in the reportDir: %s",n.length,e.reportDir);let o=$n(e.reportDir),s=await Nt(o),a=it(e.reportDir),p=null;if(s){let C=await w(o);f("Marker file detected. The report was already uploaded: %o",{runUrl:C.response.runUrl,isoDate:C.isoDate})}if(await Nt(a)&&(p=await w(a),c("Full test suite file detected: %s",a)),p)c("The discovery stage was skipped");else{if(p=await ar(r,e.reportDir).getFullTestSuite(),Wn(p))throw new Error("Failed to discover the full test suite!");await gt(a,JSON.stringify(p))}let m=p.length===1?p[0].name:null,g={currents:t},R={type:r.framework,version:r.frameworkVersion,clientVersion:$,frameworkConfig:{originFramework:r.frameworkConfig?.originFramework,originFrameworkVersion:r.frameworkConfig?.originFrameworkVersion}},h=Y.userFacingNanoid(),M=Ht(t.ciBuildId),x={};for await(let C of n){let D=await w(C);x[D.groupId]||(x[D.groupId]=[]),x[D.groupId].push(D)}let Bt=await Be(e.reportDir);if(Bt){let C=await He({instances:Object.values(x).flat(),reportDir:e.reportDir,manifest:Bt});V("[currents] Attached %d Detox artifacts and %d steps",C.artifacts,C.steps)}let K=new Map;Object.values(x).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(P=>{P&&K.set(P.path,P.contentType)})})})})});for await(let C of Object.keys(x)){let D=x[C],A=C;m&&(c("Default group found: %s, overwriting the group in the results",m),A=m,D=D.map(U=>({...U,groupId:m})));try{let U=ur(D),P=await mr({ci:M,group:A,instances:[],fullTestSuite:p,config:g,machineId:h,framework:R});for(let pt=0;pt<U.length;pt++){let ut=await mr({ci:M,group:A,instances:U[pt],fullTestSuite:[],config:g,machineId:h,framework:R});ut.artifactUploadUrls&&ut.artifactUploadUrls.length>0&&await qn(ut.artifactUploadUrls,e.reportDir,K)}c("Api response: %o",P),V("[%s] Run created: %s",A,P.runUrl);let dr={response:P,isoDate:new Date().toISOString()};await gt(o,JSON.stringify(dr)),c("Marker file %s: %s",s?"overwritten":"created",o)}catch(U){throw c("Failed to upload the results to the dashboard"),U}}}async function mr({ci:t,group:e,instances:r,fullTestSuite:n,config:o,machineId:s,framework:a}){let p=await jt(),l=await Vt(),m={browserName:"node",browserVersion:lr.default.coerce(process.version)?.version},{currents:g}=o,h={platform:{...m,...l},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:a,instances:r,previousCiBuildId:process.env.CURRENTS_PREVIOUS_CI_BUILD_ID};return c("Creating run: %o",S(h)),De(h)}function $n(t){return ct.default.join(t,"upload.marker.json")}function Vn(t){return ct.default.join(t,`.debug-${new Date().toISOString()}.log`)}function Wn(t){return t.length===0||t.some(e=>e.tests.length===0)}async function qn(t,e,r){c("Uploading %d artifacts",t.length),await Promise.all(t.map(n=>{let o=ct.default.join(e,n.path),s=r.get(n.path)||"application/octet-stream";return Qn(o,s,n.uploadUrl)}))}var Qn=async(t,e,r)=>{try{if(!await Lt.default.pathExists(t)){f("Artifact file not found: %s",t);return}let n=await Lt.default.readFile(t);await Er.default.put(r,n,{headers:{"Content-Type":e},timeout:Jn})}catch(n){c("Failed to upload artifact %s: %o",t,n)}};0&&(module.exports={handleCurrentsReport});
10
10
  /*! For license information please see index.js.LEGAL.txt */
11
11
  //# sourceMappingURL=index.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@currents/cmd",
3
- "version": "2.0.0-beta.0",
3
+ "version": "2.0.1",
4
4
  "main": "./dist/index.js",
5
5
  "author": {
6
6
  "name": "Currents Software Inc",
@@ -45,17 +45,19 @@
45
45
  "@types/xml2js": "^0.4.14",
46
46
  "@types/xxhashjs": "^0.2.4",
47
47
  "jest": "^30.4.2",
48
+ "jest-cli": "^30.4.2",
49
+ "jest-config": "^30.4.2",
48
50
  "rimraf": "^6.0.1",
49
51
  "tsup": "^8.3.5",
50
52
  "typescript": "^5.9.3",
51
- "vitest": "^4.1.0"
53
+ "vitest": "^4.1.11"
52
54
  },
53
55
  "dependencies": {
54
56
  "@commander-js/extra-typings": "^14.0.0",
55
- "@currents/commit-info": "2.0.0-beta.0",
57
+ "@currents/commit-info": "2.0.0",
56
58
  "archiver": "^7.0.1",
57
59
  "async-retry": "^1.3.3",
58
- "axios": "1.18.1",
60
+ "axios": "1.20.0",
59
61
  "axios-retry": "4.5.0",
60
62
  "chalk": "^4.1.2",
61
63
  "commander": "^14.0.0",
@@ -66,8 +68,6 @@
66
68
  "getos": "^3.2.1",
67
69
  "globby": "^11.1.0",
68
70
  "https-proxy-agent": "^7.0.4",
69
- "jest-cli": "^30.2.0",
70
- "jest-config": "^30.3.0",
71
71
  "lodash": "^4.18.1",
72
72
  "nanoid": "^3.3.8",
73
73
  "pretty-ms": "^7.0.1",