@currents/cmd 2.0.1 → 2.0.2

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