@currents/cmd 1.11.0 → 2.0.0-beta.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/bin/index.js CHANGED
@@ -1,94 +1,63 @@
1
1
  #! /usr/bin/env node
2
- "use strict";var ss=Object.create;var fe=Object.defineProperty;var as=Object.getOwnPropertyDescriptor;var cs=Object.getOwnPropertyNames;var ps=Object.getPrototypeOf,ms=Object.prototype.hasOwnProperty;var us=(t,e)=>{for(var r in e)fe(t,r,{get:e[r],enumerable:!0})},ds=(t,e,r,o)=>{if(e&&typeof e=="object"||typeof e=="function")for(let n of cs(e))!ms.call(t,n)&&n!==r&&fe(t,n,{get:()=>e[n],enumerable:!(o=as(e,n))||o.enumerable});return t};var l=(t,e,r)=>(r=t!=null?ss(ps(t)):{},ds(e||!t||!t.__esModule?fe(r,"default",{value:t,enumerable:!0}):r,t));var bI=require("source-map-support/register");var os=require("@commander-js/extra-typings");var dr={name:"@currents/cmd",version:"1.11.0",main:"./dist/index.js",author:{name:"Currents Software Inc",email:"hello@currents.dev"},license:"MIT",repository:{type:"git",url:"https://github.com/currents-dev/currents-reporter"},description:"Currents CLI tools",scripts:{test:"vitest",rm:"rimraf dist",lint:'TIMING=1 eslint "**/*.ts*"',types:"tsc --noEmit",build:"tsup-node --minify --dts",dev:"tsup-node --watch --dts",release:"release-it","publish:npm":"npm run rm && npm run build && ./publish.js"},devDependencies:{"@jest/reporters":"^30.4.1","@jest/types":"^30.4.1","@release-it/conventional-changelog":"^12.0.0","release-it":"^21.0.2","@types/archiver":"^6.0.3","@types/async-retry":"^1.4.9","@types/debug":"^4.1.12","@types/fs-extra":"^11.0.4","@types/getos":"^3.0.4","@types/lodash":"^4.17.16","@types/node":"^25.5.0","@types/proxy-from-env":"^1.0.4","@types/semver":"^7.5.8","@types/tmp":"^0.2.6","@types/unzipper":"^0.10.11","@types/uuid":"^10.0.0","@types/xml2js":"^0.4.14","@types/xxhashjs":"^0.2.4",jest:"^30.4.2",rimraf:"^6.0.1",tsup:"^8.3.5",typescript:"^5.9.3",vitest:"^4.1.0"},dependencies:{"@commander-js/extra-typings":"^13.1.0","@currents/commit-info":"1.1.0",archiver:"^7.0.1","async-retry":"^1.3.3",axios:"1.18.1","axios-retry":"4.5.0",chalk:"^4.1.2",commander:"^13.1.0",debug:"^4.4.0",dotenv:"^17.4.2",execa:"^9.5.1","fs-extra":"^11.3.4",getos:"^3.2.1",globby:"^11.1.0","https-proxy-agent":"^7.0.4","jest-cli":"^30.2.0","jest-config":"^30.3.0",lodash:"^4.18.1",nanoid:"^3.3.8","pretty-ms":"^7.0.1","proxy-from-env":"^1.1.0",semver:"^7.8.5","source-map-support":"^0.5.21",tmp:"^0.2.7","tmp-promise":"^3.0.3","ts-pattern":"^5.8.0",unzipper:"^0.12.3",uuid:"11.1.1",xml2js:"^0.6.2",xxhashjs:"^0.2.2"},bin:{currents:"./dist/bin/index.js","currents-cli":"./dist/bin/index.js"},files:["dist","!**/*.map","!**/*/*.map"],keywords:["cloud test dashboard","test reporter","test results","currents","currents dashboard","ci"],exports:{".":{import:"./dist/index.js",require:"./dist/index.js",types:"./dist/index.d.ts"},"./discovery/jest":{import:"./dist/services/upload/discovery/jest/reporter.js",require:"./dist/services/upload/discovery/jest/reporter.js",types:"./dist/services/upload/discovery/jest/reporter.d.ts"},"./package.json":"./package.json"},"release-it":{npm:{publish:!1},github:{release:!0,releaseName:"${npm.name} v${version}"},plugins:{"@release-it/conventional-changelog":{preset:"angular",header:"# Changelog",ignoreVersion:!0,infile:"./CHANGELOG.md"}},git:{commitMessage:"chore: release ${npm.name} v${version}",tagName:"${npm.name}-v${version}"}}};var mt=dr.version;var tr=require("@commander-js/extra-typings");var ls=[];function le(t){ls.push(t)}var D=l(require("chalk")),j=l(require("util"));var ge=require("debug"),gs=l(require("fs-extra")),c=(0,ge.debug)("currents"),Es=null;function fr(){ge.debug.enable("currents,currents:*")}function lr(t){Es=t}var gr=[],Er=[];var St=(...t)=>{let e=j.default.format(...t);le(e),console.log(e)},Cs=(...t)=>{let e=j.default.format(...t);le(e),console.error(e)},O=St,R=(...t)=>{let e=j.default.format(...t);return Er.push(e),c("WARNING: ",e),St(D.default.bgYellow.black(" WARNING "),e)},ot=(...t)=>{let e=j.default.format(...Cr(t));return c("WARNING: ",j.default.format(...t)),St(D.default.bgYellow.black(" WARNING "),e)},Pt=(...t)=>St(D.default.green.bold(j.default.format(...t))),I=(...t)=>{let e=j.default.format(...Cr(t));return gr.push(e),c("ERROR: ",j.default.format(...t)),Cs(D.default.bgRed.white(" ERROR "),e)};var Cr=t=>t.map(e=>e instanceof Error?e.message:e),xt=(t=2)=>console.log(Array(t).fill("").join(`
3
- `)),jc=D.default.cyan,$c=D.default.blueBright,Vc=D.default.red,Yc=D.default.yellow,Jc=D.default.green,Wc=D.default.gray,qc=D.default.white,Qc=D.default.black,Xc=D.default.magenta,g=D.default.dim,zc=D.default.bold;var Xn=l(require("chalk"));function Ir(t,e){if(!t)return t;let r={...t};return e.forEach(o=>{r.hasOwnProperty(o)&&(r[o]="*****")}),r}function bt(t){return Ir(t,["apiKey"])}function T(t){return Ir(t,["recordKey","key"])}var X=class extends Error{};var G=l(require("fs-extra")),Tt=require("path"),Rr=require("uuid");async function nt(t){try{return await G.default.readJson(t)}catch(e){throw I("Error while reading JSON file: %s",t,e),I}}async function it(t,e){try{return await G.default.writeFile(t,e,"utf8"),t}catch(r){throw I(`Error writing file at ${t}:`,r),r}}async function _t(t,e){try{try{return await G.default.access(t),t}catch{return await G.default.writeFile(t,e,"utf8"),t}}catch(r){throw I(`Error writing file at ${t}:`,r),r}}async function Tr(t,e){if(e){await G.default.ensureDir(t);return}let r=(0,Tt.dirname)(t);await G.default.ensureDir(r)}function Rs(){let t=new Date().toISOString().replace(/[:.]/g,"-"),e=(0,Rr.v4)();return`${t}-${e}`}async function _r(t,e){let r=Rs(),o=(0,Tt.join)(t,e,r);return st(o)}async function st(t){try{return await G.default.ensureDir(t),c("Folder created",t),t}catch(e){throw I(`Failed to create folder at ${t}:`,e),e}}async function wt(t,e){try{return await G.default.ensureDir((0,Tt.dirname)(e)),await G.default.copy(t,e),c("File copied from %s to %s",t,e),e}catch(r){throw I(`Failed to copy file from ${t} to ${e}:`,r),r}}var hr=l(require("crypto"));function $(t){return hr.createHash("sha256").update(t).digest("base64").slice(0,8).replace(/\+/g,"-").replace(/\//g,"_").replace(/=+$/,"")}var Nt={};us(Nt,{getNanoid:()=>Ts,userFacingNanoid:()=>Ce});var Ee=require("nanoid"),Or="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz",Ts=(t=16)=>(0,Ee.customAlphabet)(Or,t)(),Ce=(0,Ee.customAlphabet)(Or,12);function yr(t){return Object.entries(t??{}).reduce((e,[r,o])=>o===void 0?e:{...e,[r]:o},{})}function Ar(t){if(!(t===void 0||t.trim()===""))return!["false","0","no","off"].includes(t.trim().toLowerCase())}function _(t,e){return"env"in t[e]&&t[e].env?t[e].env:""}function Bt(t,e){return t[e].cli}function Lt(t,e){return t[e].name}function M(t,e,r,o,n){let i={...yr(o),...yr(r())};return e.forEach(s=>{if(!i[s])throw I(`${Lt(t,s)} is required for Currents Reporter. Use the following methods to set the value:
4
- - as environment variable: ${g(_(t,s))}
5
- - as CLI flag of the command: ${g(Bt(t,s))}`),new X("Missing required config variable")}),typeof n=="function"&&n(i),i}var _s={apiKey:{name:"Api Key",env:"CURRENTS_API_KEY",cli:"--api-key"},debug:{name:"Debug",env:"CURRENTS_DEBUG",cli:"--debug"}},hs={branch:{name:"Run Branch",cli:"--branch"},output:{name:"Output Path",env:"CURRENTS_OUTPUT",cli:"--output"},ciBuildId:{name:"CI Build ID",cli:"--ci-build-id"},projectId:{name:"Project ID",env:"CURRENTS_PROJECT_ID",cli:"--project-id"},tag:{name:"Run Tag",cli:"--tag"}},V={..._s,...hs};function Ur(){return{apiKey:process.env[V.apiKey.env],debug:!!process.env[V.debug.env]}}var Os=c.extend("config"),ys=["apiKey","projectId"],As=t=>{let{ciBuildId:e,tag:r,branch:o}=t;if(!([e,r,o].filter(Boolean).length===1||r&&o&&!e))throw I('"ciBuildId", "tag", "branch" or a combination of "tag" and "branch" are expected to be provided'),new X("Missing or invalid parameters")},Ie=null;function Dr(t){Ie=M(V,ys,Ur,t,As),Os("Resolved config: %o",bt(Ie))}function Mt(){return Ie}var eo=require("fs/promises");var $r=l(require("lodash"));var Lr=l(require("axios")),Mr=l(require("axios-retry")),Oe=l(require("lodash"));var Sr=()=>process.env.CURRENTS_API_URL??"https://cy.currents.dev",Pr=()=>process.env.CURRENTS_REST_API_URL??"https://api.currents.dev",xr=()=>3e4;var Re=require("axios"),Te=l(require("pretty-ms"));var br=c.extend("http"),vt=t=>[3*1e3,15*1e3,30*1e3][t-1],wr=t=>(br("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,Re.isAxiosError)(t)}),"code"in t&&t.code&&["ECONNABORTED","ECONNREFUSED","ECONNRESET","ETIMEDOUT","ENETRESET"].includes(t.code)?!0:(0,Re.isAxiosError)(t)?[429,502,503,504].includes(t.response?.status??0):!1),Ft=()=>3;function Nr(t,e,r){br("Network request '%s' failed: '%s'. Next attempt is in %s (%d/%d).",`${r.method?.toUpperCase()} ${r.url}`,e.message,(0,Te.default)(vt(t)),t,Ft()),R("Network request '%s' failed: '%s'. Next attempt is in %s (%d/%d).",`${r.method?.toUpperCase()} ${r.url}`,e.message,(0,Te.default)(vt(t)),t,Ft())}var _e=c.extend("http");var he={api:null,restApi:null};function Us(t){let e=t==="api"?Sr():Pr();_e("client base url: %s",e);let r=Lr.default.create({baseURL:e,timeout:xr(),transitional:{clarifyTimeoutError:!0}});return r.interceptors.request.use(o=>{let n=o["axios-retry"]?.retryCount??0;o.headers.set({"x-cmd-version":mt}),o.headers.get("Content-Type")||o.headers.set("Content-Type","application/json");let i={...Oe.default.pick(o,"method","url","headers"),baseURL:e,data:Buffer.isBuffer(o.data)?"buffer":o.data,params:o.params};return n?_e("network request retry: %o",Br({...i,baseURL:e,isRetry:!0})):_e("network request: %o",Br(i)),o}),(0,Mr.default)(r,{retries:Ft(),retryCondition:wr,retryDelay:vt,shouldResetTimeout:!0,onRetry:Nr}),r}function vr(t){return he[t]===null&&(he[t]=Us(t)),he[t]}function Br(t){return{method:t.method,baseURL:t.baseURL,url:t.url,data:t.isRetry?"<retry>":Ds(t.data),params:t.isRetry?"<retry>":t.params,headers:{...t.headers,Authorization:"Bearer ***","x-currents-key":"***"}}}function Ds(t){return t?.results?.raw?T({...t,results:{...t.results,raw:"***"}}):Oe.default.isPlainObject(t)?T(t):t}var Gr=require("axios"),Hr=l(require("lodash")),S=require("ts-pattern");function Kr(t){(0,S.match)(t).when(Gr.isAxiosError,Ss).otherwise(()=>{R("Unexpected error while sending network request: %s",t)})}function Ss(t){return(0,S.match)(t).with({code:"ECONNABORTED"},()=>{R("Network connection aborted")}).with({code:"ECONNREFUSED"},()=>{R("Network connection aborted")}).with({code:"ECONNRESET"},()=>{R("Network connection reset")}).with({code:"ETIMEDOUT"},()=>{R("Network connection timeout")}).with({response:S.P.not(S.P.nullish)},e=>{Ps(e,{status:e.response.status,data:e.response.data})}).otherwise(e=>{R(`[currents] Unexpected network error: %s
6
- %O`,t.message,{method:t.response?.config.method,url:t.response?.config.url,status:t.response?.status,payload:t.response?.config.data})})}function Ps(t,{status:e,data:r}){(0,S.match)(e).with(401,()=>{R(`[currents] ${t.response?.config.method} ${t.response?.config.url}} - 401 Unauthorized Request from cloud service`)}).with(400,()=>{R(`[currents] ${t.response?.config.method} ${t.response?.config.url} - 400 Bad Request from cloud service:
7
- %o`,r)}).with(404,()=>{R(`[currents] ${t.response?.config.method} ${t.response?.config.url} - 404 Not Found from cloud service`)}).with(429,()=>{R(`[currents] ${t.response?.config.method} ${t.response?.config.url} - 429 Too Many Requests from cloud service`)}).with(422,()=>{xs(t,r)}).otherwise(()=>{R(`[currents] Unexpected network response: %s
8
- %O`,t.message,{method:t.response?.config.method,url:t.response?.config.url,status:t.response?.status})})}function xs(t,e){(0,S.match)(e).with({code:Fr.MISSING_SUITE,message:S.P.string,errors:S.P.array(S.P.string)},async r=>{let{message:o,errors:n}=r;xt(1),I(...kr(o,n))}).with({code:Fr.RUN_EXPIRED,message:S.P.string},r=>{R(r.message)}).with({message:S.P.string,errors:S.P.array(S.P.string)},r=>{let{message:o,errors:n}=r;xt(1),R(...kr(o,n)),xt(1)}).otherwise(()=>{R(`[currents] Unexpected network response: %s
9
- %O`,t.message,{method:t.response?.config.method,url:t.response?.config.url,status:t.response?.status})})}var Fr={RUN_CANCELLED:"RUN_CANCELLED",RUN_EXPIRED:"RUN_EXPIRED",MISSING_SUITE:"MISSING_SUITE"};function kr(t,e){return Hr.default.isString(t)?e?.length===0?[t]:[t,`
2
+ "use strict";var vc=Object.create;var lr=Object.defineProperty;var Mc=Object.getOwnPropertyDescriptor;var Fc=Object.getOwnPropertyNames;var kc=Object.getPrototypeOf,Gc=Object.prototype.hasOwnProperty;var $c=(t,e)=>{for(var r in e)lr(t,r,{get:e[r],enumerable:!0})},Kc=(t,e,r,o)=>{if(e&&typeof e=="object"||typeof e=="function")for(let n of Fc(e))!Gc.call(t,n)&&n!==r&&lr(t,n,{get:()=>e[n],enumerable:!(o=Mc(e,n))||o.enumerable});return t};var l=(t,e,r)=>(r=t!=null?vc(kc(t)):{},Kc(e||!t||!t.__esModule?lr(r,"default",{value:t,enumerable:!0}):r,t));var UO=require("source-map-support/register");var Nc=require("@commander-js/extra-typings");var bo={name:"@currents/cmd",version:"2.0.0-beta.0",main:"./dist/index.js",author:{name:"Currents Software Inc",email:"hello@currents.dev"},license:"MIT",repository:{type:"git",url:"https://github.com/currents-dev/currents-reporter"},description:"Currents CLI tools",engines:{node:">=20"},scripts:{test:"vitest",rm:"rimraf dist",lint:'TIMING=1 eslint "**/*.ts*"',types:"tsc --noEmit",build:"tsup-node --minify --dts",dev:"tsup-node --watch --dts",release:"release-it","publish:npm":"npm run rm && npm run build && ./publish.js"},devDependencies:{"@jest/reporters":"^30.4.1","@jest/types":"^30.4.1","@release-it/conventional-changelog":"^12.0.0","release-it":"^21.0.2","@types/archiver":"^6.0.3","@types/async-retry":"^1.4.9","@types/debug":"^4.1.12","@types/fs-extra":"^11.0.4","@types/getos":"^3.0.4","@types/lodash":"^4.17.16","@types/node":"^25.5.0","@types/proxy-from-env":"^1.0.4","@types/semver":"^7.5.8","@types/tmp":"^0.2.6","@types/unzipper":"^0.10.11","@types/uuid":"^10.0.0","@types/xml2js":"^0.4.14","@types/xxhashjs":"^0.2.4",jest:"^30.4.2",rimraf:"^6.0.1",tsup:"^8.3.5",typescript:"^5.9.3",vitest:"^4.1.0"},dependencies:{"@commander-js/extra-typings":"^14.0.0","@currents/commit-info":"2.0.0-beta.0",archiver:"^7.0.1","async-retry":"^1.3.3",axios:"1.18.1","axios-retry":"4.5.0",chalk:"^4.1.2",commander:"^14.0.0",debug:"^4.4.0",dotenv:"^17.4.2",execa:"^9.5.1","fs-extra":"^11.3.4",getos:"^3.2.1",globby:"^11.1.0","https-proxy-agent":"^7.0.4","jest-cli":"^30.2.0","jest-config":"^30.3.0",lodash:"^4.18.1",nanoid:"^3.3.8","pretty-ms":"^7.0.1","proxy-from-env":"^1.1.0",semver:"^7.8.5","source-map-support":"^0.5.21",tmp:"^0.2.7","tmp-promise":"^3.0.3","ts-pattern":"^5.8.0",unzipper:"^0.12.3",uuid:"11.1.1",xml2js:"^0.6.2",xxhashjs:"^0.2.2"},bin:{currents:"./dist/bin/index.js","currents-cli":"./dist/bin/index.js"},files:["dist","!**/*.map","!**/*/*.map"],keywords:["cloud test dashboard","test reporter","test results","currents","currents dashboard","ci"],exports:{".":{import:"./dist/index.js",require:"./dist/index.js",types:"./dist/index.d.ts"},"./discovery/jest":{import:"./dist/services/upload/discovery/jest/reporter.js",require:"./dist/services/upload/discovery/jest/reporter.js",types:"./dist/services/upload/discovery/jest/reporter.d.ts"},"./package.json":"./package.json"},"release-it":{npm:{publish:!1},github:{release:!0,releaseName:"${npm.name} v${version}"},plugins:{"@release-it/conventional-changelog":{preset:{name:"conventionalcommits"},header:"# Changelog",ignoreVersion:!0,infile:"./CHANGELOG.md"}},git:{commitMessage:"chore: release ${npm.name} v${version}",tagName:"${npm.name}-v${version}"}}};var xt=bo.version;var no=require("@commander-js/extra-typings");var jc=[];function fr(t){jc.push(t)}var b=l(require("chalk")),Y=l(require("util"));var gr=require("debug"),Vc=l(require("fs-extra")),p=(0,gr.debug)("currents"),Jc=null;function No(){gr.debug.enable("currents,currents:*")}function Lo(t){Jc=t}var Bo=[],vo=[];var ne=(...t)=>{let e=Y.default.format(...t);fr(e),console.log(e)},Mo=(...t)=>{let e=Y.default.format(...t);fr(e),console.error(e)},T=ne,E=(...t)=>{let e=Y.default.format(...t);return vo.push(e),p("WARNING: ",e),ne(b.default.bgYellow.black(" WARNING "),e)},gt=(...t)=>{let e=Y.default.format(...Fo(t));return p("WARNING: ",Y.default.format(...t)),ne(b.default.bgYellow.black(" WARNING "),e)},se=(...t)=>Mo(b.default.bgYellow.black(" WARNING "),Y.default.format(...t)),ie=(...t)=>ne(b.default.green.bold(Y.default.format(...t))),C=(...t)=>{let e=Y.default.format(...Fo(t));return Bo.push(e),p("ERROR: ",Y.default.format(...t)),Mo(b.default.bgRed.white(" ERROR "),e)};var Fo=t=>t.map(e=>e instanceof Error?e.message:e),ae=(t=2)=>console.log(Array(t).fill("").join(`
3
+ `)),Mu=b.default.cyan,Fu=b.default.blueBright,ku=b.default.red,Gu=b.default.yellow,$u=b.default.green,Ku=b.default.gray,Hu=b.default.white,ju=b.default.black,Vu=b.default.magenta,x=b.default.dim,Ju=b.default.bold;var ko=80,hr=" ",Wc=" ";function qc(t){let e=t.match(/"[^"]*"|'[^']*'|\S+/g)??[],r=[];for(let o of e){let n=r[r.length-1];n?.startsWith("-")&&!n.includes(" ")&&!o.startsWith("-")?r[r.length-1]=`${n} ${o}`:r.push(o)}return r}function zc(t){if(t.includes(`
4
+ `))return t.split(`
5
+ `).map(o=>hr+o);let e=[],r=hr;for(let o of qc(t)){let n=r.trim()==="";!n&&r.length+1+o.length+2>ko?(e.push(`${r} \\`),r=Wc+o):r=n?r+o:`${r} ${o}`}return[...e,r]}function Qc(t){let e=`${hr}# `,r=[],o=e;for(let n of t.split(" "))o!==e&&o.length+1+n.length>ko?(r.push(o),o=e+n):o=o===e?o+n:`${o} ${n}`;return[...r,o].map(n=>x(n))}function y(t){return`
6
+ Examples:
7
+ ${t.map(r=>[...Qc(r.comment),...r.commands.flatMap(zc)].join(`
8
+ `)).join(`
9
+
10
+ `)}
11
+ `}var Er=l(require("lodash")),Xc=["apiKey","recordKey","key"];function Go(t,e){return Er.default.isPlainObject(t)?Er.default.mapValues(t,(r,o)=>e.includes(o)&&r!==void 0?"*****":Go(r,e)):t}function h(t){return Go(t,Xc)}var W=class extends Error{};var q=l(require("fs-extra")),jt=require("path"),$o=require("uuid");async function ht(t){try{return await q.default.readJson(t)}catch(e){throw C("Error while reading JSON file: %s",t,e),C}}async function Et(t,e){try{return await q.default.writeFile(t,e,"utf8"),t}catch(r){throw C(`Error writing file at ${t}:`,r),r}}async function Vt(t,e){try{try{return await q.default.access(t),t}catch{return await q.default.writeFile(t,e,"utf8"),t}}catch(r){throw C(`Error writing file at ${t}:`,r),r}}async function Ko(t,e){if(e){await q.default.ensureDir(t);return}let r=(0,jt.dirname)(t);await q.default.ensureDir(r)}function Zc(){let t=new Date().toISOString().replace(/[:.]/g,"-"),e=(0,$o.v4)();return`${t}-${e}`}async function Ho(t,e){let r=Zc(),o=(0,jt.join)(t,e,r);return It(o)}async function It(t){try{return await q.default.ensureDir(t),p("Folder created",t),t}catch(e){throw C(`Failed to create folder at ${t}:`,e),e}}async function ce(t,e){try{return await q.default.ensureDir((0,jt.dirname)(e)),await q.default.copy(t,e),p("File copied from %s to %s",t,e),e}catch(r){throw C(`Failed to copy file from ${t} to ${e}:`,r),r}}var jo=l(require("crypto"));function et(t){return jo.createHash("sha256").update(t).digest("base64").slice(0,8).replace(/\+/g,"-").replace(/\//g,"_").replace(/=+$/,"")}var pe={};$c(pe,{getNanoid:()=>Cr,userFacingNanoid:()=>Tr});var Ir=require("nanoid"),Vo="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz",Cr=(t=16)=>(0,Ir.customAlphabet)(Vo,t)(),Tr=(0,Ir.customAlphabet)(Vo,12);function yr(t){return t.replace(/^([a-z][a-z0-9+.-]*:\/\/)[^/?#\s]*@/i,"$1")}function At(t){return yr(t).replace(/[?#].*$/,"")}function tp(t){return Object.entries(t??{}).reduce((e,[r,o])=>o===void 0?e:{...e,[r]:o},{})}function Jo(t){if(!(t===void 0||t.trim()===""))return!["false","0","no","off"].includes(t.trim().toLowerCase())}function N(t,e){return"env"in t[e]&&t[e].env?t[e].env:""}function de(t,e){return t[e].cli}function me(t,e){return t[e].name}function U(t,e,r,o){let n=tp(r);return e.forEach(s=>{if(!n[s]){let i=s,c=N(t,i);throw C(`${me(t,i)} is required: pass ${x(de(t,i))}${c?` or set ${x(c)}`:""}`),new W("Missing required config variable")}}),typeof o=="function"&&o(n),n}var _={apiKey:{name:"API key",env:"CURRENTS_API_KEY",cli:"--api-key"},recordKey:{name:"Record key",env:"CURRENTS_RECORD_KEY",cli:"--key"},projectId:{name:"Project ID",env:"CURRENTS_PROJECT_ID",cli:"--project-id"},ciBuildId:{name:"CI build ID",env:"CURRENTS_CI_BUILD_ID",cli:"--ci-build-id"},machineId:{name:"Machine ID",env:"CURRENTS_MACHINE_ID",cli:"--machine-id"},tag:{name:"Tag",cli:"--tag"},debug:{name:"Debug",env:"CURRENTS_DEBUG",cli:"--debug"}};var{apiKey:ep,debug:rp,ciBuildId:op,projectId:np,tag:sp}=_,ue={apiKey:ep,debug:rp,ciBuildId:op,projectId:np,tag:sp,branch:{name:"Branch",cli:"--branch"},output:{name:"Output file",env:"CURRENTS_OUTPUT",cli:"--output"}};var ip=p.extend("config"),ap=["apiKey","projectId"],cp=t=>{let{ciBuildId:e,tag:r,branch:o}=t;if(!([e,r,o].filter(Boolean).length===1||r&&o&&!e))throw C("Pass --ci-build-id, or --branch, --tag or both"),new W("Missing or invalid parameters")},Rr=null;function Yo(t){Rr=U(ue,ap,t,cp),ip("Resolved config: %o",h(Rr))}function le(){return Rr}var Sn=require("fs/promises");function St({apiKey:t,recordKey:e}){return e?{"x-currents-key":e}:t?{Authorization:`Bearer ${t}`}:{}}var mn=l(require("lodash"));var rn=l(require("axios")),on=l(require("axios-retry")),Ar=l(require("lodash"));var Wo=()=>process.env.CURRENTS_API_URL??"https://cy.currents.dev",Jt=()=>process.env.CURRENTS_REST_API_URL??"https://api.currents.dev",qo=()=>3e4;var fe=require("axios"),_r=l(require("pretty-ms"));var Qo=p.extend("http"),zo=[3*1e3,15*1e3,30*1e3],Xo=60*1e3;function Ee(t,e=Date.now()){let r=t?.response?.headers?.["retry-after"];if(r==null||r==="")return;let o=Number(r);if(Number.isFinite(o))return Math.max(0,o*1e3);let n=Date.parse(String(r));return Number.isNaN(n)?void 0:Math.max(0,n-e)}var ge=(t,e)=>{let r=zo[Math.min(t,zo.length)-1],o=Ee(e);return o===void 0?r:Math.min(Math.max(o,r),Xo)},wr=t=>(Qo("isRetriableError: %o",{message:t.message,code:"code"in t?t.code:void 0,status:"response"in t?t.response?.status:void 0,headers:"response"in t?t.response?.headers:void 0,data:"response"in t?t.response?.data:void 0,isAxiosError:(0,fe.isAxiosError)(t)}),"code"in t&&t.code&&["ECONNABORTED","ECONNREFUSED","ECONNRESET","ETIMEDOUT","ENETRESET"].includes(t.code)?!0:(0,fe.isAxiosError)(t)?[408,429,502,503,504].includes(t.response?.status??0):!1),pp=["get","head","options","put","delete"],Zo=t=>{if(!(0,fe.isAxiosError)(t))return!1;let e=t.response?.status;if(e===429){let r=Ee(t);return r===void 0||r<=Xo}return pp.includes(t.config?.method?.toLowerCase()??"get")?wr(t):e===408||t.code==="ECONNREFUSED"||t.code==="ENOTFOUND"},he=()=>3;function tn(t,e,r){Qo("Network request '%s' failed: '%s'. Next attempt is in %s (%d/%d).",`${r.method?.toUpperCase()} ${r.url}`,e.message,(0,_r.default)(ge(t,e)??0),t,he()),E("Network request '%s' failed: '%s'. Next attempt is in %s (%d/%d).",`${r.method?.toUpperCase()} ${r.url}`,e.message,(0,_r.default)(ge(t,e)??0),t,he())}var Or=p.extend("http");var xr={api:null,restApi:null};function dp(t){let e=t==="api"?Wo():Jt();Or("client base url: %s",e);let r=rn.default.create({baseURL:e,timeout:qo(),transitional:{clarifyTimeoutError:!0}});return r.interceptors.request.use(o=>{let n=o["axios-retry"]?.retryCount??0;o.headers.set({"x-cmd-version":xt}),o.headers.get("Content-Type")||o.headers.set("Content-Type","application/json");let s={...Ar.default.pick(o,"method","url","headers"),baseURL:e,data:Buffer.isBuffer(o.data)?"buffer":o.data,params:o.params};return n?Or("network request retry: %o",en({...s,baseURL:e,isRetry:!0})):Or("network request: %o",en(s)),o}),(0,on.default)(r,{retries:he(),retryCondition:t==="restApi"?Zo:wr,retryDelay:(o,n)=>ge(o,n),shouldResetTimeout:!0,onRetry:tn}),r}function Ut(t){return xr[t]===null&&(xr[t]=dp(t)),xr[t]}function en(t){return{method:t.method,baseURL:t.baseURL,url:t.url,data:t.isRetry?"<retry>":mp(t.data),params:t.isRetry?"<retry>":t.params,headers:{...t.headers,Authorization:"Bearer ***","x-currents-key":"***"}}}function mp(t){if(t?.results?.raw)return h({...t,results:{...t.results,raw:"***"}});if(typeof t=="string")try{return h(JSON.parse(t))}catch{return t}return Ar.default.isPlainObject(t)?h(t):t}var an=require("axios"),cn=l(require("lodash")),B=require("ts-pattern");function pn(t){(0,B.match)(t).when(an.isAxiosError,up).otherwise(()=>{E("Unexpected error while sending network request: %s",t)})}function up(t){return(0,B.match)(t).with({code:"ECONNABORTED"},()=>{E("Network connection aborted")}).with({code:"ECONNREFUSED"},()=>{E("Network connection aborted")}).with({code:"ECONNRESET"},()=>{E("Network connection reset")}).with({code:"ETIMEDOUT"},()=>{E("Network connection timeout")}).with({response:B.P.not(B.P.nullish)},e=>{lp(e,{status:e.response.status,data:e.response.data})}).otherwise(e=>{E(`[currents] Unexpected network error: %s
12
+ %O`,t.message,{method:t.response?.config.method,url:t.response?.config.url,status:t.response?.status,payload:t.response?.config.data})})}function lp(t,{status:e,data:r}){(0,B.match)(e).with(401,()=>{E(`[currents] ${t.response?.config.method} ${t.response?.config.url} - 401 Unauthorized Request from cloud service`)}).with(400,()=>{E(`[currents] ${t.response?.config.method} ${t.response?.config.url} - 400 Bad Request from cloud service:
13
+ %o`,r)}).with(404,()=>{E(`[currents] ${t.response?.config.method} ${t.response?.config.url} - 404 Not Found from cloud service`)}).with(429,()=>{E(`[currents] ${t.response?.config.method} ${t.response?.config.url} - 429 Too Many Requests from cloud service`)}).with(422,()=>{fp(t,r)}).otherwise(()=>{E(`[currents] Unexpected network response: %s
14
+ %O`,t.message,{method:t.response?.config.method,url:t.response?.config.url,status:t.response?.status})})}function fp(t,e){(0,B.match)(e).with({code:nn.MISSING_SUITE,message:B.P.string,errors:B.P.array(B.P.string)},async r=>{let{message:o,errors:n}=r;ae(1),C(...sn(o,n))}).with({code:nn.RUN_EXPIRED,message:B.P.string},r=>{E(r.message)}).with({message:B.P.string,errors:B.P.array(B.P.string)},r=>{let{message:o,errors:n}=r;ae(1),E(...sn(o,n)),ae(1)}).otherwise(()=>{E(`[currents] Unexpected network response: %s
15
+ %O`,t.message,{method:t.response?.config.method,url:t.response?.config.url,status:t.response?.status})})}var nn={RUN_CANCELLED:"RUN_CANCELLED",RUN_EXPIRED:"RUN_EXPIRED",MISSING_SUITE:"MISSING_SUITE"};function sn(t,e){return cn.default.isString(t)?e?.length===0?[t]:[t,`
10
16
  ${(e??[]).map(r=>` - ${r}`).join(`
11
17
  `)}
12
- `]:["Unexpected network error"]}var jr=c.extend("http");async function H(t,e,r=vr){try{let o=await r(t).request(e);return jr("network response: %o",{...$r.default.omit(o,"request","config"),url:o.config.url,method:o.config.method}),o}catch(o){let n=o;throw jr("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}),Kr(n),n}}var ut=c.extend("api");async function Vr(t){try{return ut("Request params: %o",T(t)),H("api",{url:"cache/upload",method:"POST",data:t}).then(e=>e.data)}catch(e){throw ut("Failed to create cache:",e),e}}async function Yr(t){try{return ut("Request params: %o",t),H("api",{url:"cache/v2/download",method:"POST",data:t}).then(e=>e.data)}catch(e){throw ut("Failed to retrieve cache:",e),e}}async function Jr(t){try{return ut("Request params: %o",t),H("api",{url:"cache/meta",method:"POST",data:t}).then(e=>e.data)}catch(e){throw ut("Failed to retrieve reference cache meta:",e),e}}var bs=c.extend("api");async function Wr(t){return bs("Cancel params: %o",T(t)),(await H("api",{url:"v1/runs/cancel",method:"POST",data:t})).data}var Qr=require("util"),Xr=require("zlib");var qr=c.extend("api"),ws=(0,Qr.promisify)(Xr.gzip);async function zr(t){try{qr("Run params: %o",T(t));let e=await Ns(JSON.stringify(t));return H("api",{url:"v1/runs",method:"POST",headers:{"Content-Type":"application/json","Content-Encoding":"gzip"},data:e}).then(r=>r.data)}catch(e){throw qr("Failed to create the run:",e),e}}async function Ns(t){try{return await ws(t)}catch(e){throw I("Failed to compress run payload:",e),e}}var Zr=c.extend("api");async function to(t,e){try{return Zr("Run params: %o",e),H("restApi",{url:"v1/runs/find",params:e,method:"GET",headers:{"Content-Type":"application/json",Authorization:`Bearer ${t}`}}).then(r=>r.data)}catch(r){throw Zr("Failed to obtain run data:",r),r}}async function Ae(){try{let t=Mt();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 to(t.apiKey,e);await Bs(t.pwLastRun&&r.data.pwLastRun?r.data.pwLastRun:r.data,t)}catch(t){throw c("Failed to get run data"),t}}async function Bs(t,e){let r=JSON.stringify(t,null,2);e.output?(await Tr(e.output),await(0,eo.writeFile)(e.output,r,"utf-8"),O(`Successfully written to ${e.output}`)):O(r)}var Ho=require("axios"),He=l(require("path"));var P=require("@commander-js/extra-typings");var Ls={recordKey:{name:"Record Key",env:"CURRENTS_RECORD_KEY",cli:"--key"},debug:{name:"Debug",env:"CURRENTS_DEBUG",cli:"--debug"}},Ms={id:{name:"Cache id",cli:"--id"},preset:{name:"Preset",cli:"--preset"},pwOutputDir:{name:"Playwright output directory",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"}},vs={id:{name:"Cache id",cli:"--id"},preset:{name:"Preset",cli:"--preset"},outputDir:{name:"Custom directory to write output",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"}},z={...Ls,...Ms,...vs};function Ue(){return{recordKey:process.env[z.recordKey.env],debug:process.env[z.debug.env]}}var ro=c.extend("config"),oo=["recordKey"],at;function no(t){at={type:"SET_COMMAND_CONFIG",values:M(z,oo,Ue,t)},ro("Resolved config: %o",{...at,values:T(at.values)})}function io(t){at={type:"GET_COMMAND_CONFIG",values:M(z,oo,Ue,t)},ro("Resolved config: %o",{...at,values:T(at.values)})}function Z(){return at}function so(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 ao(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 co=require("@commander-js/extra-typings");function dt(t,e=[]){return t?e.concat(t.split(",").map(r=>r.trim())):e}async function N(t,e){try{e.debug&&fr(),await t(e),process.exit(0)}catch(r){I(r.message);let o=r instanceof co.CommanderError?r.exitCode:1;process.exit(o)}}var De=new P.Option("-k, --key <record-key>","Your secret Record Key obtained from Currents").env(_(z,"recordKey")),Se=new P.Option("--debug","Enable debug logging").env(_(z,"debug")).default(!1),Pe=new P.Option("--id <id>","The ID the data is saved under in the cache"),po=new P.Option("--path <path>",'Comma-separated list of paths to cache, enquote for globs e.g. "dist/**/*"').argParser(dt),kt=(e=>(e.lastRun="last-run",e))(kt||{}),xe=new P.Option("--preset <preset-name>",'A set of predefined options. Use "last-run" to get the last run data').choices(Object.values(kt)),mo=new P.Option("--output-dir <dir>","Path to the directory where output will be written"),uo=new P.Option("--pw-output-dir <dir>","Directory for artifacts produced by Playwright tests").default("test-results"),ht=".currents_env",fo=new P.Option("--preset-output <path>","Path to the file containing the preset output").default(ht),be=new P.Option("--matrix-index <number>","The index of the matrix to use").default(1).argParser(lo),we=new P.Option("--matrix-total <number>","The total number of matrices available").default(1).argParser(lo);function lo(t){let e=parseInt(t,10);if(isNaN(e)||e<=0||!Number.isInteger(e))throw new P.InvalidArgumentError("A positive integer is expected.");return e}var go=new P.Option("--continue","Continue the script execution if the cache is not found").default(!1),Eo=new P.Option("--continue","Continue the script execution if upload paths are not found").default(!1);var h=require("lodash");var Gt=c.extend("ci"),Fs=(t,...e)=>(0,h.chain)(e).compact().join(t).value(),ks=(t,e)=>(0,h.set)(t,(0,h.camelCase)(e),process.env[e]),A=t=>(0,h.transform)(t,ks,{}),Gs=()=>process.env.TF_BUILD&&process.env.AZURE_HTTP_USER_AGENT,Hs=()=>(0,h.some)(process.env,(t,e)=>/^CODEBUILD_/.test(e)),Ks=()=>process.env.bamboo_buildNumber,js=()=>(0,h.some)(process.env,(t,e)=>/^CONCOURSE_/.test(e)),$s=()=>process.env.GITLAB_CI||process.env.CI_SERVER_NAME&&/^GitLab/.test(process.env.CI_SERVER_NAME),Vs=()=>!!(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),Ys=()=>process.env.JENKINS_URL||process.env.JENKINS_HOME||process.env.JENKINS_VERSION||process.env.HUDSON_URL||process.env.HUDSON_HOME,Js={appveyor:"APPVEYOR",azure:Gs,awsCodeBuild:Hs,bamboo:Ks,bitbucket:"BITBUCKET_BUILD_NUMBER",buildkite:"BUILDKITE",circle:"CIRCLECI",concourse:js,codeFresh:"CF_BUILD_ID",drone:"DRONE",githubActions:"GITHUB_ACTIONS",gitlab:$s,goCD:"GO_JOB_NAME",jenkins:Ys,googleCloud:Vs,semaphore:"SEMAPHORE",teamcity:"TEAMCITY_VERSION",travis:"TRAVIS",netlify:"NETLIFY"};function Ws(){let{env:t}=process;return(0,h.findKey)(Js,e=>{if((0,h.isString)(e))return t[e];if((0,h.isFunction)(e))return e()})}var Co=()=>({appveyor:A(["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:A(["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:A(["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:A(["bamboo_buildNumber","bamboo_buildResultsUrl","bamboo_planRepository_repositoryUrl","bamboo_buildKey"]),bitbucket:A(["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:A(["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:A(["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:A(["BUILD_ID","BUILD_NAME","BUILD_JOB_NAME","BUILD_PIPELINE_NAME","BUILD_TEAM_NAME","ATC_EXTERNAL_URL"]),codeFresh:A(["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:A(["DRONE_BUILD_LINK","DRONE_BUILD_NUMBER","DRONE_PULL_REQUEST"]),githubActions:A(["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:A(["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:A(["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:A(["BUILD_ID","PROJECT_ID","REPO_NAME","BRANCH_NAME","TAG_NAME","COMMIT_SHA","SHORT_SHA"]),jenkins:A(["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:A(["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:A(["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:A(["BUILD_ID","CONTEXT","URL","DEPLOY_URL","DEPLOY_PRIME_URL","DEPLOY_ID"])}),qs=()=>{let{env:t}=process;return{appveyor:{sha:t.APPVEYOR_REPO_COMMIT,branch:t.APPVEYOR_PULL_REQUEST_HEAD_REPO_BRANCH||t.APPVEYOR_REPO_BRANCH,message:Fs(`
13
- `,t.APPVEYOR_REPO_COMMIT_MESSAGE,t.APPVEYOR_REPO_COMMIT_MESSAGE_EXTENDED),authorName:t.APPVEYOR_REPO_COMMIT_AUTHOR,authorEmail:t.APPVEYOR_REPO_COMMIT_AUTHOR_EMAIL},awsCodeBuild:{sha:t.CODEBUILD_RESOLVED_SOURCE_VERSION,remoteOrigin:t.CODEBUILD_SOURCE_REPO_URL},azure:{sha:t.BUILD_SOURCEVERSION,branch:t.BUILD_SOURCEBRANCHNAME,message:t.BUILD_SOURCEVERSIONMESSAGE,authorName:t.BUILD_SOURCEVERSIONAUTHOR,authorEmail:t.BUILD_REQUESTEDFOREMAIL},bamboo:{sha:t.bamboo_planRepository_revision,branch:t.bamboo_planRepository_branch,authorName:t.bamboo_planRepository_username,remoteOrigin:t.bamboo_planRepository_repositoryURL},bitbucket:{sha:t.BITBUCKET_COMMIT,branch:t.BITBUCKET_BRANCH},buildkite:{sha:t.BUILDKITE_COMMIT,branch:t.BUILDKITE_BRANCH,message:t.BUILDKITE_MESSAGE,authorName:t.BUILDKITE_BUILD_CREATOR,authorEmail:t.BUILDKITE_BUILD_CREATOR_EMAIL,remoteOrigin:t.BUILDKITE_REPO,defaultBranch:t.BUILDKITE_PIPELINE_DEFAULT_BRANCH},circle:{sha:t.CIRCLE_SHA1,branch:t.CIRCLE_BRANCH,authorName:t.CIRCLE_USERNAME,remoteOrigin:t.CIRCLE_REPOSITORY_URL},codeFresh:{sha:t.CF_REVISION,branch:t.CF_BRANCH,message:t.CF_COMMIT_MESSAGE,authorName:t.CF_COMMIT_AUTHOR},drone:{sha:t.DRONE_COMMIT_SHA,branch:t.DRONE_SOURCE_BRANCH,message:t.DRONE_COMMIT_MESSAGE,authorName:t.DRONE_COMMIT_AUTHOR,authorEmail:t.DRONE_COMMIT_AUTHOR_EMAIL,remoteOrigin:t.DRONE_GIT_HTTP_URL,defaultBranch:t.DRONE_REPO_BRANCH},githubActions:{sha:t.GITHUB_SHA,branch:t.GH_BRANCH||t.GITHUB_REF,defaultBranch:t.GITHUB_BASE_REF,remoteBranch:t.GITHUB_HEAD_REF,runAttempt:t.GITHUB_RUN_ATTEMPT},gitlab:{sha:t.CI_COMMIT_SHA,branch:t.CI_COMMIT_REF_NAME,message:t.CI_COMMIT_MESSAGE,authorName:t.GITLAB_USER_NAME,authorEmail:t.GITLAB_USER_EMAIL,remoteOrigin:t.CI_REPOSITORY_URL,defaultBranch:t.CI_DEFAULT_BRANCH},googleCloud:{sha:t.COMMIT_SHA,branch:t.BRANCH_NAME},jenkins:{sha:t.GIT_COMMIT,branch:t.GIT_BRANCH},semaphore:{sha:t.SEMAPHORE_GIT_SHA,branch:t.SEMAPHORE_GIT_BRANCH,remoteOrigin:t.SEMAPHORE_GIT_REPO_SLUG},snap:null,teamcity:null,travis:{sha:t.TRAVIS_PULL_REQUEST_SHA||t.TRAVIS_COMMIT,branch:t.TRAVIS_PULL_REQUEST_BRANCH||t.TRAVIS_BRANCH,message:t.TRAVIS_COMMIT_MESSAGE},netlify:{sha:t.COMMIT_REF,branch:t.BRANCH,remoteOrigin:t.REPOSITORY_URL}}},Io=t=>{let e=Ro();return e?(0,h.chain)(t()).get(e).value():{}};function Qs(){return(0,h.chain)(Co()).omitBy(h.isNull).keys().value()}function Xs(t){return t&&Qs().includes(t)}function Ro(){let t=Ws();return Gt("detected CI provider name: %s",t),t||null}function zs(){return Io(Co)}function To(){return Io(qs)}function ft(t){let e=zs(),r=Ro(),o=Zs(t,r);return Gt("detected CI provider: %s",r),Gt("detected CI params: %O",e),Gt("detected CI build ID: %o",o),{params:e,provider:r,ciBuildId:o}}function Zs(t,e){return t?{source:"user",value:t}:Xs(e)?{source:"server",value:null}:{source:"random",value:`auto:${Ce()}`}}var _o=l(require("archiver")),ho=l(require("fs-extra")),Ne=l(require("path")),Oo=l(require("unzipper"));var ta=50*1024*1024;async function yo(t,e=ta){return new Promise((r,o)=>{let n=(0,_o.default)("zip",{zlib:{level:9}}),i=[],s=0;n.on("data",m=>{i.push(m),s+=m.length,s>e&&o(new Error(`Zip size exceeded the limit of ${e} bytes`))}),n.on("warning",m=>{m.code==="ENOENT"?R(m):o(m)}),n.on("error",m=>o(m)),n.on("end",()=>{let m=Buffer.concat(i);r(m)});let p=async m=>{let f=process.cwd(),d=Ne.default.normalize(m),E=Ne.default.relative(f,d),C=await ho.default.stat(m);C.isDirectory()?n.directory(m,E):n.file(m,{name:E,stats:C})};(async m=>{for(let f of m)await p(f);await n.finalize()})(t).catch(o)})}async function Ao(t,e){return Oo.default.Open.buffer(t).then(r=>r.extract({path:e,concurrency:3}))}var xo=l(require("async-retry")),bo=require("axios");var Uo=l(require("axios")),Do=require("https-proxy-agent"),So=l(require("proxy-from-env"));var ea=c.extend("axios");function Be(t={}){let e=Uo.default.create(t);return e.interceptors.request.use(r=>{let o={...r},n=e.getUri(r),i=So.default.getProxyForUrl(n);return i&&(ea("Using HTTP proxy %s for %s ",i,n),o.proxy=!1,o.httpsAgent=ra(i)),o}),e}var Ht=null;function ra(t){return Ht||(Ht=new Do.HttpsProxyAgent(t),Ht)}var jt=c.extend("upload"),Kt=5;async function Le(t,e,r){return jt("Uploading buffer %s",t.name,{buffer:Buffer.byteLength(t.buffer)}),na(t.buffer,t.uploadUrl,e,r)}async function oa(t,e,r,o){return Be().request({method:"put",url:e,data:t,onUploadProgress:o,headers:{"Content-Disposition":"inline","Content-Type":r}})}async function Me(t,e){try{let r=await Be().get(t,{responseType:"arraybuffer",onDownloadProgress:e});return Buffer.from(r.data)}catch(r){throw(0,bo.isAxiosError)(r)&&jt("Failed to download %s: %s",t,r.message),r}}async function na(...t){await(0,xo.default)(async()=>{await oa(...t)},{retries:Kt,onRetry:(e,r)=>{if(jt("Upload failed %d out of %d attempts: %s",r,Kt,e.message),r===Kt){I(`Cannot upload after ${r} times: ${e.message}`);return}R(`Upload failed ${r} out of ${Kt} attempts: ${e.message}`)}})}var ve=t=>({total:e,loaded:r})=>{};function Po(t){return t/1e3/1e3}var Ge=l(require("lodash"));var tt=l(require("path")),ke=l(require("globby"));var wo=require("lodash");function Fe({config:t,cacheId:e,orgId:r,path:o,ci:n,cacheKey:i,metaCacheKey:s}){let p={id:e,orgId:r,config:(0,wo.omit)(t,"recordKey"),path:o,ci:n,createdAt:new Date().toISOString(),cacheKey:i,metaCacheKey:s};return Buffer.from(JSON.stringify(p))}function No(t,e){t instanceof Error?ot("%s. %s.",e,t.message):ot("%s. %s.",e,"Unknown error")}var Bo=async t=>{let e=tt.default.resolve(t??"./test-results"),r=[tt.default.posix.join(e.replace(/\\/g,"/"),"**/.last-run.json"),tt.default.posix.join(e.replace(/\\/g,"/"),".last-run.json")];return ke.sync(r)},Lo=async(t=[])=>{let e=ia(t),r=[];return e.length>0&&r.push(...ke.sync(t.map(o=>o.replace(/\\/g,"/")))),r};function ia(t){let e=process.cwd();return t.filter(r=>{let o=tt.default.resolve(r),n=tt.default.relative(e,o);return r.startsWith("..")||tt.default.isAbsolute(n)?(No(null,`Invalid path: "${r}". Path traversal detected. The path was skipped.`),!1):!0})}function $t(t){return t?t.path.some(e=>tt.default.basename(e)===".last-run.json"):!1}async function Mo(t,e){switch(e.provider){case"githubActions":await ko(t,e);break;case"gitlab":await Fo(t,e);break;case"circle":await Go(t,e);break;default:break}}async function vo(t,e,r){switch(e.provider){case"githubActions":await ko(t,e,r);break;case"gitlab":await Fo(t,e,r);break;case"circle":await Go(t,e,r);break;default:break}}async function Fo(t,e,r=null){let o=e.params,n=r?.ci.params,s=(n?lt(n.runAttempt,0):0)+1,p=lt(o.ciNodeIndex,1),u=lt(o.ciNodeTotal,1),m=$t(r),f=s>1&&m,d=f?"--last-failed":"",E="";u>1&&(E=f?"--shard=1/1":`--shard=${p}/${u}`);let C=[d,E].filter(Boolean).join(" ");await it(t.presetOutput??ht,`EXTRA_PW_FLAGS="${C}"
14
- EXTRA_PWCP_FLAGS="${d}"
15
- RUN_ATTEMPT=${s}
16
- `)}async function ko(t,e,r=null){let{matrixIndex:o,matrixTotal:n}=t,i=e.params,s=lt(i.githubRunAttempt,1),p=$t(r),u=s>1&&p,m=u?"--last-failed":"",f="";n>1&&(f=u?"--shard=1/1":`--shard=${o}/${n}`);let d=[m,f].filter(Boolean).join(" "),E=t.presetOutput??ht;await it(E,d),c('Dumped PW config: "%s" for GHA to %s',d,E)}async function Go(t,e,r=null){let o=e.params,n=r?.ci.params,i=n?.circleWorkflowId,s=n?.circleWorkflowWorkspaceId,p=lt(o.circleNodeIndex,0),u=lt(o.circleNodeTotal,1),m=s==o.circleWorkflowWorkspaceId&&i!==o.circleWorkflowId,f=$t(r),d=m&&f,E=d?"--last-failed":"",C="";u>1&&(C=d?"--shard=1/1":`--shard=${p+1}/${u}`);let x=[E,C].filter(Boolean).join(" "),Q=t.presetOutput??ht;await it(Q,x),c('Dumped PW config: "%s" for Circle to %s',x,Q)}var lt=(t,e)=>{let r=Ge.default.toNumber(t);return Ge.default.isNaN(r)?e:r};async function Ke(){let t=Z();if(t.type!=="GET_COMMAND_CONFIG"||!t.values)throw new Error("Config is missing!");let{recordKey:e,id:r,preset:o,matrixIndex:n,matrixTotal:i,continue:s}=t.values,p=t.values.outputDir,u=ft();o==="last-run"&&await Mo(t.values,u);let{cacheId:m,refMetaReadUrl:f}=await Jr({recordKey:e,ci:u,id:r,config:{matrixIndex:n,matrixTotal:i}});try{let d=await ca(f),{readUrl:E}=await Yr({recordKey:e,cacheKey:d.cacheKey}),C=await sa({readUrl:E,outputDir:p});o==="last-run"&&await vo(t.values,u,d),O(g("- restoring cache to"),C),Pt("Cache restored. Cache ID: %s",m)}catch(d){if((0,Ho.isAxiosError)(d)&&(d.response?.status===403||d.response?.status===404)){let E=`Cache with ID "${m}" not found`;if(s){ot(E);return}throw new Error(E)}throw d}}async function sa({readUrl:t,outputDir:e}){let r=await Me(t),o=aa(e);return await Ao(r,o),c("Cache downloaded",{readUrl:t,destination:o}),o}function aa(t){let e=t??process.cwd();return He.default.isAbsolute(e)?e:He.default.resolve(process.cwd(),e)}async function ca(t){let e=await Me(t),r=JSON.parse(e.toString("utf-8"));return c("Meta file downloaded: %O",r),r}var jo=require("lodash");async function je(){let t=Z();if(t.type!=="SET_COMMAND_CONFIG"||!t.values)throw new Error("Config is missing!");let{recordKey:e,id:r,preset:o,pwOutputDir:n,matrixIndex:i,matrixTotal:s,continue:p}=t.values,u=await Lo(t.values.path),m=t.values.path||[],f=ft();if(o==="last-run"&&(m.push(n),u.push(...await Bo(n))),u.length===0){let Q=`No files available to upload: ${m.filter(Boolean).join(",")}`;if(!p)throw new Error(Q);ot(Q)}let d=await Vr({recordKey:e,ci:f,id:r,config:{matrixIndex:i,matrixTotal:s}});c("Cache upload url created",{result:d});let E=ma(f),C=u.length>0?await yo(u):null,x=[];C&&x.push(pa({archive:C,cacheId:d.cacheId,uploadUrl:d.uploadUrl}).then(()=>{ua(u),c("Cache archive uploaded",{uploadUrl:d.uploadUrl})})),x.push(Ko({meta:Fe({cacheId:d.cacheId,config:t.values,ci:E,orgId:d.orgId,path:u}),cacheId:d.cacheId,uploadUrl:d.metaUploadUrl}).then(()=>c("Meta uploaded",{uploadUrl:d.metaUploadUrl})),Ko({meta:Fe({cacheId:d.cacheId,config:t.values,ci:E,orgId:d.orgId,path:u,cacheKey:d.cacheKey,metaCacheKey:d.metaCacheKey}),cacheId:d.cacheId,uploadUrl:d.refMetaUploadUrl}).then(()=>c("Ref meta uploaded",{uploadUrl:d.refMetaUploadUrl}))),await Promise.all(x),Pt("Cache uploaded. Cache ID: %s",d.cacheId)}async function pa({archive:t,cacheId:e,uploadUrl:r}){try{let o="application/zip";await Le({buffer:t,contentType:o,name:e,uploadUrl:r},o,ve(e)),c("Cache archive uploaded",{cacheId:e})}catch(o){throw c("Failed to upload cache archive",o),o}}async function Ko({meta:t,cacheId:e,uploadUrl:r}){try{let o=`${e}_meta`,n="application/json";await Le({buffer:t,contentType:n,name:o,uploadUrl:r},n,ve(o)),c("Cache meta uploaded",{cacheId:e})}catch(o){throw c("Failed to upload cache meta",o),o}}function ma(t){return t.ciBuildId.source==="server"||t.ciBuildId.source==="random"?(0,jo.omit)(t,"ciBuildId"):t}function ua(t){O(`Cache upload paths:
17
- `+t.map(e=>`${g("- uploading")} ${e}`).join(`
18
- `))}var y={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"},runId:{name:"Run ID",env:"CURRENTS_RUN_ID",cli:"--run-id"},debug:{name:"Debug",env:"CURRENTS_DEBUG",cli:"--debug"}};function $o(){return{recordKey:process.env[y.recordKey.env],projectId:process.env[y.projectId.env],ciBuildId:process.env[y.ciBuildId.env],runId:process.env[y.runId.env],debug:Ar(process.env[y.debug.env])}}var da=c.extend("config"),fa=["recordKey","projectId"];function la(t){if(!(t.runId||t.ciBuildId))throw I(`${Lt(y,"runId")} or ${Lt(y,"ciBuildId")} is required for Currents Reporter. Use the following methods to set the value:
19
- - as environment variable: ${g(_(y,"runId"))} or ${g(_(y,"ciBuildId"))}
20
- - as CLI flag of the command: ${g(Bt(y,"runId"))} or ${g(Bt(y,"ciBuildId"))}`),new X("Missing required config variable")}var $e=null;function Vo(t){$e=M(y,fa,$o,t,la),da("Resolved config: %o",T($e))}function Vt(){return $e}async function Ve(){let t=Vt();if(!t)throw new Error("Config is missing!");let e=t.runId?`runId: ${t.runId}`:`ciBuildId: ${t.ciBuildId}`;try{let r=await Wr({recordKey:t.recordKey,projectId:t.projectId,ciBuildId:t.ciBuildId,runId:t.runId});return r.data.runId?O('Run "%s" (%s) is cancelled',r.data.runId,e):O('No run to cancel (%s) in project "%s"',e,t.projectId),r}catch(r){throw c("Failed to cancel the run"),r}}var Jo=require("@currents/commit-info"),Wo=require("lodash");var Yt=require("lodash");var Ye=c.extend("ci-git");function Yo(t){Ye("git commit existing info: %O",t);let e=To();Ye("commit info from provider environment variables: %O",e);let r=(0,Yt.transform)(t,(o,n,i)=>{let s=n||(e?e[i]:null);return o[i]=(0,Yt.defaultTo)(s,null)});return Ye("combined git and environment variables from provider: %O",r),r}var ga=async()=>{let t=await(0,Jo.commitInfo)();return Yo({branch:t.branch,remoteOrigin:t.remote,authorEmail:t.email,authorName:t.author,message:t.message,sha:t.sha,ghaEventData:t.ghaEventData})},qo=(0,Wo.memoize)(ga);var Qo=l(require("getos")),Xo=require("lodash"),v=require("os"),zo=require("util"),Ea=async()=>{if((0,v.platform)()==="linux")try{let t=await(0,zo.promisify)(Qo.default)();return"dist"in t&&"release"in t?[t.dist,t.release].join(" - "):(0,v.release)()}catch{return(0,v.release)()}return(0,v.release)()},Ca=async()=>{let t=await Ea();return{osName:(0,v.platform)(),osVersion:t,osCpus:[],osMemory:{free:(0,v.freemem)(),total:(0,v.totalmem)()}}},Zo=(0,Xo.memoize)(Ca);var Gn=l(require("axios")),ze=l(require("fs-extra")),ee=l(require("path")),Hn=l(require("semver"));var U={debug:{name:"Debug",env:"CURRENTS_DEBUG",cli:"--debug"},ciBuildId:{name:"CI Build ID",env:"CURRENTS_CI_BUILD_ID",cli:"--ci-build-id"},recordKey:{name:"Record Key",env:"CURRENTS_RECORD_KEY",cli:"--key"},projectId:{name:"Project ID",env:"CURRENTS_PROJECT_ID",cli:"--project-id"},tag:{name:"Currents Tag",env:"CURRENTS_TAG",cli:"--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"},machineId:{name:"Machine ID",env:"CURRENTS_MACHINE_ID",cli:"--machine-id"},reportDir:{name:"Report Directory",env:"CURRENTS_REPORT_DIR",cli:"--report-dir"}};function tn(){return{projectId:process.env[U.projectId.env],recordKey:process.env[U.recordKey.env],ciBuildId:process.env[U.ciBuildId.env],tag:process.env[U.tag.env]?process.env[U.tag.env]?.split(",").map(t=>t.trim()):void 0,disableTitleTags:process.env[U.disableTitleTags.env],removeTitleTags:process.env[U.removeTitleTags.env],debug:process.env[U.debug.env],machineId:process.env[U.machineId.env]}}var Ia=c.extend("config"),Ra=["projectId","recordKey"],Je=null;function en(t){Je=M(U,Ra,tn,t),Ia("Resolved Currents config: %o",Je)}function Jt(){return Je}function rn(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 qe=l(require("fs-extra")),Y=require("path");var on=l(require("fs-extra")),nn=require("path"),We=c.extend("detox"),Ta="detox.json";function sn(t){return[...t].sort((e,r)=>(e.session??0)-(r.session??0)||e.invocations-r.invocations)}async function an(t){let e=(0,nn.join)(t,Ta);try{let r=await on.default.readJson(e);if(typeof r?.artifactsRootDir!="string"||!Array.isArray(r?.tests)){We("Unexpected Detox manifest contents at %s",e);return}return We("Detox manifest: %o",r),r}catch{We("No Detox manifest at %s",e);return}}var Wt=require("path"),_a=c.extend("detox"),cn=255,ha=/[/\\?<>:*|"$\u0000-\u001f]/g,pn=4;function mn(t){return Oa(t)??ya(t)}function Oa({rootDir:t,fullName:e,status:r,invocations:o}){try{let n=require.resolve("detox/src/artifacts/utils/ArtifactPathBuilder",{paths:[process.cwd()]}),i=require(n),s=new i({rootDir:t});return(0,Wt.dirname)(s.buildPathForTestArtifact("test.mp4",{fullName:e,status:r,invocations:o}))}catch(n){_a("Detox path builder is not available: %o",n);return}}function ya({rootDir:t,fullName:e,status:r,invocations:o}){let n=Ua(r),i=o>1?` (${o})`:"",s=e.slice(-cn+n.length+i.length),p=`${n}${s}${i}`.replace(ha,"_");return(0,Wt.join)(t,Aa(p,cn))}function Aa(t,e){let r=Buffer.from(t,"utf8");return r.length<=e?t:r.subarray(0,e).toString("utf8").replace(/\uFFFD$/,"")}function Ua(t){switch(t){case"passed":return"\u2713 ";case"failed":return"\u2717 ";default:return""}}var dn=l(require("fs-extra")),fn=require("path"),un=c.extend("detox"),qt="detox.trace.json",Da="ws-client-invocation";async function ln(t){let e=(0,fn.join)(t,qt),r=new Map,o;try{o=await dn.default.readJson(e)}catch{return un("No Detox trace at %s",e),r}if(!Array.isArray(o))return un("Unexpected Detox trace contents at %s",e),r;let n=Sa(o);return xa(o).forEach(({pid:s,ts:p,step:u})=>{n.filter(f=>f.pid===s&&p>=f.startTs&&p<=f.endTs).sort((f,d)=>f.startTs-d.startTs).pop()?.steps.push(u)}),n.forEach(({fullName:s,invocations:p,steps:u})=>{let m=r.get(s)??[];m.push({fullName:s,invocations:p,steps:u.sort((f,d)=>+new Date(f.startTime)-+new Date(d.startTime))}),r.set(s,m)}),r}function Sa(t){let e=new Map,r=[];t.forEach(n=>{let i=`${n.pid}:${n.tid}`,s=e.get(i)??[];if(e.set(i,s),n.ph==="B"){s.push(Pa(n));return}if(n.ph==="E"){let p=s.pop();p&&r.push({...p,endTs:Number(n.ts)})}});let o=[...e.values()].flatMap(n=>n.filter(i=>i!==void 0));return[...r,...o]}function Pa(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 xa(t){let e=new Map,r=[];return t.forEach(o=>{if(!o.cat?.includes(Da))return;let n=`${o.pid}:${o.tid}`,i=e.get(n)??[];if(o.ph==="B"){i.push({name:o.name??"action",cat:o.cat,ts:Number(o.ts)}),e.set(n,i);return}if(o.ph==="E"){let s=i.pop();if(!s)return;r.push({pid:Number(o.pid),ts:s.ts,step:{title:s.name,category:"detox",startTime:new Date(s.ts/1e3).toISOString(),duration:Math.round((Number(o.ts)-s.ts)/1e3),steps:[]}})}}),r}var Ot=c.extend("detox"),gn="artifacts",ba={".mp4":{type:"video",contentType:"video/mp4"},".png":{type:"screenshot",contentType:"image/png"},".jpg":{type:"screenshot",contentType:"image/jpeg"},".log":{type:"attachment",contentType:"text/plain"},".txt":{type:"attachment",contentType:"text/plain"},".json":{type:"attachment",contentType:"application/json"},".viewhierarchy":{type:"attachment",contentType:"application/xml"}};async function En({instances:t,reportDir:e,manifest:r}){let o=Na(r),n=await ln(r.artifactsRootDir),i=await st((0,Y.join)(e,gn)),s={artifacts:0,steps:0};for(let p of t)for(let u of p.results.tests){let m=o.get(u.testId);if(!m){Ot("No Detox manifest entry for %s",u.testId);continue}await Ba({test:u,manifestTest:m,rootDir:r.artifactsRootDir,artifactsDir:i,traceSlices:n.get(m.fullName)??[],result:s})}return s.artifacts+=await wa({instances:t,rootDir:r.artifactsRootDir,artifactsDir:i}),s}async function wa({instances:t,rootDir:e,artifactsDir:r}){if(!await qe.default.pathExists((0,Y.join)(e,qt)))return 0;let[o]=await Cn(e,[qt],r),n=t.map(i=>i.results.tests[0]).filter(i=>i!==void 0);return n.forEach(i=>{i.artifacts=[...i.artifacts??[],o]}),n.length}function Na(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||Ot("Ambiguous Detox test name, skipping: %s",r.fullName),o}).map(r=>[r.testId,r]))}async function Ba({test:t,manifestTest:e,rootDir:r,artifactsDir:o,traceSlices:n,result:i}){let s=[...t.attempts].sort((m,f)=>m.attempt-f.attempt),p=sn(e.attempts),u=1;for(let[m,f]of p.entries()){let d=s[m];if(!d){Ot("No reported attempt %d of %s",m,e.fullName);continue}let E=await La({fullName:e.fullName,status:f.status,rootDir:r,artifactsDir:o,fromInvocation:u});E&&(u=E.invocation+1,d.artifacts=[...d.artifacts??[],...E.artifacts],i.artifacts+=E.artifacts.length);let C=va(n,m,E?.invocation);C.length&&(d.steps=[...d.steps??[],...C],i.steps+=C.length)}}async function La({fullName:t,status:e,rootDir:r,artifactsDir:o,fromInvocation:n}){for(let i=n;i<n+pn;i++){let s=mn({rootDir:r,fullName:t,status:e,invocations:i}),p=await Ma(s);if(p)return{invocation:i,artifacts:await Cn(s,p,o)}}Ot("No Detox artifacts for %s [%s]",t,e)}async function Ma(t){try{return(await qe.default.readdir(t)).sort()}catch{return}}async function Cn(t,e,r){let o=[];for(let n of e){let i=ba[(0,Y.extname)(n)];if(!i){Ot("Skipping unsupported Detox artifact %s",n);continue}let s=(0,Y.join)(t,n),p=`${$(s)}${(0,Y.extname)(n)}`;await wt(s,(0,Y.join)(r,p)),o.push({...i,path:(0,Y.join)(gn,p),name:n})}return o}function va(t,e,r){return((r===void 0?void 0:t.find(i=>i.invocations===r))??[...t].sort((i,s)=>i.invocations-s.invocations)[e])?.steps??[]}var et=class{constructor(e){this.config=e}async getFullTestSuite(){return[]}};var Sn=l(require("fs-extra")),Pn=require("jest-cli"),xn=l(require("tmp"));var Un=require("lodash");function In(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 Rn=require("lodash"),Fa=["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 Tn(t){return(0,Rn.omit)(t,...Fa)}var On=l(require("fs")),yn=require("jest-config"),Qe=require("lodash"),Xe=l(require("path"));function Qt(t,e){return(...r)=>new Promise((o,n)=>{let i=0,s=()=>{i++;try{let p=t(...r);o(p)}catch(p){if(i>=e.length)n(p);else{let u=e[i-1];setTimeout(s,u)}}};s()})}var _n=l(require("fs-extra")),ka=l(require("path"));async function Xt(t){let e=await _n.default.pathExists(t);if(!e)throw new Error("File does not exist");return e}var hn=c.extend("jest-discovery");async function An(t){try{let{config:e,configPath:r}=await(0,yn.readInitialOptions)(t),o=["collectCoverage","collectCoverageFrom","coverageDirectory","coveragePathIgnorePatterns","coverageProvider","coverageReporters","coverageThreshold","errorOnDeprecated","forceCoverageMatch","notify","notifyMode","openHandlesTimeout","reporters","runner","showSeed","testFailureExitCode","verbose","watchPathIgnorePatterns","watchPlugins","watchman","bail","clearCache","color","colors","debug","detectLeaks","detectOpenHandles","expand","forceExit","json","listTests","logHeapUsage","noStackTrace","outputFile","shard","showConfig","silent","testNamePattern","waitNextEventLoopTurnForUnhandledRejectionEvents","watch","watchAll"],n=["collectCoverageFrom","coverageDirectory","coveragePathIgnorePatterns","detectLeaks","detectOpenHandles","errorOnDeprecated","forceCoverageMatch","openHandlesTimeout","runner","watchPathIgnorePatterns"],i=(0,Qe.omit)(e,o);if(i.projects&&(i.projects=i.projects.map(u=>typeof u!="string"?(0,Qe.omit)(u,n):u)),i.rootDir&&Object.keys(i).length===1)return null;let s=Xe.default.resolve(r?Xe.default.dirname(r):process.cwd(),`.jest-scanner-${new Date().getTime()}.config.cjs`),p=`module.exports=${JSON.stringify(i,null,2)}`;return hn("configFileContent: %O",p),On.default.writeFileSync(s,p),await Qt(Xt,[200,200,200,200,200,1e3])(s),s}catch(e){return I("Failed to recreate the config file"),hn("error %o",e),null}}async function Dn(t){let e="!!##ThisPatternWillNotMatchAnyTestName##!!",r=t.options,o=Tn(r),n=In(o),i=r.config,s=await An(i);return{cliArgs:[n,"--testNamePattern",e,"--reporters","@currents/cmd/discovery/jest","--shard=1/1",s?`--config=${s}`:"",...t.args].filter(u=>!(0,Un.isEmpty)(u)),configFilePath:s}}var Ga=c.extend("jest-discovery");async function bn(t,e){console.time(g("@currents/jest:fullTestSuite-ready"));let{cliArgs:r,configFilePath:o}=await Dn(e);try{let n=xn.default.fileSync({postfix:".json"});return Ga("running scanner: %o",r),process.env.CURRENTS_DISCOVERY_PATH=n.name,await(0,Pn.run)(r.concat(["--openHandlesTimeout=0"])),await Qt(Xt,Array.from({length:300},()=>100))(n.name),console.timeEnd(g("@currents/jest:fullTestSuite-ready")),await nt(n.name)}catch(n){return I("Failed to obtain the jest full test suite:",n),[]}finally{o&&Sn.default.unlinkSync(o)}}var zt=class extends et{constructor(e){super(e)}async getFullTestSuite(){return bn(this.config.frameworkConfig,this.config.cliArgs)}};var Nn=l(require("fs-extra"));var wn=l(require("path"));function gt(t){return wn.default.join(t,"fullTestSuite.json")}var Ha=c.extend("junit-discovery");async function Bn(t){console.time(g("@currents/junit:fullTestSuite-ready"));try{Ha("running scanner: %o",t);let e=gt(t);process.env.CURRENTS_DISCOVERY_PATH=e;let r=Nn.default.readFileSync(e,"utf-8");return JSON.parse(r)}catch(e){return I("Failed to obtain the junit full test suite:",e),[]}}var Zt=class extends et{constructor(e,r){super(e),this.reportDir=r}async getFullTestSuite(){return Bn(this.reportDir)}};function Ln(t,e){switch(t.framework){case"jest":return new zt(t);case"junit":return new Zt(t,e);default:return new et(t)}}var Et=l(require("fs-extra")),J=l(require("path"));async function Mn(t){let e=await Ka(t?.reportDir);if(!e)throw new Error("Failed to find the report dir");return{reportDir:e,configFilePath:t?.configFilePath??J.default.join(e,"config.json")}}async function Ka(t){return t?(await te(t),t):ja((0,J.join)(process.cwd(),".currents"))}async function ja(t){let e=await Et.default.readdir(t),r=null;for(let o of e){let n=J.default.join(t,o),i=await Et.default.stat(n);i.isDirectory()&&(!r||i.birthtime>r.birthtime)&&(r={name:o,birthtime:i.birthtime})}return r?(0,J.resolve)(t,r.name):null}async function te(t){try{return await Et.default.pathExists(t)}catch{return I("Error checking if path exists:",I),!1}}async function vn(t){let e=J.default.join(t,"instances");return $a(e)}async function $a(t){let e=await Et.default.readdir(t),r=[];for(let o of e){let n=J.default.join(t,o);(await Et.default.stat(n)).isFile()&&r.push(n)}return r}var Va=t=>Buffer.byteLength(JSON.stringify(t),"utf8"),Fn=(t,e=1048576)=>{let r=[],o=[],n=0;for(let i of t){let s=Va(i);n+s>e&&(r.push(o),o=[],n=0),o.push(i),n+=s}return o.length>0&&r.push(o),r};var Ya=3e4;async function Ze(){let t=Jt();if(!t)throw new Error("Currents config is missing!");let e=await Mn(t);lr(Wa(e.reportDir)),c("Reporter options: %o",e),O("Report directory: %s",e.reportDir);let r=await nt(e.configFilePath);c("Report config: %o",r);let o=await vn(e.reportDir);c("Found %d instance results in the reportDir: %s",o.length,e.reportDir);let n=Ja(e.reportDir),i=await te(n),s=gt(e.reportDir),p=null;if(i){let b=await nt(n);R("Marker file detected. The report was already uploaded: %o",{runUrl:b.response.runUrl,isoDate:b.isoDate})}if(await te(s)&&(p=await nt(s),c("Full test suite file detected: %s",s)),p)c("The discovery stage was skipped");else{if(p=await Ln(r,e.reportDir).getFullTestSuite(),qa(p))throw new Error("Failed to discover the full test suite!");await it(s,JSON.stringify(p))}let m=p.length===1?p[0].name:null,f={currents:t},d={type:r.framework,version:r.frameworkVersion,clientVersion:mt,frameworkConfig:{originFramework:r.frameworkConfig?.originFramework,originFrameworkVersion:r.frameworkConfig?.originFrameworkVersion}},E=Nt.userFacingNanoid(),C=ft(t.ciBuildId),x={};for await(let b of o){let B=await nt(b);x[B.groupId]||(x[B.groupId]=[]),x[B.groupId].push(B)}let Q=await an(e.reportDir);if(Q){let b=await En({instances:Object.values(x).flat(),reportDir:e.reportDir,manifest:Q});O("[currents] Attached %d Detox artifacts and %d steps",b.artifacts,b.steps)}let Dt=new Map;Object.values(x).forEach(b=>{b.forEach(B=>{B.artifacts?.forEach(L=>{L&&Dt.set(L.path,L.contentType)}),B.results.tests.forEach(L=>{L.artifacts?.forEach(w=>{w&&Dt.set(w.path,w.contentType)}),L.attempts.forEach(w=>{w.artifacts?.forEach(rt=>{rt&&Dt.set(rt.path,rt.contentType)})})})})});for await(let b of Object.keys(x)){let B=x[b],L=b;m&&(c("Default group found: %s, overwriting the group in the results",m),L=m,B=B.map(w=>({...w,groupId:m})));try{let w=Fn(B),rt=await kn({ci:C,group:L,instances:[],fullTestSuite:p,config:f,machineId:E,framework:d});for(let ue=0;ue<w.length;ue++){let de=await kn({ci:C,group:L,instances:w[ue],fullTestSuite:[],config:f,machineId:E,framework:d});de.artifactUploadUrls&&de.artifactUploadUrls.length>0&&await Qa(de.artifactUploadUrls,e.reportDir,Dt)}c("Api response: %o",rt),O("[%s] Run created: %s",L,rt.runUrl);let is={response:rt,isoDate:new Date().toISOString()};await it(n,JSON.stringify(is)),c("Marker file %s: %s",i?"overwritten":"created",n)}catch(w){throw c("Failed to upload the results to the dashboard"),w}}}async function kn({ci:t,group:e,instances:r,fullTestSuite:o,config:n,machineId:i,framework:s}){let p=await qo(),u=await Zo(),m={browserName:"node",browserVersion:Hn.default.coerce(process.version)?.version},{currents:f}=n,E={platform:{...m,...u},ci:t,commit:p,group:e,fullTestSuite:o,config:n,projectId:f.projectId,recordKey:f.recordKey,ciBuildId:t.ciBuildId.value??void 0,tags:f.tag??[],machineId:f.machineId??i,framework:s,instances:r,previousCiBuildId:process.env.CURRENTS_PREVIOUS_CI_BUILD_ID};return c("Creating run: %o",T(E)),zr(E)}function Ja(t){return ee.default.join(t,"upload.marker.json")}function Wa(t){return ee.default.join(t,`.debug-${new Date().toISOString()}.log`)}function qa(t){return t.length===0||t.some(e=>e.tests.length===0)}async function Qa(t,e,r){c("Uploading %d artifacts",t.length),await Promise.all(t.map(o=>{let n=ee.default.join(e,o.path),i=r.get(o.path)||"application/octet-stream";return Xa(n,i,o.uploadUrl)}))}var Xa=async(t,e,r)=>{try{if(!await ze.default.pathExists(t)){R("Artifact file not found: %s",t);return}let o=await ze.default.readFile(t);await Gn.default.put(r,o,{headers:{"Content-Type":e},timeout:Ya})}catch(o){c("Failed to upload artifact %s: %o",t,o)}};var za=c.extend("cli");async function Kn(t){await N(async e=>{Dr(e);let r=Mt();za("Config: %o",bt(r)),await Ae()},t)}var W=require("@commander-js/extra-typings");var jn=new W.Option("--api-key <api-key>","API key from Currents dashboard for authentication").env(_(V,"apiKey")),$n=new W.Option("-o, --output <path>","Path to the file where output will be written").env(_(V,"output")),Vn=new W.Option("--ci-build-id <id>","Unique identifier for the run"),Yn=new W.Option("-p, --project-id <project>","Project ID from Currents associated with the run").env(_(V,"projectId")),Jn=new W.Option("-t, --tag <tag>","Filter by comma-separated list of tags").argParser(dt),Wn=new W.Option("--debug","Enable debug logging").env(_(V,"debug")).default(!1),qn=new W.Option("-b, --branch <branch>","Filter by git branch name"),Qn=new W.Option("--pw-last-run",'Create Playwright ".last-run.json" file with the failed test(s) from the run');var re="api",Za=t=>`
21
-
22
- ${Xn.default.bold("Examples")}
23
-
24
- Obtain run data by --ci-build-id:
25
- ${g(`${t} ${re} get-run --api-key <api-key> --ci-build-id <ci-build-id>`)}
26
-
27
- Obtain the most recent run data by filters:
28
- ${g(`${t} ${re} get-run --api-key <api-key> --project-id <project-id> --branch <branch> --tag tagA,tagB`)}
29
-
30
- Obtain run data by --ci-build-id, save the failed test in a format compatible with Playwright --last-failed:
31
- ${g(`${t} ${re} get-run --api-key <api-key> --ci-build-id <ci-build-id> --pw-last-run --output <output-path>`)}
32
-
33
- `,zn=t=>new tr.Command().command(re).description("Interact with the Currents API").showHelpAfterError("(add --help for additional information)").allowUnknownOption().addCommand(tc(t)),tc=t=>new tr.Command().name("get-run").description(`Retrieve run data from Currents API ${Za(t)}`).allowUnknownOption().addOption(jn).addOption(Wn).addOption(Vn).addOption(Yn).addOption(qn).addOption(Jn).addOption($n).addOption(Qn).action(Kn);var oe=require("@commander-js/extra-typings");var ei=l(require("chalk"));var ec=c.extend("cli");async function Zn(t){await N(async e=>{io(so(e));let r=Z();ec("Config: %o",T(r.values)),await Ke()},t)}var rc=c.extend("cli");async function ti(t){await N(async e=>{no(ao(e));let r=Z();rc("Config: %o",T(r.values)),await je()},t)}var Ct="cache",oc=t=>`
34
-
35
- ${ei.default.bold("Examples")}
36
-
37
- Save files to the cache under a specific ID:
38
- ${g(`${t} ${Ct} set --key <record-key> --id <id> --path <path-1,path-2,...path-n>`)}
39
-
40
- Retrieve files from the cache saved under a specific ID:
41
- ${g(`${t} ${Ct} get --key <record-key> --id <id>`)}
42
-
43
- Store the last run data in the cache:
44
- ${g(`${t} ${Ct} set --key <record-key> --preset last-run`)}
45
-
46
- Retrieve the last run data from the cache:
47
- ${g(`${t} ${Ct} get --key <record-key> --preset last-run`)}
48
-
49
- Retrieve the last run data from the cache and save it to a custom directory:
50
- ${g(`${t} ${Ct} get --key <record-key> --preset last-run --output-dir <outputDir>`)}
51
-
52
- `,ri=t=>new oe.Command().command(Ct).description(`Cache data to Currents ${oc(t)}`).showHelpAfterError("(add --help for additional information)").allowUnknownOption().addCommand(nc()).addCommand(ic()),nc=()=>new oe.Command().name("set").allowUnknownOption().addOption(De).addOption(Pe).addOption(xe).addOption(po).addOption(Se).addOption(uo).addOption(be).addOption(we).addOption(Eo).action(ti),ic=()=>new oe.Command().name("get").allowUnknownOption().addOption(De).addOption(Pe).addOption(xe).addOption(mo).addOption(fo).addOption(Se).addOption(be).addOption(we).addOption(go).action(Zn);var pi=require("@commander-js/extra-typings");var mi=l(require("chalk"));var sc=c.extend("cli");async function oi(t){await N(async({key:e,...r})=>{Vo({...r,recordKey:e});let o=Vt();sc("Config: %o",T(o??{})),await Ve()},t)}var It=require("@commander-js/extra-typings");var ni=new It.Option("-k, --key <record-key>","your secret Record Key obtained from Currents").env(_(y,"recordKey")),ii=new It.Option("-p, --project-id <project>","the project ID the run belongs to").env(_(y,"projectId")),si=new It.Option("--ci-build-id <id>","the unique identifier of the build (run) to cancel").env(_(y,"ciBuildId")),ai=new It.Option("--run-id <id>","the identifier of the run to cancel, as reported when the run was created").env(_(y,"runId")),ci=new It.Option("--debug","enable debug logs").env(_(y,"debug")).default(!1);var er="cancel",ac=t=>`
53
-
54
- ${mi.default.bold("Examples")}
55
-
56
- Cancel the run recorded under a CI build id:
57
- ${g(`${t} ${er} --key <record-key> --project-id <id> --ci-build-id <build-id>`)}
58
-
59
- Cancel a run by its id, as reported when the run was created:
60
- ${g(`${t} ${er} --key <record-key> --project-id <id> --run-id <run-id>`)}
61
-
62
- Cancel the run when a GitHub Actions workflow is cancelled:
63
- ${g("- if: ${{ cancelled() }}\n run: npx currents cancel")}
64
-
65
- `,ui=t=>new pi.Command().name(er).description(`Cancel a run in progress, e.g. when the CI job it belongs to is cancelled ${ac(t)}`).allowUnknownOption().addOption(ni).addOption(ii).addOption(si).addOption(ai).addOption(ci).action(oi);var Ai=require("@commander-js/extra-typings"),Ui=l(require("chalk"));var K=require("@commander-js/extra-typings");var di=new K.Option("--ci-build-id <id>","the unique identifier for the recorded build (run)").env(_(U,"ciBuildId")),fi=new K.Option("-k, --key <record-key>","your secret Record Key obtained from Currents").env(_(U,"recordKey")),li=new K.Option("-p, --project-id <project>","the project ID for results reporting obtained from Currents").env(_(U,"projectId")),gi=new K.Option("-t, --tag <tag>","comma-separated tag(s) for recorded runs in Currents").argParser(dt),Ei=new K.Option("--remove-title-tags","remove tags from test names in Currents, e.g. `Test name @smoke` becomes `Test name` in the dashboard").default(!1),Ci=new K.Option("--disable-title-tags","disable parsing tags from test title, e.g. `Test name @smoke` would not be tagged with `smoke` in the dashboard").default(!1),Ii=new K.Option("--machine-id <string>","unique identifier of the machine running the tests. If not provided, it will be generated automatically. See: https://docs.currents.dev/?q=machineId").env(_(U,"machineId")),Ri=new K.Option("--report-dir <string>","explicit path to the report directory").env(_(U,"reportDir")),Ti=new K.Option("--debug","enable debug logs").env(_(U,"debug")).default(!1);var Oi=l(require("fs"));var _i=require("tmp-promise"),hi=async()=>{let{path:t}=await(0,_i.file)();return t};var rr=c.extend("cli"),ne=class{constructor(e){this.configFilePath=null;this.cliOptions=e,rr("CLI options: %o",T(this.cliOptions)),this.parsedConfig=rn(this.cliOptions),rr("Parsed config from CLI options: %o",T(this.parsedConfig))}async getConfigFilePath(){if(this.configFilePath)return this.configFilePath;let e=await hi();return Oi.default.writeFileSync(e,JSON.stringify(this.parsedConfig)),rr("CLI options temp file path: %s",e),this.configFilePath=e,e}};async function yi(t){await N(async e=>{let r=new ne(e);en(r.parsedConfig);let o=Jt();O("Currents config: %o",T(o)),await Ze()},t)}var yt="upload",cc=t=>`
66
-
67
- ${Ui.default.bold("Examples")}
68
-
69
- Upload test results to Currents:
70
- ${g(`${t} ${yt} --key <record-key> --project-id <id> --ci-build-id <build-id>`)}
71
-
72
- Upload test results to Currents, add tags "tagA", "tagB" to the recorded run:
73
- ${g(`${t} ${yt} --key <record-key> --project-id <id> --ci-build-id <build-id> --tag tagA --tag tagB`)}
74
-
75
- Provide a custom path to the reports directory:
76
- ${g(`${t} ${yt} --key <record-key> --project-id <id> --ci-build-id <build-id> --report-dir <report-dir>`)}
77
-
78
- `,Di=t=>new Ai.Command().name(yt).command(yt).showHelpAfterError("(add --help for additional information)").allowUnknownOption().description(`Upload test results generated by Currents reporters to https://currents.dev
79
- ${cc(t)}`).addOption(di).addOption(fi).addOption(li).addOption(gi).addOption(Ei).addOption(Ci).addOption(Ii).addOption(Ti).addOption(Ri).action(r=>yi(r));var ts=require("@commander-js/extra-typings");var es=l(require("chalk"));var At={debug:{name:"Debug",env:"CURRENTS_DEBUG",cli:"--debug"},inputFormat:{name:"Input Format",cli:"--input-format"},inputFiles:{name:"Input File",cli:"--input-file"},outputDir:{name:"Output Dir",cli:"--output-dir"},framework:{name:"Framework",cli:"--framework"},frameworkVersion:{name:"Framework Version",cli:"--framework-version"}};function Si(){return{debug:process.env[At.debug.env]}}var pc=c.extend("config"),mc=["inputFormat","inputFiles","framework"],or=null;function Pi(t){or=M(At,mc,Si,t),pc("Resolved config: %o",or)}function ie(){return or}function xi(t){return{inputFiles:t.inputFile,inputFormat:t.inputFormat,outputDir:t.outputDir,framework:t.framework,frameworkVersion:t.frameworkVersion,debug:t.debug}}var pt=require("path");var Li=require("lodash"),Mi=l(require("crypto"));var F=require("path"),ae=async(t,e,r,o)=>{if(t)for(let n of t)try{let i=(0,F.resolve)(o,n.path),s=(0,F.relative)(o,i);if(s.startsWith("..")||(0,F.isAbsolute)(s)){c("Skipping artifact outside workspace: %s (resolved: %s)",n.path,i);continue}let p=`${$(e+n.path)}.${(0,F.extname)(n.path).slice(1)||"bin"}`;await wt(i,(0,F.join)(r,p)),n.path=(0,F.join)("artifacts",p)}catch(i){c("Failed to copy artifact %s: %o",n.path,i)}};function wi(t){let e=Bi(t.properties?.property??t.property);return se(e,"currents.artifact.instance.","spec")}function Ni(t){let e=Bi(t.properties?.property),r=se(e,"currents.artifact.test.","test"),o=new Map;uc(e).forEach((s,p)=>{o.has(p)||o.set(p,[]),o.get(p).push(...s)});let i=se(e,"currents.artifact.attempt.","attempt");return i.length>0&&(o.has(0)||o.set(0,[]),o.get(0).push(...i)),{testArtifacts:r,attemptArtifacts:o}}function uc(t){let e=new Map,r=/^currents\.artifact\.attempt\.(\d+)\.(.+)$/,o=new Map;for(let n of t){let i=n.value??n._;if(!n.name||!i)continue;let s=n.name.match(r);if(!s)continue;let[,p,u]=s,m=parseInt(p,10);o.has(m)||o.set(m,[]),o.get(m).push({name:`currents.artifact.attempt.${u}`,value:i})}for(let[n,i]of o.entries()){let s=se(i,"currents.artifact.attempt.","attempt");s.length>0&&e.set(n,s)}return e}function se(t,e,r){let o=[],n={};for(let i of t){let s=i.value??i._;if(!i.name||!s||!i.name.startsWith(e))continue;let p=i.name.slice(e.length);/^\d+\./.test(p)||["path","type","contentType","name"].includes(p)&&(n[p]&&(bi(n)&&o.push({...n,level:r}),n={}),n[p]=s)}return bi(n)&&o.push({...n,level:r}),o}function bi(t){return!!(t.path&&t.type&&t.contentType)}function Bi(t){return t?Array.isArray(t)?t:[t]:[]}function vi(t,e,r,o){let n=ct(t.failure),i=n.length>0,s=e?.timestamp??"",p="skipped"in t,u=p?"pending":i?"failed":"passed",{testArtifacts:m,attemptArtifacts:f}=Ni(t);return{_t:ce(s),testId:ar(Ut(t.name,o).join(", "),o),title:Ut(t.name,o),state:u,isFlaky:dc(),expectedStatus:"passed",timeout:fc(),location:lc(e?.file??""),retries:gc(n),artifacts:m,attempts:Ec(t,n,cr(s),r,f,p)}}function ar(t,e){let r=`${t}${e}`;return Mi.default.createHash("sha256").update(r).digest("hex").substring(0,16)}function ce(t){return Fi(t)?new Date(t).getTime():new Date().getTime()}function cr(t){return Fi(t)?new Date(t).toISOString():new Date().toISOString()}function Fi(t){let e=new Date(t);return!isNaN(e.getTime())}function Ut(t,e){return[e,t].filter(Boolean)}function dc(){return!1}function fc(){return 0}function lc(t){return{column:1,file:t,line:1}}function gc(t){let e=0;return t.forEach(r=>{typeof r!="string"&&e++}),e}function Ec(t,e,r,o,n,i){let s=t.time?pe(t.time):0;if(i)return[{_s:"pending",attempt:0,startTime:r,steps:[],duration:s,status:"skipped",stdout:nr(t?.["system-out"]),stderr:ir(t?.["system-err"]),artifacts:n.get(0),errors:[],error:void 0}];if(e.length===0){let p=[];return n.forEach(u=>{p.push(...u)}),[{_s:"passed",attempt:0,startTime:r,steps:[],duration:s,status:"passed",stdout:nr(t?.["system-out"]),stderr:ir(t?.["system-err"]),artifacts:p,errors:[],error:void 0}]}return e.reduce((p,u,m)=>{if(u!=="true"&&u!=="false"){let f=Cc(u);p.push({_s:"failed",attempt:m,startTime:Ic(o,r),steps:[],duration:s,status:"failed",stdout:nr(t?.["system-out"]),stderr:ir(t?.["system-err"]),artifacts:n.get(m),errors:f,error:f[0]})}return p},[])}function nr(t){return t?[t]:[]}function ir(t){return t?[t]:[]}function Cc(t){return t==="true"||t==="false"?[]:[typeof t=="string"?{message:t}:{message:t.message,stack:t._,value:t.type}]}function Ic(t,e){let r=ce(e)+t;return new Date(r).toISOString()}function ct(t){return t?Array.isArray(t)?t:[t]:[]}function Rc(t){return Math.round(t*1e3)}function pe(t){let e=parseFloat(t);return isNaN(e)?0:Rc(e)}function me(t,e,r){let o=(0,Li.isNumber)(r)&&r>0,n=!!t.id&&sr(e,"id",t.id);if(t.file){let i=sr(e,"file",t.file);return i&&!n?`${t.file} - ${t.id}`:i&&o?`${t.file} - ${r}`:t.file}if(t.name){let i=sr(e,"name",t.name);return i&&!n?`${t.name} - ${t.id}`:i&&o?`${t.name} - ${r}`:t.name}return t.id?n&&o?`${t.id} - ${r}`:t.id:o?`unknown - ${r}`:"unknown"}function sr(t,e,r){return t.filter(n=>n[e]===r).length>1}function ki(t){let e=[];return t.forEach(r=>{let o=ct(r.testsuites?.testsuite),n={name:r.testsuites?.name??"No name",tags:[],tests:[]};o?.forEach(i=>{let s=me(i,o);ct(i?.testcase)?.forEach(u=>{let m={title:Ut(u.name,s),spec:s,tags:[],testId:ar(Ut(u.name,s).join(", "),s)};n.tests.push(m)})}),e.push(n)}),e}var q=require("@commander-js/extra-typings"),Gi=l(require("globby"));var Hi=new q.Option("--debug","Enable debug logging").env(_(At,"debug")).default(!1),pr=(e=>(e.junit="junit",e))(pr||{}),Ki=new q.Option("--input-format <string>","the format of the input test reports").choices(Object.values(pr)),ji=new q.Option("--input-file <patterns>",'comma-separated glob patterns to match report file paths (e.g., "report1.xml,report2.xml")').argParser(Tc),$i=new q.Option("-o, --output-dir <string>","the directory to save the converted test reports"),mr=(n=>(n.postman="postman",n.node="node",n.vitest="vitest",n.wdio="wdio",n))(mr||{}),Vi=new q.Option("--framework <string>","the testing framework used to generate the test reports").choices(Object.values(mr)),Yi=new q.Option("--framework-version <string>","the version of the testing framework used to generate the test reports");function Tc(t){let e=t.split(",").map(o=>o.trim()),r=Gi.sync(e);if(r.length===0)throw new q.InvalidArgumentError("No files found with the provided patterns");return r}async function k(t){let e=new Map;return t.forEach(r=>{let o=ct(r.testsuites?.testsuite),n=r.testsuites?.name??"No name";o.forEach((i,s)=>{let p=me(i,o,s),u=_c(i,n,p),m=$(n+p);u.results.tests.length!==0&&e.set(m,u)})}),e}function _c(t,e,r){let o=cr(t.timestamp??""),n=t.time?pe(t.time):0,i=new Date(ce(t.timestamp??"")+n),s=ct(t.testcase),p=[t["system-out"],t["system-err"],...s.flatMap(C=>[C["system-out"],C["system-err"]])].filter(C=>C).join(`
80
- `),u=0,m=s.filter(C=>"failure"in C).length,f=s.filter(C=>"skipped"in C).length,d=s.length-m-f;return{groupId:e,spec:r,startTime:o,artifacts:wi(t),_stdout:p,results:{stats:{suites:1,tests:s.length,passes:d,pending:f,skipped:0,failures:m,flaky:0,wallClockStartedAt:o,wallClockEndedAt:i.toISOString(),wallClockDuration:n},tests:s?.map(C=>(s[0]?.time&&(u+=pe(s[0].time)),vi(C,t,u,r)))}}}async function Ji({inputFormat:t,framework:e,parsedXMLArray:r}){return t==="junit"?hc(e,r):new Map}async function hc(t,e){switch(t){case"node":return k(e);case"postman":return k(e);case"vitest":return k(e);case"wdio":return k(e);default:return R("Unsupported framework: %s",t),new Map}}var Wi=require("fs-extra"),qi=require("xml2js");async function Qi(t){let e=await Promise.all(t.map(o=>(0,Wi.readFile)(o,"utf-8"))),r=(await Promise.all(e.map(Oc))).filter(Boolean);return e.length!==r.length&&R("Some files could not be parsed. Enable debug logging for more details"),r}async function Oc(t){let e=t.trim();if(!e)return null;try{return await(0,qi.parseStringPromise)(e,{explicitArray:!1,mergeAttrs:!0})||null}catch(r){return c("Error parsing XML input",r),null}}function Xi(t){return{framework:t.inputFormat,frameworkVersion:t.frameworkVersion??null,frameworkConfig:{originFramework:t.framework,originFrameworkVersion:t.frameworkVersion}}}async function zi(){try{let t=ie();if(!t)throw new Error("Config is missing!");let e=t.outputDir?await st(t.outputDir):await _r(process.cwd(),".currents"),r=await st((0,pt.join)(e,"instances")),o=Xi(t);c("Report config:",o),O("[currents] Convertion files: %s",t.inputFiles.join(", ")),await _t((0,pt.join)(e,"config.json"),JSON.stringify(o));let n=await Qi(t.inputFiles);if(n.length===0)throw new Error("No valid XML JUnit report was found.");let i=ki(n);await _t(gt(e),JSON.stringify(i));let s=await Ji({inputFormat:t.inputFormat,framework:t.framework,parsedXMLArray:n}),p=await st((0,pt.join)(e,"artifacts")),u=process.cwd();await Promise.all(Array.from(s.values()).map(async m=>{if(await ae(m.artifacts,m.spec,p,u),m._stdout){let f=`${$(m.spec)}.stdout.txt`;await _t((0,pt.join)(p,f),m._stdout),m.artifacts||(m.artifacts=[]),m.artifacts.push({path:(0,pt.join)("artifacts",f),type:"stdout",contentType:"text/plain",level:"spec"}),delete m._stdout}for(let f of m.results.tests){await ae(f.artifacts,f.testId,p,u);for(let d of f.attempts)await ae(d.artifacts,f.testId+d.attempt,p,u)}})),await Promise.all(Array.from(s.entries()).map(([m,f])=>_t((0,pt.join)(r,`${$(m)}.json`),JSON.stringify(f)))),O("[currents] Conversion completed, report saved to: %s",e)}catch(t){throw c("Failed to convert: %o",t),t}}var yc=c.extend("cli");async function Zi(t){await N(async e=>{Pi(xi(e));let r=ie();yc("Config: %o",r),await zi()},t)}var ur="convert",Ac=t=>`
81
-
82
- ${es.default.bold("Examples")}
83
-
84
- Convert JUnit test reports to Currents format:
85
- ${g(`${t} ${ur} --input-format junit --input-file ./*.xml --framework postman`)}
86
- `,rs=t=>new ts.Command().name(ur).command(ur).showHelpAfterError("(add --help for additional information)").allowUnknownOption().description(`Convert reports from various testing frameworks to Currents format
87
- ${Ac(t)}`).addOption(Hi).addOption(Ki).addOption(ji).addOption($i).addOption(Vi).addOption(Yi).action(r=>Zi(r));var Uc=`
88
- ----------------------------------------------------
89
- \u{1F4D6} Documentation: https://docs.currents.dev
90
- \u{1F919} Support: support@currents.dev
91
- ----------------------------------------------------
92
- `,Rt="currents",ns=()=>new os.Command(Rt).version(mt).description(`Currents CLI ${Uc}`).addCommand(Di(Rt),{isDefault:!0}).addCommand(ri(Rt)).addCommand(zn(Rt)).addCommand(ui(Rt)).addCommand(rs(Rt));import("dotenv/config");function Dc(){ns().parse()}Dc();
18
+ `]:["Unexpected network error"]}var dn=p.extend("http");async function z(t,e,r=Ut){try{let o=await r(t).request(e);return dn("network response: %o",{...mn.default.omit(o,"request","config"),url:o.config.url,method:o.config.method}),o}catch(o){let n=o;throw dn("network error: %o",{code:n.code,message:n.message,url:n.config?.url,method:n.config?.method,status:n.response?.status,headers:n.response?.headers,data:n.response?.data}),pn(n),n}}var Dt=p.extend("api");async function un(t){try{return Dt("Request params: %o",h(t)),z("api",{url:"cache/upload",method:"POST",data:t}).then(e=>e.data)}catch(e){throw Dt("Failed to create cache:",e),e}}async function ln(t){try{return Dt("Request params: %o",h(t)),z("api",{url:"cache/v2/download",method:"POST",data:t}).then(e=>e.data)}catch(e){throw Dt("Failed to retrieve cache:",e),e}}async function fn(t){try{return Dt("Request params: %o",h(t)),z("api",{url:"cache/meta",method:"POST",data:t}).then(e=>e.data)}catch(e){throw Dt("Failed to retrieve reference cache meta:",e),e}}var gp=p.extend("api");async function gn(t){return gp("Cancel params: %o",h(t)),(await z("api",{url:"v1/runs/cancel",method:"POST",data:t})).data}var En=require("util"),In=require("zlib");var hn=p.extend("api"),hp=(0,En.promisify)(In.gzip);async function Cn(t){try{hn("Run params: %o",h(t));let e=await Ep(JSON.stringify(t));return z("api",{url:"v1/runs",method:"POST",headers:{"Content-Type":"application/json","Content-Encoding":"gzip"},data:e}).then(r=>r.data)}catch(e){throw hn("Failed to create the run:",e),e}}async function Ep(t){try{return await hp(t)}catch(e){throw C("Failed to compress run payload:",e),e}}var Tn=p.extend("api");async function yn(t,e){try{return Tn("Run params: %o",e),z("restApi",{url:"v1/runs/find",params:e,method:"GET",headers:{"Content-Type":"application/json",...St({apiKey:t})}}).then(r=>r.data)}catch(r){throw Tn("Failed to obtain run data:",r),r}}var Rn=require("axios");var _n=p.extend("api");function Ip(t){if(!(0,Rn.isAxiosError)(t)||!t.response)return t;let e=t.response.data,r=[`${t.response.status}`];e?.code&&r.push(e.code);let o=e?.error??t.message,n=Ee(t),s=n?` Retry in ${Math.ceil(n/1e3)} seconds.`:"",i=Cp(e?.candidates);return new Error(`${r.join(" ")}: ${o}${s}${i}`)}function Cp(t){return!Array.isArray(t)||t.length===0?"":`
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 Ip(o)}}function wn(t,e){return _n("Create session params: %o",e),Wt("v1/sessions",{apiKey:t},e)}function On(t,e,r,o){return _n("Create attachments: %o",{owner:e,target:r,attachments:o}),"sessionId"in e?Wt(`v1/sessions/${encodeURIComponent(e.sessionId)}/attachments`,t,{attachments:o}):"runId"in e?Wt(`v1/runs/${encodeURIComponent(e.runId)}/attachments`,t,{...r,attachments:o}):Wt("v1/runs/attachments",t,{...e,...r,attachments:o})}function xn(t,e){return Wt("v1/share",{apiKey:t},e)}function An(t,e){return Ut("restApi").request({...e,headers:{...St({apiKey:t}),...e.headers},responseType:"text",transformResponse:r=>r})}async function Sr(){try{let t=le();if(!t)throw new Error("Config is missing!");let e=t.ciBuildId?{projectId:t.projectId,ciBuildId:t.ciBuildId,pwLastRun:t.pwLastRun}:{projectId:t.projectId,branch:t.branch,tag:t.tag,pwLastRun:t.pwLastRun},r=await yn(t.apiKey,e);if(t.pwLastRun&&!r.data.pwLastRun)throw new Error("The API answered without the status and failed tests of the run (pwLastRun). Nothing was written.");await Tp(t.pwLastRun?r.data.pwLastRun:r.data,t)}catch(t){throw p("Failed to get run data"),t}}async function Tp(t,e){let r=JSON.stringify(t,null,2);e.output?(await Ko(e.output),await(0,Sn.writeFile)(e.output,r,"utf-8"),T(`Successfully written to ${e.output}`)):process.stdout.write(r+`
22
+ `)}var Os=require("axios"),Gr=l(require("path"));var v=require("@commander-js/extra-typings");var Un=require("@commander-js/extra-typings");function Ie(t,e=[]){return t?e.concat(t.split(",").map(r=>r.trim())):e}function Dn(t){for(let e of t.options){let r=e.attributeName();if(!e.envVar||!e.isBoolean()||t.getOptionValueSource(r)!=="env")continue;let o=Jo(process.env[e.envVar]);t.setOptionValueWithSource(r,o??e.defaultValue,o===void 0?"default":"env")}}function yp(t,e){if(!Array.isArray(t))return String(t)===e;let r=o=>o.map(n=>n.trim()).filter(Boolean).join(",");return r(t.map(String))===r(e.split(","))}function Pn(t){for(let e of t.options){let r=e.attributeName(),o=e.envVar?process.env[e.envVar]:void 0,n=t.getOptionValue(r);!o||e.isBoolean()||t.getOptionValueSource(r)!=="cli"||yp(n,o)||se(`${e.long} and ${e.envVar} are set to different values; using ${e.long}`)}}function Pt(){console.log=(...t)=>console.error(...t)}async function w(t,e){try{e.debug&&No(),await t(e),process.exit(0)}catch(r){C(r.message);let o=r instanceof Un.CommanderError?r.exitCode:1;process.exit(o)}}var bn="Without it the ID comes from the CI job: on GitHub Actions the repository, the run ID and --matrix-index; on GitLab the pipeline ID and the job name; on other CI the variables that identify the pipeline and the job, and --matrix-index. When no CI job is detected the ID is random, so pass --id",Nn=new v.Option("--id <id>",`the ID to save the files under. ${bn}`),Ln=new v.Option("--id <id>",`the ID the files were saved under. ${bn}`),Bn=new v.Option("--path <path>",'comma-separated paths or glob patterns of the files to save, inside the current folder; quote globs, e.g. "dist/**/*". At most 50 MB zipped').argParser(Ie),qt=(e=>(e.lastRun="last-run",e))(qt||{}),vn=new v.Option("--preset <preset-name>",'"last-run" saves the Playwright .last-run.json files of --pw-output-dir, to rerun only the failed tests').choices(Object.values(qt)),Mn=new v.Option("--preset <preset-name>",'"last-run" restores the saved .last-run.json files and writes the Playwright options for the rerun to --preset-output').choices(Object.values(qt)),Fn=new v.Option("--output-dir <folder>","the folder to restore the files to; by default the current folder"),kn=new v.Option("--pw-output-dir <folder>","the Playwright output folder that holds .last-run.json").default("test-results"),zt=".currents_env",Gn=new v.Option("--preset-output <path>",'the file the "last-run" preset writes, relative to the current folder. On GitHub Actions and CircleCI it holds options for "playwright test"; on GitLab the shell variables EXTRA_PW_FLAGS, EXTRA_PWCP_FLAGS and RUN_ATTEMPT, to source. Nothing is written on other CI').default(zt),Ur=new v.Option("--matrix-index <number>","the index of this job among parallel jobs, from 1; each job has its own cache. Pass it when the CI does not tell the jobs apart, as in a GitHub Actions matrix").default(1).argParser($n),Dr=new v.Option("--matrix-total <number>","GitHub Actions only: the number of jobs in the matrix, for the shards that the last-run preset writes").default(1).argParser($n);function $n(t){let e=parseInt(t,10);if(isNaN(e)||e<=0||!Number.isInteger(e))throw new v.InvalidArgumentError("A positive integer is expected.");return e}var Kn=new v.Option("--continue","exit with 0 when the cache is not found").default(!1),Hn=new v.Option("--continue","exit with 0 when no files are found, and save the cache without files").default(!1);var Rp={recordKey:_.recordKey,debug:_.debug},_p={id:{name:"Cache id",cli:"--id"},preset:{name:"Preset",cli:"--preset"},pwOutputDir:{name:"Playwright output folder",cli:"--pw-output-dir"},presetOutput:{name:"Preset output path",cli:"--preset-output"},path:{name:"Paths to cache",cli:"--path"},matrixIndex:{name:"Matrix index",cli:"--matrix-index"},matrixTotal:{name:"Matrix total",cli:"--matrix-total"},continue:{name:"Continue when upload path missing",cli:"--continue"}},wp={id:{name:"Cache id",cli:"--id"},preset:{name:"Preset",cli:"--preset"},outputDir:{name:"Output folder",cli:"--output-dir"},matrixIndex:{name:"Matrix index",cli:"--matrix-index"},matrixTotal:{name:"Matrix total",cli:"--matrix-total"},continue:{name:"Continue on cache miss",cli:"--continue"}},Pr={...Rp,..._p,...wp};var jn=p.extend("config"),Vn=["recordKey"],Ct;function Jn(t){Ct={type:"SET_COMMAND_CONFIG",values:U(Pr,Vn,t)},jn("Resolved config: %o",{...Ct,values:h(Ct.values)})}function Yn(t){Ct={type:"GET_COMMAND_CONFIG",values:U(Pr,Vn,t)},jn("Resolved config: %o",{...Ct,values:h(Ct.values)})}function dt(){return Ct}function Wn(t){return{recordKey:t.key,id:t.id,preset:t.preset,outputDir:t.outputDir,presetOutput:t.presetOutput,debug:t.debug,matrixIndex:t.matrixIndex,matrixTotal:t.matrixTotal,continue:t.continue}}function qn(t){return{recordKey:t.key,id:t.id,preset:t.preset,pwOutputDir:t.pwOutputDir,path:t.path,debug:t.debug,matrixIndex:t.matrixIndex,matrixTotal:t.matrixTotal,continue:t.continue}}var R=require("lodash");var Ce=p.extend("ci"),Op=(t,e)=>(0,R.set)(t,(0,R.camelCase)(e),process.env[e]),D=t=>(0,R.transform)(t,Op,{}),xp=()=>process.env.TF_BUILD&&process.env.AZURE_HTTP_USER_AGENT,Ap=()=>(0,R.some)(process.env,(t,e)=>/^CODEBUILD_/.test(e)),Sp=()=>process.env.bamboo_buildNumber,Up=()=>(0,R.some)(process.env,(t,e)=>/^CONCOURSE_/.test(e)),Dp=()=>process.env.GITLAB_CI||process.env.CI_SERVER_NAME&&/^GitLab/.test(process.env.CI_SERVER_NAME),Pp=()=>!!(process.env.BUILD_ID&&process.env.PROJECT_ID&&process.env.PROJECT_NUMBER||process.env.GCP_PROJECT||process.env.GCLOUD_PROJECT||process.env.GOOGLE_CLOUD_PROJECT),bp=()=>process.env.JENKINS_URL||process.env.JENKINS_HOME||process.env.JENKINS_VERSION||process.env.HUDSON_URL||process.env.HUDSON_HOME,Np={appveyor:"APPVEYOR",azure:xp,awsCodeBuild:Ap,bamboo:Sp,bitbucket:"BITBUCKET_BUILD_NUMBER",buildkite:"BUILDKITE",circle:"CIRCLECI",concourse:Up,codeFresh:"CF_BUILD_ID",drone:"DRONE",githubActions:"GITHUB_ACTIONS",gitlab:Dp,goCD:"GO_JOB_NAME",jenkins:bp,googleCloud:Pp,semaphore:"SEMAPHORE",teamcity:"TEAMCITY_VERSION",travis:"TRAVIS",netlify:"NETLIFY"};function Lp(){let{env:t}=process;return(0,R.findKey)(Np,e=>{if((0,R.isString)(e))return t[e];if((0,R.isFunction)(e))return e()})}var zn=()=>({appveyor:D(["APPVEYOR_JOB_ID","APPVEYOR_ACCOUNT_NAME","APPVEYOR_PROJECT_SLUG","APPVEYOR_BUILD_NUMBER","APPVEYOR_BUILD_VERSION","APPVEYOR_PULL_REQUEST_NUMBER","APPVEYOR_PULL_REQUEST_HEAD_REPO_BRANCH"]),azure:D(["AGENT_BUILDDIRECTORY","AGENT_ID","AGENT_JOBNAME","AGENT_JOBSTATUS","AGENT_MACHINENAME","AGENT_NAME","AGENT_OS","AGENT_OSARCHITECTURE","BUILD_BUILDID","BUILD_BUILDNUMBER","BUILD_BUILDURI","BUILD_CONTAINERID","BUILD_CRONSCHEDULE_DISPLAYNAME","BUILD_DEFINITIONNAME","BUILD_DEFINITIONVERSION","BUILD_QUEUEDBY","BUILD_QUEUEDBYID","BUILD_REASON","BUILD_REPOSITORY_ID","BUILD_REPOSITORY_NAME","BUILD_REPOSITORY_PROVIDER","BUILD_REPOSITORY_URI","BUILD_REQUESTEDFOR","BUILD_REQUESTEDFOREMAIL","BUILD_REQUESTEDFORID","BUILD_SOURCEBRANCH","BUILD_SOURCEBRANCHNAME","BUILD_SOURCESDIRECTORY","BUILD_SOURCEVERSION","BUILD_SOURCEVERSIONAUTHOR","BUILD_SOURCEVERSIONMESSAGE","BUILD_STAGINGDIRECTORY","BUILD_TRIGGEREDBY_BUILDID","BUILD_TRIGGEREDBY_BUILDNUMBER","BUILD_TRIGGEREDBY_DEFINITIONID","BUILD_TRIGGEREDBY_DEFINITIONNAME","BUILD_TRIGGEREDBY_PROJECTID","COMMON_TESTRESULTSDIRECTORY","PIPELINE_WORKSPACE","SYSTEM_COLLECTIONID","SYSTEM_COLLECTIONURI","SYSTEM_DEFAULTWORKINGDIRECTORY","SYSTEM_DEFINITIONID","SYSTEM_HOSTTYPE","SYSTEM_JOBATTEMPT","SYSTEM_JOBDISPLAYNAME","SYSTEM_JOBID","SYSTEM_JOBNAME","SYSTEM_PHASEATTEMPT","SYSTEM_PHASEDISPLAYNAME","SYSTEM_PHASENAME","SYSTEM_PLANID","SYSTEM_PULLREQUEST_ISFORK","SYSTEM_PULLREQUEST_PULLREQUESTID","SYSTEM_PULLREQUEST_PULLREQUESTNUMBER","SYSTEM_PULLREQUEST_SOURCEREPOSITORYURI","SYSTEM_PULLREQUEST_SOURCEBRANCH","SYSTEM_PULLREQUEST_SOURCECOMMITID","SYSTEM_PULLREQUEST_TARGETBRANCH","SYSTEM_PULLREQUEST_TARGETBRANCHNAME","SYSTEM_STAGEATTEMPT","SYSTEM_STAGEDISPLAYNAME","SYSTEM_STAGENAME","SYSTEM_TEAMFOUNDATIONCOLLECTIONURI","SYSTEM_TEAMPROJECT","SYSTEM_TEAMPROJECTID","SYSTEM_TIMELINEID"]),awsCodeBuild:D(["AWS_DEFAULT_REGION","AWS_REGION","CODEBUILD_BATCH_BUILD_IDENTIFIER","CODEBUILD_BUILD_ARN","CODEBUILD_BUILD_ID","CODEBUILD_BUILD_IMAGE","CODEBUILD_BUILD_NUMBER","CODEBUILD_BUILD_SUCCEEDING","CODEBUILD_BUILD_URL","CODEBUILD_INITIATOR","CODEBUILD_PROJECT_ARN","CODEBUILD_PUBLIC_BUILD_URL","CODEBUILD_RESOLVED_SOURCE_VERSION","CODEBUILD_SOURCE_REPO_URL","CODEBUILD_SOURCE_VERSION","CODEBUILD_SRC_DIR","CODEBUILD_START_TIME","CODEBUILD_WEBHOOK_ACTOR_ACCOUNT_ID","CODEBUILD_WEBHOOK_BASE_REF","CODEBUILD_WEBHOOK_EVENT","CODEBUILD_WEBHOOK_HEAD_REF","CODEBUILD_WEBHOOK_MERGE_COMMIT","CODEBUILD_WEBHOOK_PREV_COMMIT","CODEBUILD_WEBHOOK_TRIGGER","CODEBUILD_WEBHOOK_LABEL","CODEBUILD_WEBHOOK_RUN_ID","CODEBUILD_WEBHOOK_JOB_ID","CODEBUILD_WEBHOOK_WORKFLOW_NAME","CODEBUILD_RUNNER_OWNER","CODEBUILD_RUNNER_REPO","CODEBUILD_RUNNER_REPO_DOMAIN","CODEBUILD_RUNNER_WITH_BUILDSPEC"]),bamboo:D(["bamboo_buildNumber","bamboo_buildResultsUrl","bamboo_planRepository_repositoryUrl","bamboo_buildKey"]),bitbucket:D(["CI","BITBUCKET_WORKSPACE","BITBUCKET_REPO_SLUG","BITBUCKET_REPO_UUID","BITBUCKET_REPO_FULL_NAME","BITBUCKET_REPO_IS_PRIVATE","BITBUCKET_REPO_OWNER","BITBUCKET_REPO_OWNER_UUID","BITBUCKET_PROJECT_KEY","BITBUCKET_PROJECT_UUID","BITBUCKET_BUILD_NUMBER","BITBUCKET_PIPELINE_UUID","BITBUCKET_STEP_UUID","BITBUCKET_STEP_RUN_NUMBER","BITBUCKET_STEP_TRIGGERER_UUID","BITBUCKET_PARALLEL_STEP","BITBUCKET_PARALLEL_STEP_COUNT","BITBUCKET_CLONE_DIR","BITBUCKET_COMMIT","BITBUCKET_BRANCH","BITBUCKET_TAG","BITBUCKET_BOOKMARK","BITBUCKET_GIT_HTTP_ORIGIN","BITBUCKET_GIT_SSH_ORIGIN","BITBUCKET_PR_ID","BITBUCKET_PR_DESTINATION_BRANCH","BITBUCKET_PR_DESTINATION_COMMIT","BITBUCKET_DEPLOYMENT_ENVIRONMENT","BITBUCKET_DEPLOYMENT_ENVIRONMENT_UUID","BITBUCKET_EXIT_CODE"]),buildkite:D(["BUILDKITE_ORGANIZATION_SLUG","BUILDKITE_PIPELINE_ID","BUILDKITE_PIPELINE_NAME","BUILDKITE_PIPELINE_SLUG","BUILDKITE_PIPELINE_DEFAULT_BRANCH","BUILDKITE_REPO","BUILDKITE_SOURCE","BUILDKITE_BRANCH","BUILDKITE_TAG","BUILDKITE_COMMIT","BUILDKITE_MESSAGE","BUILDKITE_BUILD_AUTHOR","BUILDKITE_BUILD_AUTHOR_EMAIL","BUILDKITE_JOB_ID","BUILDKITE_BUILD_ID","BUILDKITE_BUILD_URL","BUILDKITE_BUILD_NUMBER","BUILDKITE_LABEL","BUILDKITE_COMMAND","BUILDKITE_STEP_ID","BUILDKITE_STEP_KEY","BUILDKITE_PARALLEL_JOB","BUILDKITE_PARALLEL_JOB_COUNT","BUILDKITE_RETRY_COUNT","BUILDKITE_COMPUTE_TYPE","BUILDKITE_CLUSTER_NAME","BUILDKITE_PULL_REQUEST","BUILDKITE_PULL_REQUEST_REPO","BUILDKITE_PULL_REQUEST_BASE_BRANCH","BUILDKITE_PULL_REQUEST_DRAFT","BUILDKITE_PULL_REQUEST_LABELS","BUILDKITE_MERGE_QUEUE_BASE_BRANCH","BUILDKITE_MERGE_QUEUE_BASE_COMMIT","BUILDKITE_REBUILT_FROM_BUILD_ID","BUILDKITE_REBUILT_FROM_BUILD_NUMBER","BUILDKITE_TRIGGERED_FROM_BUILD_ID","BUILDKITE_TRIGGERED_FROM_BUILD_NUMBER","BUILDKITE_TRIGGERED_FROM_BUILD_PIPELINE_SLUG"]),circle:D(["CI","CIRCLECI","CIRCLE_BRANCH","CIRCLE_BUILD_NUM","CIRCLE_BUILD_URL","CIRCLE_PREVIOUS_BUILD_NUM","CIRCLE_JOB","CIRCLE_WORKFLOW_ID","CIRCLE_WORKFLOW_JOB_ID","CIRCLE_WORKFLOW_WORKSPACE_ID","CIRCLE_PIPELINE_ID","CIRCLE_ORGANIZATION_ID","CIRCLE_PROJECT_ID","CIRCLE_PROJECT_REPONAME","CIRCLE_PROJECT_USERNAME","CIRCLE_REPOSITORY_URL","CIRCLE_WORKING_DIRECTORY","CIRCLE_SHA1","CIRCLE_TAG","CIRCLE_USERNAME","CIRCLE_NODE_INDEX","CIRCLE_NODE_TOTAL","CIRCLE_PR_NUMBER","CIRCLE_PR_REPONAME","CIRCLE_PR_USERNAME","CIRCLE_PULL_REQUEST","CIRCLE_PULL_REQUESTS","CI_PULL_REQUEST"]),concourse:D(["BUILD_ID","BUILD_NAME","BUILD_JOB_NAME","BUILD_PIPELINE_NAME","BUILD_TEAM_NAME","ATC_EXTERNAL_URL"]),codeFresh:D(["CF_BUILD_ID","CF_BUILD_URL","CF_CURRENT_ATTEMPT","CF_STEP_NAME","CF_PIPELINE_NAME","CF_PIPELINE_TRIGGER_ID","CF_PULL_REQUEST_ID","CF_PULL_REQUEST_IS_FORK","CF_PULL_REQUEST_NUMBER","CF_PULL_REQUEST_TARGET"]),drone:D(["DRONE_BUILD_LINK","DRONE_BUILD_NUMBER","DRONE_PULL_REQUEST"]),githubActions:D(["CI","GITHUB_ACTIONS","GITHUB_WORKFLOW","GITHUB_WORKFLOW_REF","GITHUB_WORKFLOW_SHA","GITHUB_ACTION","GITHUB_ACTION_PATH","GITHUB_ACTION_REPOSITORY","GITHUB_JOB","GITHUB_EVENT_NAME","GITHUB_EVENT_PATH","GITHUB_RUN_ID","GITHUB_RUN_NUMBER","GITHUB_RUN_ATTEMPT","GITHUB_REPOSITORY","GITHUB_REPOSITORY_ID","GITHUB_REPOSITORY_OWNER","GITHUB_REPOSITORY_OWNER_ID","GITHUB_REF","GITHUB_REF_NAME","GITHUB_REF_TYPE","GITHUB_REF_PROTECTED","GITHUB_BASE_REF","GITHUB_HEAD_REF","GITHUB_SHA","GITHUB_ACTOR","GITHUB_ACTOR_ID","GITHUB_TRIGGERING_ACTOR","GITHUB_SERVER_URL","GITHUB_API_URL","GITHUB_GRAPHQL_URL","GITHUB_WORKSPACE","GITHUB_RETENTION_DAYS","RUNNER_OS","RUNNER_ARCH","RUNNER_NAME","RUNNER_ENVIRONMENT","RUNNER_DEBUG"]),gitlab:D(["CI_PIPELINE_ID","CI_PIPELINE_URL","CI_BUILD_ID","CI_JOB_ID","CI_JOB_URL","CI_JOB_NAME","CI_NODE_INDEX","CI_NODE_TOTAL","GITLAB_HOST","CI_PROJECT_ID","CI_PROJECT_URL","CI_REPOSITORY_URL","CI_ENVIRONMENT_URL","CI_DEFAULT_BRANCH","RUN_ATTEMPT","CI_MERGE_REQUEST_IID","CI_MERGE_REQUEST_PROJECT_URL","CI_MERGE_REQUEST_TITLE","CI_MERGE_REQUEST_SOURCE_BRANCH_NAME","CI_MERGE_REQUEST_TARGET_BRANCH_NAME","CI_OPEN_MERGE_REQUESTS"]),goCD:D(["GO_SERVER_URL","GO_ENVIRONMENT_NAME","GO_PIPELINE_NAME","GO_PIPELINE_COUNTER","GO_PIPELINE_LABEL","GO_STAGE_NAME","GO_STAGE_COUNTER","GO_JOB_NAME","GO_TRIGGER_USER","GO_REVISION","GO_TO_REVISION","GO_FROM_REVISION","GO_MATERIAL_HAS_CHANGED"]),googleCloud:D(["BUILD_ID","PROJECT_ID","REPO_NAME","BRANCH_NAME","TAG_NAME","COMMIT_SHA","SHORT_SHA"]),jenkins:D(["BRANCH_NAME","BUILD_DISPLAY_NAME","BUILD_ID","BUILD_NUMBER","BUILD_TAG","BUILD_URL","CHANGE_AUTHOR","CHANGE_AUTHOR_DISPLAY_NAME","CHANGE_AUTHOR_EMAIL","CHANGE_BRANCH","CHANGE_FORK","CHANGE_ID","CHANGE_TARGET","CHANGE_TITLE","CHANGE_URL","CI","EXECUTOR_NUMBER","JAVA_HOME","JENKINS_HOME","JENKINS_URL","JOB_BASE_NAME","JOB_NAME","JOB_URL","NODE_LABELS","NODE_NAME","RUN_ARTIFACTS_DISPLAY_URL","RUN_CHANGES_DISPLAY_URL","TAG_NAME","WORKSPACE","WORKSPACE_TMP","GIT_AUTHOR_EMAIL","GIT_AUTHOR_NAME","GIT_BRANCH","GIT_COMMIT","GIT_COMMITTER_EMAIL","GIT_COMMITTER_NAME","GIT_LOCAL_BRANCH","GIT_PREVIOUS_COMMIT","GIT_PREVIOUS_SUCCESSFUL_COMMIT","GIT_URL","ghprbActualCommit","ghprbGhRepository","ghprbPullId","ghprbPullLink","ghprbSourceBranch","ghprbTargetBranch","ghprbTriggerAuthorLogin"]),semaphore:D(["SEMAPHORE_BRANCH_ID","SEMAPHORE_BUILD_NUMBER","SEMAPHORE_CURRENT_JOB","SEMAPHORE_CURRENT_THREAD","SEMAPHORE_EXECUTABLE_UUID","SEMAPHORE_GIT_BRANCH","SEMAPHORE_GIT_DIR","SEMAPHORE_GIT_REF","SEMAPHORE_GIT_REF_TYPE","SEMAPHORE_GIT_REPO_SLUG","SEMAPHORE_GIT_SHA","SEMAPHORE_GIT_URL","SEMAPHORE_JOB_COUNT","SEMAPHORE_JOB_ID","SEMAPHORE_JOB_NAME","SEMAPHORE_JOB_UUID","SEMAPHORE_PIPELINE_ID","SEMAPHORE_PLATFORM","SEMAPHORE_PROJECT_DIR","SEMAPHORE_PROJECT_HASH_ID","SEMAPHORE_PROJECT_ID","SEMAPHORE_PROJECT_NAME","SEMAPHORE_PROJECT_UUID","SEMAPHORE_REPO_SLUG","SEMAPHORE_TRIGGER_SOURCE","SEMAPHORE_WORKFLOW_ID","PULL_REQUEST_NUMBER"]),teamcity:null,travis:D(["TRAVIS_JOB_ID","TRAVIS_BUILD_ID","TRAVIS_BUILD_WEB_URL","TRAVIS_REPO_SLUG","TRAVIS_JOB_NUMBER","TRAVIS_EVENT_TYPE","TRAVIS_COMMIT_RANGE","TRAVIS_BUILD_NUMBER","TRAVIS_PULL_REQUEST","TRAVIS_PULL_REQUEST_BRANCH","TRAVIS_PULL_REQUEST_SHA"]),netlify:D(["BUILD_ID","CONTEXT","URL","DEPLOY_URL","DEPLOY_PRIME_URL","DEPLOY_ID"])}),Bp=t=>{let e=Qn();return e?(0,R.chain)(t()).get(e).value():{}};function vp(){return(0,R.chain)(zn()).omitBy(R.isNull).keys().value()}function Mp(t){return t&&vp().includes(t)}function Qn(){let t=Lp();return Ce("detected CI provider name: %s",t),t||null}function Fp(){let t=Bp(zn);return(0,R.mapValues)(t,e=>(0,R.isString)(e)?yr(e):e)}function rt(t){let e=Fp(),r=Qn(),o=kp(t,r);return Ce("detected CI provider: %s",r),Ce("detected CI params: %O",e),Ce("detected CI build ID: %o",o),{params:e,provider:r,ciBuildId:o}}function kp(t,e){return t?{source:"user",value:t}:Mp(e)?{source:"server",value:null}:{source:"random",value:`auto:${Tr()}`}}var Xn=l(require("archiver")),Zn=l(require("fs-extra")),br=l(require("path")),ts=l(require("unzipper"));var Gp=50*1024*1024;async function es(t,e=Gp){return new Promise((r,o)=>{let n=(0,Xn.default)("zip",{zlib:{level:9}}),s=[],i=0;n.on("data",d=>{s.push(d),i+=d.length,i>e&&o(new Error(`Zip size exceeded the limit of ${e} bytes`))}),n.on("warning",d=>{d.code==="ENOENT"?E(d):o(d)}),n.on("error",d=>o(d)),n.on("end",()=>{let d=Buffer.concat(s);r(d)});let c=async d=>{let f=process.cwd(),u=br.default.normalize(d),I=br.default.relative(f,u),g=await Zn.default.stat(d);g.isDirectory()?n.directory(d,I):n.file(d,{name:I,stats:g})};(async d=>{for(let f of d)await c(f);await n.finalize()})(t).catch(o)})}async function rs(t,e){return ts.default.Open.buffer(t).then(r=>r.extract({path:e,concurrency:3}))}var os=require("lodash");var $p={githubActions:[],gitlab:[],appveyor:["APPVEYOR_ACCOUNT_NAME","APPVEYOR_PROJECT_SLUG","APPVEYOR_BUILD_NUMBER"],azure:["SYSTEM_COLLECTIONID","BUILD_BUILDID"],awsCodeBuild:["CODEBUILD_BUILD_ID"],bamboo:["bamboo_buildKey","bamboo_buildNumber"],bitbucket:["BITBUCKET_PIPELINE_UUID"],buildkite:["BUILDKITE_BUILD_ID"],circle:["CIRCLE_WORKFLOW_WORKSPACE_ID"],concourse:["BUILD_ID"],codeFresh:["CF_BUILD_ID"],drone:["DRONE_BUILD_LINK"],goCD:["GO_PIPELINE_NAME","GO_PIPELINE_COUNTER"],googleCloud:["BUILD_ID"],jenkins:["JOB_NAME","BUILD_NUMBER"],semaphore:["SEMAPHORE_PIPELINE_ID"],travis:["TRAVIS_JOB_ID"],netlify:["BUILD_ID"]};function Kp({provider:t,params:e}){let r=t?$p[t]:null;return!r||!e?!1:r.every(o=>!!e[(0,os.camelCase)(o)])}function Te(t,e){e||Kp(t)||se("No CI job detected: without --id the cache ID is random, so cache get does not find what cache set saved. Pass --id to save and restore the same cache.")}var cs=l(require("async-retry")),ps=l(require("fs")),ds=require("stream"),Qt=require("axios");var ns=l(require("axios")),ss=require("https-proxy-agent"),is=l(require("proxy-from-env"));var Hp=p.extend("axios");function Nr(t={}){let e=ns.default.create(t);return e.interceptors.request.use(r=>{let o={...r},n=e.getUri(r),s=is.default.getProxyForUrl(n);return s&&(Hp("Using HTTP proxy %s for %s",At(s),At(n)),o.proxy=!1,o.httpsAgent=jp(s)),o}),e}var ye=null;function jp(t){return ye||(ye=new ss.HttpsProxyAgent(t),ye)}var Xt=p.extend("upload"),Re=5;async function Lr(t,e,r){return Xt("Uploading buffer %s",t.name,{buffer:Buffer.byteLength(t.buffer)}),gs(t.buffer,t.uploadUrl,e,r,t.headers,us(Buffer.byteLength(t.buffer)))}var Vp=256*1024,Jp=120*1e3;async function ms(t){return Xt("Uploading file %s",t.name,{bytes:t.sizeBytes}),gs(()=>t.sizeBytes>0?ps.default.createReadStream(t.path,{end:t.sizeBytes-1}):ds.Readable.from([]),t.uploadUrl,t.contentType,void 0,{...t.headers??{"Content-Type":t.contentType},"Content-Length":String(t.sizeBytes)},us(t.sizeBytes))}function us(t){return Jp+Math.ceil(t/Vp)*1e3}async function Yp(t,e,r,o,n,s){return Nr().request({method:"put",url:e,timeout:s,data:typeof t=="function"?t():t,...typeof t=="function"&&{maxRedirects:0},onUploadProgress:o,headers:n??{"Content-Disposition":"inline","Content-Type":r}})}async function Br(t,e){try{let r=await Nr().get(t,{responseType:"arraybuffer",onDownloadProgress:e});return Buffer.isBuffer(r.data)?r.data:Buffer.from(r.data)}catch(r){throw(0,Qt.isAxiosError)(r)&&Xt("Failed to download %s: %s",At(t),r.message),r}}var Wp=["RequestTimeout","OperationAborted","SlowDown"];function ls(t){if(t)return t.replace(/[\u0000-\u001f\u007f-\u009f]/g,"").replace(/\b[a-z][a-z0-9+.-]*:\/\/\S+/gi,e=>At(e)).slice(0,200)}function fs(t){let e=(0,Qt.isAxiosError)(t)?t.response?.data:void 0,r=typeof e=="string"?e:"";return{code:r.match(/<Code>([^<]*)<\/Code>/)?.[1],message:ls(r.match(/<Message>([^<]*)<\/Message>/)?.[1])}}function qp(t){let e=(0,Qt.isAxiosError)(t)?t.response?.status:void 0;if(e===void 0||e<400||e>=500||e===408||e===429)return!1;let{code:r}=fs(t);return!(r&&Wp.includes(r))}function zp(t){if(!(0,Qt.isAxiosError)(t)||!t.response)return t instanceof Error?t:new Error(String(t));let{code:e,message:r}=fs(t),o=[ls(e),r].filter(Boolean).join(": ");return new Error(`storage answered ${t.response.status}${o?` ${o}`:""}`)}async function gs(...t){try{await Qp(t)}catch(e){throw zp(e)}}async function Qp(t){await(0,cs.default)(async e=>{try{await Yp(...t)}catch(r){if(qp(r)){e(r);return}throw r}},{retries:Re,onRetry:(e,r)=>{if(Xt("Upload failed %d out of %d attempts: %s",r,Re,e.message),r===Re){C(`Cannot upload after ${r} times: ${e.message}`);return}E(`Upload failed ${r} out of ${Re} attempts: ${e.message}`)}})}var vr=t=>({total:e,loaded:r})=>{Xt("Uploading %s: %d / %d",t,as(r),as(e??0))};function as(t){return t/1e3/1e3}var kr=l(require("lodash"));var ot=l(require("path")),Fr=l(require("globby"));var hs=require("lodash");function Mr({config:t,cacheId:e,orgId:r,path:o,ci:n,cacheKey:s,metaCacheKey:i}){let c={id:e,orgId:r,config:(0,hs.omit)(t,"recordKey"),path:o,ci:n,createdAt:new Date().toISOString(),cacheKey:s,metaCacheKey:i};return Buffer.from(JSON.stringify(c))}function Es(t,e){t instanceof Error?gt("%s. %s.",e,t.message):gt("%s. %s.",e,"Unknown error")}var Is=async t=>{let e=ot.default.resolve(t??"./test-results"),r=[ot.default.posix.join(e.replace(/\\/g,"/"),"**/.last-run.json"),ot.default.posix.join(e.replace(/\\/g,"/"),".last-run.json")];return Fr.sync(r)},Cs=async(t=[])=>{let e=Xp(t);return e.length===0?[]:Fr.sync(e.map(r=>r.replace(/\\/g,"/")))};function Xp(t){let e=process.cwd();return t.filter(r=>{let o=ot.default.relative(e,ot.default.resolve(r));return o===".."||o.startsWith(`..${ot.default.sep}`)||ot.default.isAbsolute(o)?(Es(null,`Invalid path: "${r}". Path traversal detected. The path was skipped.`),!1):!0})}function _e(t){return t?t.path.some(e=>ot.default.basename(e)===".last-run.json"):!1}async function Ts(t,e){switch(e.provider){case"githubActions":await _s(t,e);break;case"gitlab":await Rs(t,e);break;case"circle":await ws(t,e);break;default:break}}async function ys(t,e,r){switch(e.provider){case"githubActions":await _s(t,e,r);break;case"gitlab":await Rs(t,e,r);break;case"circle":await ws(t,e,r);break;default:break}}async function Rs(t,e,r=null){let o=e.params,n=r?.ci.params,i=(n?bt(n.runAttempt,0):0)+1,c=bt(o.ciNodeIndex,1),m=bt(o.ciNodeTotal,1),d=_e(r),f=i>1&&d,u=f?"--last-failed":"",I="";m>1&&(I=f?"--shard=1/1":`--shard=${c}/${m}`);let g=[u,I].filter(Boolean).join(" ");await Et(t.presetOutput??zt,`EXTRA_PW_FLAGS="${g}"
23
+ EXTRA_PWCP_FLAGS="${u}"
24
+ RUN_ATTEMPT=${i}
25
+ `)}async function _s(t,e,r=null){let{matrixIndex:o,matrixTotal:n}=t,s=e.params,i=bt(s.githubRunAttempt,1),c=_e(r),m=i>1&&c,d=m?"--last-failed":"",f="";n>1&&(f=m?"--shard=1/1":`--shard=${o}/${n}`);let u=[d,f].filter(Boolean).join(" "),I=t.presetOutput??zt;await Et(I,u),p('Dumped PW config: "%s" for GHA to %s',u,I)}async function ws(t,e,r=null){let o=e.params,n=r?.ci.params,s=n?.circleWorkflowId,i=n?.circleWorkflowWorkspaceId,c=bt(o.circleNodeIndex,0),m=bt(o.circleNodeTotal,1),d=i==o.circleWorkflowWorkspaceId&&s!==o.circleWorkflowId,f=_e(r),u=d&&f,I=u?"--last-failed":"",g="";m>1&&(g=u?"--shard=1/1":`--shard=${c+1}/${m}`);let S=[I,g].filter(Boolean).join(" "),J=t.presetOutput??zt;await Et(J,S),p('Dumped PW config: "%s" for Circle to %s',S,J)}var bt=(t,e)=>{let r=kr.default.toNumber(t);return kr.default.isNaN(r)?e:r};async function $r(){let t=dt();if(t.type!=="GET_COMMAND_CONFIG"||!t.values)throw new Error("Config is missing!");let{recordKey:e,id:r,preset:o,matrixIndex:n,matrixTotal:s,continue:i}=t.values,c=t.values.outputDir,m=rt();Te(m,r),o==="last-run"&&await Ts(t.values,m);let{cacheId:d,refMetaReadUrl:f}=await fn({recordKey:e,ci:m,id:r,config:{matrixIndex:n,matrixTotal:s}});try{let u=await ed(f),{readUrl:I}=await ln({recordKey:e,cacheKey:u.cacheKey}),g=await Zp({readUrl:I,outputDir:c});o==="last-run"&&await ys(t.values,m,u),T(x("- restoring cache to"),g),ie("Cache restored. Cache ID: %s",d)}catch(u){if((0,Os.isAxiosError)(u)&&(u.response?.status===403||u.response?.status===404)){let I=`Cache with ID "${d}" not found`;if(i){gt(I);return}throw new Error(I)}throw u}}async function Zp({readUrl:t,outputDir:e}){let r=await Br(t),o=td(e);return await rs(r,o),p("Cache downloaded",{readUrl:t,destination:o}),o}function td(t){let e=t??process.cwd();return Gr.default.isAbsolute(e)?e:Gr.default.resolve(process.cwd(),e)}async function ed(t){let e=await Br(t),r=JSON.parse(e.toString("utf-8"));return p("Meta file downloaded: %O",r),r}var As=require("lodash");async function Kr(){let t=dt();if(t.type!=="SET_COMMAND_CONFIG"||!t.values)throw new Error("Config is missing!");let{recordKey:e,id:r,preset:o,pwOutputDir:n,matrixIndex:s,matrixTotal:i,continue:c}=t.values,m=await Cs(t.values.path),d=t.values.path||[],f=rt();if(Te(f,r),o==="last-run"&&(d.push(n),m.push(...await Is(n))),m.length===0){let J=`No files available to upload: ${d.filter(Boolean).join(",")}`;if(!c)throw new Error(J);gt(J)}let u=await un({recordKey:e,ci:f,id:r,config:{matrixIndex:s,matrixTotal:i}});p("Cache upload url created",{result:u});let I=od(f),g=m.length>0?await es(m):null,S=[];g&&S.push(rd({archive:g,cacheId:u.cacheId,uploadUrl:u.uploadUrl}).then(()=>{nd(m),p("Cache archive uploaded",{uploadUrl:u.uploadUrl})})),S.push(xs({meta:Mr({cacheId:u.cacheId,config:t.values,ci:I,orgId:u.orgId,path:m}),cacheId:u.cacheId,uploadUrl:u.metaUploadUrl}).then(()=>p("Meta uploaded",{uploadUrl:u.metaUploadUrl})),xs({meta:Mr({cacheId:u.cacheId,config:t.values,ci:I,orgId:u.orgId,path:m,cacheKey:u.cacheKey,metaCacheKey:u.metaCacheKey}),cacheId:u.cacheId,uploadUrl:u.refMetaUploadUrl}).then(()=>p("Ref meta uploaded",{uploadUrl:u.refMetaUploadUrl}))),await Promise.all(S),ie("Cache uploaded. Cache ID: %s",u.cacheId)}async function rd({archive:t,cacheId:e,uploadUrl:r}){try{let o="application/zip";await Lr({buffer:t,contentType:o,name:e,uploadUrl:r},o,vr(e)),p("Cache archive uploaded",{cacheId:e})}catch(o){throw p("Failed to upload cache archive",o),o}}async function xs({meta:t,cacheId:e,uploadUrl:r}){try{let o=`${e}_meta`,n="application/json";await Lr({buffer:t,contentType:n,name:o,uploadUrl:r},n,vr(o)),p("Cache meta uploaded",{cacheId:e})}catch(o){throw p("Failed to upload cache meta",o),o}}function od(t){return t.ciBuildId.source==="server"||t.ciBuildId.source==="random"?(0,As.omit)(t,"ciBuildId"):t}function nd(t){T(`Cache upload paths:
26
+ `+t.map(e=>`${x("- uploading")} ${e}`).join(`
27
+ `))}var{recordKey:sd,projectId:id,ciBuildId:ad,debug:cd}=_,Q={recordKey:sd,projectId:id,ciBuildId:ad,runId:{name:"Run ID",env:"CURRENTS_RUN_ID",cli:"--run-id"},debug:cd};var pd=p.extend("config"),dd=["recordKey","projectId"];function md(t){if(!(t.runId||t.ciBuildId))throw C(`${me(Q,"runId")} or ${me(Q,"ciBuildId")} is required: pass ${x(de(Q,"runId"))} or ${x(de(Q,"ciBuildId"))}, or set ${x(N(Q,"runId"))} or ${x(N(Q,"ciBuildId"))}`),new W("Missing required config variable")}var Hr=null;function Ss(t){Hr=U(Q,dd,t,md),pd("Resolved config: %o",h(Hr))}function we(){return Hr}async function jr(){let t=we();if(!t)throw new Error("Config is missing!");let e=t.runId?`runId: ${t.runId}`:`ciBuildId: ${t.ciBuildId}`;try{let r=await gn({recordKey:t.recordKey,projectId:t.projectId,ciBuildId:t.ciBuildId,runId:t.runId});return r.data.runId?T('Run "%s" (%s) is cancelled',r.data.runId,e):T('No run to cancel (%s) in project "%s"',e,t.projectId),r}catch(r){throw p("Failed to cancel the run"),r}}var Us=require("@currents/commit-info"),Ds=require("lodash");var ud=p.extend("git"),ld=async()=>{let t=await(0,Us.commitInfo)();return ud("commit: %O",t),{branch:t.branch,remoteOrigin:t.remote,authorEmail:t.email,authorName:t.author,message:t.message,sha:t.sha,ghaEventData:t.ghaEventData??null}},Oe=(0,Ds.memoize)(ld);var Ps=l(require("getos")),bs=require("lodash"),H=require("os"),Ns=require("util"),fd=async()=>{if((0,H.platform)()==="linux")try{let t=await(0,Ns.promisify)(Ps.default)();return"dist"in t&&"release"in t?[t.dist,t.release].join(" - "):(0,H.release)()}catch{return(0,H.release)()}return(0,H.release)()},gd=async()=>{let t=await fd();return{osName:(0,H.platform)(),osVersion:t,osCpus:[],osMemory:{free:(0,H.freemem)(),total:(0,H.totalmem)()}}},Ls=(0,bs.memoize)(gd);var Ti=l(require("axios")),Zr=l(require("fs-extra")),Ne=l(require("path")),yi=l(require("semver"));var{debug:hd,ciBuildId:Ed,recordKey:Id,projectId:Cd,machineId:Td}=_,nt={debug:hd,ciBuildId:Ed,recordKey:Id,projectId:Cd,machineId:Td,tag:{..._.tag,env:"CURRENTS_TAG"},disableTitleTags:{name:"Disable title tags",env:"CURRENTS_DISABLE_TITLE_TAGS",cli:"--disable-title-tags"},removeTitleTags:{name:"Remove title tags",env:"CURRENTS_REMOVE_TITLE_TAGS",cli:"--remove-title-tags"},reportDir:{name:"Report folder",env:"CURRENTS_REPORT_DIR",cli:"--report-dir"}};var yd=p.extend("config"),Rd=["projectId","recordKey"],Vr=null;function Bs(t){Vr=U(nt,Rd,t),yd("Resolved Currents config: %o",h(Vr))}function xe(){return Vr}function vs(t){return{ciBuildId:t.ciBuildId,projectId:t.projectId,recordKey:t.key,tag:t.tag,removeTitleTags:t.removeTitleTags,disableTitleTags:t.disableTitleTags,debug:t.debug,machineId:t.machineId,reportDir:t.reportDir}}var qr=l(require("fs-extra")),st=require("path");var Ms=l(require("path")),Jr={".png":{type:"screenshot",contentType:"image/png"},".jpg":{type:"screenshot",contentType:"image/jpeg"},".jpeg":{type:"screenshot",contentType:"image/jpeg"},".webp":{type:"screenshot",contentType:"image/webp"},".gif":{type:"screenshot",contentType:"image/gif"},".mp4":{type:"video",contentType:"video/mp4"},".webm":{type:"video",contentType:"video/webm"},".svg":{type:"attachment",contentType:"image/svg+xml"},".log":{type:"attachment",contentType:"text/plain"},".txt":{type:"attachment",contentType:"text/plain"},".yml":{type:"attachment",contentType:"text/plain"},".yaml":{type:"attachment",contentType:"text/plain"},".md":{type:"attachment",contentType:"text/markdown"},".html":{type:"attachment",contentType:"text/html"},".csv":{type:"attachment",contentType:"text/csv"},".json":{type:"attachment",contentType:"application/json"},".pdf":{type:"attachment",contentType:"application/pdf"},".gz":{type:"attachment",contentType:"application/gzip"},".viewhierarchy":{type:"attachment",contentType:"application/xml"}},Yr=t=>Jr[Ms.default.extname(t).toLowerCase()];var Fs=l(require("fs-extra")),ks=require("path"),Wr=p.extend("detox"),_d="detox.json";function Gs(t){return[...t].sort((e,r)=>(e.session??0)-(r.session??0)||e.invocations-r.invocations)}async function $s(t){let e=(0,ks.join)(t,_d);try{let r=await Fs.default.readJson(e);if(typeof r?.artifactsRootDir!="string"||!Array.isArray(r?.tests)){Wr("Unexpected Detox manifest contents at %s",e);return}return Wr("Detox manifest: %o",r),r}catch{Wr("No Detox manifest at %s",e);return}}var Ae=require("path"),wd=p.extend("detox"),Ks=255,Od=/[/\\?<>:*|"$\u0000-\u001f]/g,Hs=4;function js(t){return xd(t)??Ad(t)}function xd({rootDir:t,fullName:e,status:r,invocations:o}){try{let n=require.resolve("detox/src/artifacts/utils/ArtifactPathBuilder",{paths:[process.cwd()]}),s=require(n),i=new s({rootDir:t});return(0,Ae.dirname)(i.buildPathForTestArtifact("test.mp4",{fullName:e,status:r,invocations:o}))}catch(n){wd("Detox path builder is not available: %o",n);return}}function Ad({rootDir:t,fullName:e,status:r,invocations:o}){let n=Ud(r),s=o>1?` (${o})`:"",i=e.slice(-Ks+n.length+s.length),c=`${n}${i}${s}`.replace(Od,"_");return(0,Ae.join)(t,Sd(c,Ks))}function Sd(t,e){let r=Buffer.from(t,"utf8");return r.length<=e?t:r.subarray(0,e).toString("utf8").replace(/\uFFFD$/,"")}function Ud(t){switch(t){case"passed":return"\u2713 ";case"failed":return"\u2717 ";default:return""}}var Js=l(require("fs-extra")),Ys=require("path"),Vs=p.extend("detox"),Se="detox.trace.json",Dd="ws-client-invocation";async function Ws(t){let e=(0,Ys.join)(t,Se),r=new Map,o;try{o=await Js.default.readJson(e)}catch{return Vs("No Detox trace at %s",e),r}if(!Array.isArray(o))return Vs("Unexpected Detox trace contents at %s",e),r;let n=Pd(o);return Nd(o).forEach(({pid:i,ts:c,step:m})=>{n.filter(f=>f.pid===i&&c>=f.startTs&&c<=f.endTs).sort((f,u)=>f.startTs-u.startTs).pop()?.steps.push(m)}),n.forEach(({fullName:i,invocations:c,steps:m})=>{let d=r.get(i)??[];d.push({fullName:i,invocations:c,steps:m.sort((f,u)=>+new Date(f.startTime)-+new Date(u.startTime))}),r.set(i,d)}),r}function Pd(t){let e=new Map,r=[];t.forEach(n=>{let s=`${n.pid}:${n.tid}`,i=e.get(s)??[];if(e.set(s,i),n.ph==="B"){i.push(bd(n));return}if(n.ph==="E"){let c=i.pop();c&&r.push({...c,endTs:Number(n.ts)})}});let o=[...e.values()].flatMap(n=>n.filter(s=>s!==void 0));return[...r,...o]}function bd(t){let e=t.args?.fullName;if(!(t.args?.context!=="test"||typeof e!="string"))return{fullName:e,invocations:Number(t.args?.invocations??1),pid:Number(t.pid),startTs:Number(t.ts),endTs:Number.MAX_SAFE_INTEGER,steps:[]}}function Nd(t){let e=new Map,r=[];return t.forEach(o=>{if(!o.cat?.includes(Dd))return;let n=`${o.pid}:${o.tid}`,s=e.get(n)??[];if(o.ph==="B"){s.push({name:o.name??"action",cat:o.cat,ts:Number(o.ts)}),e.set(n,s);return}if(o.ph==="E"){let i=s.pop();if(!i)return;r.push({pid:Number(o.pid),ts:i.ts,step:{title:i.name,category:"detox",startTime:new Date(i.ts/1e3).toISOString(),duration:Math.round((Number(o.ts)-i.ts)/1e3),steps:[]}})}}),r}var Zt=p.extend("detox"),qs="artifacts",Ld=[".mp4",".png",".jpg",".log",".txt",".json",".viewhierarchy"],Bd=t=>{let e=(0,st.extname)(t);return Ld.includes(e)?Jr[e]:void 0};async function zs({instances:t,reportDir:e,manifest:r}){let o=Md(r),n=await Ws(r.artifactsRootDir),s=await It((0,st.join)(e,qs)),i={artifacts:0,steps:0};for(let c of t)for(let m of c.results.tests){let d=o.get(m.testId);if(!d){Zt("No Detox manifest entry for %s",m.testId);continue}await Fd({test:m,manifestTest:d,rootDir:r.artifactsRootDir,artifactsDir:s,traceSlices:n.get(d.fullName)??[],result:i})}return i.artifacts+=await vd({instances:t,rootDir:r.artifactsRootDir,artifactsDir:s}),i}async function vd({instances:t,rootDir:e,artifactsDir:r}){if(!await qr.default.pathExists((0,st.join)(e,Se)))return 0;let[o]=await Qs(e,[Se],r),n=t.map(s=>s.results.tests[0]).filter(s=>s!==void 0);return n.forEach(s=>{s.artifacts=[...s.artifacts??[],o]}),n.length}function Md(t){let e=new Map;return t.tests.forEach(r=>{e.set(r.fullName,[...e.get(r.fullName)??[],r.testId])}),new Map(t.tests.filter(r=>{let o=e.get(r.fullName)?.length===1;return o||Zt("Ambiguous Detox test name, skipping: %s",r.fullName),o}).map(r=>[r.testId,r]))}async function Fd({test:t,manifestTest:e,rootDir:r,artifactsDir:o,traceSlices:n,result:s}){let i=[...t.attempts].sort((d,f)=>d.attempt-f.attempt),c=Gs(e.attempts),m=1;for(let[d,f]of c.entries()){let u=i[d];if(!u){Zt("No reported attempt %d of %s",d,e.fullName);continue}let I=await kd({fullName:e.fullName,status:f.status,rootDir:r,artifactsDir:o,fromInvocation:m});I&&(m=I.invocation+1,u.artifacts=[...u.artifacts??[],...I.artifacts],s.artifacts+=I.artifacts.length);let g=$d(n,d,I?.invocation);g.length&&(u.steps=[...u.steps??[],...g],s.steps+=g.length)}}async function kd({fullName:t,status:e,rootDir:r,artifactsDir:o,fromInvocation:n}){for(let s=n;s<n+Hs;s++){let i=js({rootDir:r,fullName:t,status:e,invocations:s}),c=await Gd(i);if(c)return{invocation:s,artifacts:await Qs(i,c,o)}}Zt("No Detox artifacts for %s [%s]",t,e)}async function Gd(t){try{return(await qr.default.readdir(t)).sort()}catch{return}}async function Qs(t,e,r){let o=[];for(let n of e){let s=Bd(n);if(!s){Zt("Skipping unsupported Detox artifact %s",n);continue}let i=(0,st.join)(t,n),c=`${et(i)}${(0,st.extname)(n)}`;await ce(i,(0,st.join)(r,c)),o.push({...s,path:(0,st.join)(qs,c),name:n})}return o}function $d(t,e,r){return((r===void 0?void 0:t.find(s=>s.invocations===r))??[...t].sort((s,i)=>s.invocations-i.invocations)[e])?.steps??[]}var mt=class{constructor(e){this.config=e}async getFullTestSuite(){return[]}};var ci=l(require("fs-extra")),pi=require("jest-cli"),di=l(require("tmp"));var ii=require("lodash");function Xs(t){let e=[];for(let[r,o]of Object.entries(t))r==="_"||r==="$0"||r.includes("-")||(typeof o=="boolean"?o&&e.push(`--${r}`):Array.isArray(o)?o.forEach(n=>{e.push(`--${r}=${n}`)}):e.push(`--${r}=${o}`));return e.join(" ")}var Zs=require("lodash"),Kd=["bail","clearCache","collectCoverage","collectCoverageFrom","color","colors","config","coverage","coverageDirectory","coveragePathIgnorePatterns","coverageProvider","coverageReporters","coverageThreshold","debug","detectLeaks","detectOpenHandles","errorOnDeprecated","expand","forceExit","json","listTests","logHeapUsage","noStackTrace","notify","notifyMode","openHandlesTimeout","outputFile","reporters","runner","shard","showConfig","showSeed","silent","testNamePattern","verbose","waitNextEventLoopTurnForUnhandledRejectionEvents","watch","watchAll","watchPathIgnorePatterns","watchman"];function ti(t){return(0,Zs.omit)(t,...Kd)}var oi=l(require("fs")),ni=require("jest-config"),zr=require("lodash"),Qr=l(require("path"));function Ue(t,e){return(...r)=>new Promise((o,n)=>{let s=0,i=()=>{s++;try{let c=t(...r);o(c)}catch(c){if(s>=e.length)n(c);else{let m=e[s-1];setTimeout(i,m)}}};i()})}var ei=l(require("fs-extra")),Hd=l(require("path"));async function De(t){let e=await ei.default.pathExists(t);if(!e)throw new Error("File does not exist");return e}var ri=p.extend("jest-discovery");async function si(t){try{let{config:e,configPath:r}=await(0,ni.readInitialOptions)(t),o=["collectCoverage","collectCoverageFrom","coverageDirectory","coveragePathIgnorePatterns","coverageProvider","coverageReporters","coverageThreshold","errorOnDeprecated","forceCoverageMatch","notify","notifyMode","openHandlesTimeout","reporters","runner","showSeed","testFailureExitCode","verbose","watchPathIgnorePatterns","watchPlugins","watchman","bail","clearCache","color","colors","debug","detectLeaks","detectOpenHandles","expand","forceExit","json","listTests","logHeapUsage","noStackTrace","outputFile","shard","showConfig","silent","testNamePattern","waitNextEventLoopTurnForUnhandledRejectionEvents","watch","watchAll"],n=["collectCoverageFrom","coverageDirectory","coveragePathIgnorePatterns","detectLeaks","detectOpenHandles","errorOnDeprecated","forceCoverageMatch","openHandlesTimeout","runner","watchPathIgnorePatterns"],s=(0,zr.omit)(e,o);if(s.projects&&(s.projects=s.projects.map(m=>typeof m!="string"?(0,zr.omit)(m,n):m)),s.rootDir&&Object.keys(s).length===1)return null;let i=Qr.default.resolve(r?Qr.default.dirname(r):process.cwd(),`.jest-scanner-${new Date().getTime()}.config.cjs`),c=`module.exports=${JSON.stringify(s,null,2)}`;return ri("configFileContent: %O",c),oi.default.writeFileSync(i,c),await Ue(De,[200,200,200,200,200,1e3])(i),i}catch(e){return C("Failed to recreate the config file"),ri("error %o",e),null}}async function ai(t){let e="!!##ThisPatternWillNotMatchAnyTestName##!!",r=t.options,o=ti(r),n=Xs(o),s=r.config,i=await si(s);return{cliArgs:[n,"--testNamePattern",e,"--reporters","@currents/cmd/discovery/jest","--shard=1/1",i?`--config=${i}`:"",...t.args].filter(m=>!(0,ii.isEmpty)(m)),configFilePath:i}}var jd=p.extend("jest-discovery");async function mi(t,e){console.time(x("@currents/jest:fullTestSuite-ready"));let{cliArgs:r,configFilePath:o}=await ai(e);try{let n=di.default.fileSync({postfix:".json"});return jd("running scanner: %o",r),process.env.CURRENTS_DISCOVERY_PATH=n.name,await(0,pi.run)(r.concat(["--openHandlesTimeout=0"])),await Ue(De,Array.from({length:300},()=>100))(n.name),console.timeEnd(x("@currents/jest:fullTestSuite-ready")),await ht(n.name)}catch(n){return C("Failed to obtain the jest full test suite:",n),[]}finally{o&&ci.default.unlinkSync(o)}}var Pe=class extends mt{constructor(e){super(e)}async getFullTestSuite(){return mi(this.config.frameworkConfig,this.config.cliArgs)}};var li=l(require("fs-extra"));var ui=l(require("path"));function Tt(t){return ui.default.join(t,"fullTestSuite.json")}var Vd=p.extend("junit-discovery");async function fi(t){console.time(x("@currents/junit:fullTestSuite-ready"));try{Vd("running scanner: %o",t);let e=Tt(t);process.env.CURRENTS_DISCOVERY_PATH=e;let r=li.default.readFileSync(e,"utf-8");return JSON.parse(r)}catch(e){return C("Failed to obtain the junit full test suite:",e),[]}}var be=class extends mt{constructor(e,r){super(e),this.reportDir=r}async getFullTestSuite(){return fi(this.reportDir)}};function gi(t,e){switch(t.framework){case"jest":return new Pe(t);case"junit":return new be(t,e);default:return new mt(t)}}var ut=l(require("fs-extra")),it=l(require("path"));async function hi(t){let e=await Jd(t?.reportDir);return{reportDir:e,configFilePath:t?.configFilePath??it.default.join(e,"config.json")}}async function Jd(t){if(t){if(!await ut.default.pathExists(t))throw new Error(`No reports found: the folder "${t}" does not exist.`);return t}let e=(0,it.join)(process.cwd(),".currents"),r=await ut.default.pathExists(e)?await Yd(e):null;if(!r)throw new Error(`No reports found: there is no report folder in "${e}". Run the tests with a Currents reporter first, or pass --report-dir with the folder of the reports.`);return r}async function Yd(t){let e=await ut.default.readdir(t),r=null;for(let o of e){let n=it.default.join(t,o),s=await ut.default.stat(n);s.isDirectory()&&(!r||s.birthtime>r.birthtime)&&(r={name:o,birthtime:s.birthtime})}return r?(0,it.resolve)(t,r.name):null}async function Xr(t){try{return await ut.default.pathExists(t)}catch{return C("Error checking if path exists:",C),!1}}async function Ei(t){let e=it.default.join(t,"instances");return Wd(e)}async function Wd(t){let e=await ut.default.readdir(t),r=[];for(let o of e){let n=it.default.join(t,o);(await ut.default.stat(n)).isFile()&&r.push(n)}return r}var qd=t=>Buffer.byteLength(JSON.stringify(t),"utf8"),Ii=(t,e=1048576)=>{let r=[],o=[],n=0;for(let s of t){let i=qd(s);n+i>e&&(r.push(o),o=[],n=0),o.push(s),n+=i}return o.length>0&&r.push(o),r};var zd=3e4;async function to(){let t=xe();if(!t)throw new Error("Currents config is missing!");let e=await hi(t);Lo(Xd(e.reportDir)),p("Reporter options: %o",e),T("Report directory: %s",e.reportDir);let r=await ht(e.configFilePath);p("Report config: %o",r);let o=await Ei(e.reportDir);p("Found %d instance results in the reportDir: %s",o.length,e.reportDir);let n=Qd(e.reportDir),s=await Xr(n),i=Tt(e.reportDir),c=null;if(s){let M=await ht(n);E("Marker file detected. The report was already uploaded: %o",{runUrl:M.response.runUrl,isoDate:M.isoDate})}if(await Xr(i)&&(c=await ht(i),p("Full test suite file detected: %s",i)),c)p("The discovery stage was skipped");else{if(c=await gi(r,e.reportDir).getFullTestSuite(),Zd(c))throw new Error("Failed to discover the full test suite!");await Et(i,JSON.stringify(c))}let d=c.length===1?c[0].name:null,f={currents:t},u={type:r.framework,version:r.frameworkVersion,clientVersion:xt,frameworkConfig:{originFramework:r.frameworkConfig?.originFramework,originFrameworkVersion:r.frameworkConfig?.originFrameworkVersion}},I=pe.userFacingNanoid(),g=rt(t.ciBuildId),S={};for await(let M of o){let $=await ht(M);S[$.groupId]||(S[$.groupId]=[]),S[$.groupId].push($)}let J=await $s(e.reportDir);if(J){let M=await zs({instances:Object.values(S).flat(),reportDir:e.reportDir,manifest:J});T("[currents] Attached %d Detox artifacts and %d steps",M.artifacts,M.steps)}let Ot=new Map;Object.values(S).forEach(M=>{M.forEach($=>{$.artifacts?.forEach(K=>{K&&Ot.set(K.path,K.contentType)}),$.results.tests.forEach(K=>{K.artifacts?.forEach(k=>{k&&Ot.set(k.path,k.contentType)}),K.attempts.forEach(k=>{k.artifacts?.forEach(ft=>{ft&&Ot.set(ft.path,ft.contentType)})})})})});for await(let M of Object.keys(S)){let $=S[M],K=M;d&&(p("Default group found: %s, overwriting the group in the results",d),K=d,$=$.map(k=>({...k,groupId:d})));try{let k=Ii($),ft=await Ci({ci:g,group:K,instances:[],fullTestSuite:c,config:f,machineId:I,framework:u});for(let mr=0;mr<k.length;mr++){let ur=await Ci({ci:g,group:K,instances:k[mr],fullTestSuite:[],config:f,machineId:I,framework:u});ur.artifactUploadUrls&&ur.artifactUploadUrls.length>0&&await tm(ur.artifactUploadUrls,e.reportDir,Ot)}p("Api response: %o",ft),T("[%s] Run created: %s",K,ft.runUrl);let Bc={response:ft,isoDate:new Date().toISOString()};await Et(n,JSON.stringify(Bc)),p("Marker file %s: %s",s?"overwritten":"created",n)}catch(k){throw p("Failed to upload the results to the dashboard"),k}}}async function Ci({ci:t,group:e,instances:r,fullTestSuite:o,config:n,machineId:s,framework:i}){let c=await Oe(),m=await Ls(),d={browserName:"node",browserVersion:yi.default.coerce(process.version)?.version},{currents:f}=n,I={platform:{...d,...m},ci:t,commit:c,group:e,fullTestSuite:o,config:n,projectId:f.projectId,recordKey:f.recordKey,ciBuildId:t.ciBuildId.value??void 0,tags:f.tag??[],machineId:f.machineId??s,framework:i,instances:r,previousCiBuildId:process.env.CURRENTS_PREVIOUS_CI_BUILD_ID};return p("Creating run: %o",h(I)),Cn(I)}function Qd(t){return Ne.default.join(t,"upload.marker.json")}function Xd(t){return Ne.default.join(t,`.debug-${new Date().toISOString()}.log`)}function Zd(t){return t.length===0||t.some(e=>e.tests.length===0)}async function tm(t,e,r){p("Uploading %d artifacts",t.length),await Promise.all(t.map(o=>{let n=Ne.default.join(e,o.path),s=r.get(o.path)||"application/octet-stream";return em(n,s,o.uploadUrl)}))}var em=async(t,e,r)=>{try{if(!await Zr.default.pathExists(t)){E("Artifact file not found: %s",t);return}let o=await Zr.default.readFile(t);await Ti.default.put(r,o,{headers:{"Content-Type":e},timeout:zd})}catch(o){p("Failed to upload artifact %s: %o",t,o)}};var rm=p.extend("cli");async function Ri(t,e){await w(async r=>{r.output||Pt(),e.getOptionValueSource("ciBuildId")==="env"&&(r.branch||r.tag)&&(r={...r,ciBuildId:void 0}),Yo(r);let n=le();rm("Config: %o",h(n)),await Sr()},t)}var X=require("@commander-js/extra-typings");var Oi=require("axios"),xi=l(require("fs-extra"));var om=p.extend("api");function nm(t){if(/^[a-z][a-z0-9+.-]*:\/\//i.test(t))throw new Error(`Pass a path such as /v1/runs/<run-id>, not a URL. The CLI sends requests to ${Jt()}`);let e=t.replace(/^\/+/,""),r=o=>/^(\.|%2e){1,2}$/i.test(o);if(e.split(/[?#]/)[0].split("/").some(r))throw new Error(`The path cannot hold "." or ".." segments: ${t}`);return/^v1(\/|\?|$)/.test(e)?e:`v1/${e}`}function sm(t){let e=Object.create(null);for(let[r,o]of t)if(r.endsWith("[]")){let n=r.slice(0,-2);e[n]=[...Array.isArray(e[n])?e[n]:[],o]}else e[r]=o;return e}function im(t){let e=new URLSearchParams;for(let[r,o]of t)e.append(r,String(o));return e}async function am(t){let e=t==="-"?await new Promise((r,o)=>{let n="";process.stdin.setEncoding("utf8"),process.stdin.on("data",s=>n+=s),process.stdin.on("end",()=>r(n)),process.stdin.on("error",o)}):await xi.default.readFile(t,"utf8");try{return JSON.parse(e)}catch(r){throw new Error(`--input ${t} is not valid JSON: ${r.message}`)}}async function cm(t,e){let r=[...e.field??[],...e.rawField??[]],o=e.input!==void 0,n=e.method??(o||r.length>0?"POST":"GET"),s=o||n==="GET"||n==="HEAD";return{method:n,url:nm(t),params:s&&r.length>0?im(r):void 0,data:o?JSON.stringify(await am(e.input)):!s&&r.length>0?JSON.stringify(sm(r)):void 0,headers:Object.fromEntries(e.header??[])}}function _i(t){let e=Object.entries(t.headers).map(([r,o])=>`${r}: ${Array.isArray(o)?o.join(", "):o}`);return[`HTTP/1.1 ${t.status} ${t.statusText}`,...e,"",""].join(`
28
+ `)}function wi(t,e){let r=t.data??"",o=String(t.headers["content-type"]??"").toLowerCase().includes("json");if(!e||!o||!r)return r;try{return JSON.stringify(JSON.parse(r),null,2)+`
29
+ `}catch{return r}}async function Ai(t,e){let{apiKey:r}=U(_,["apiKey"],e),o=s=>s?.map(([i])=>i);om("Options: %o",h({...e,field:o(e.field),rawField:o(e.rawField),header:o(e.header)}));let n=await cm(t,e);try{let s=await An(r,n);e.include&&process.stdout.write(_i(s)),process.stdout.write(wi(s,!!process.stdout.isTTY))}catch(s){if(!(0,Oi.isAxiosError)(s))throw s;let i=s.response;if(!i)throw new Error(`Could not reach the REST API at ${Jt()}: ${s.message}`);e.include&&process.stderr.write(_i(i));let c=wi(i,!!process.stderr.isTTY);throw c&&process.stderr.write(c.endsWith(`
30
+ `)?c:`${c}
31
+ `),new Error(`${n.method} ${n.url.split("?")[0]} failed: the REST API answered ${i.status} ${i.statusText}`)}}var Si=["GET","POST","PUT","PATCH","DELETE","HEAD"];function eo(t,e){let r=t.indexOf(e),o=r<0?"":t.slice(0,r).trim();if(!o)throw new X.InvalidArgumentError(`Expected key${e}value.`);let n=t.slice(r+1);return[o,e===":"?n.trim():n]}function pm(t){if(t==="true")return!0;if(t==="false")return!1;if(t==="null")return null;if(/^-?\d+(\.\d+)?$/.test(t)){let e=Number(t);if(t.includes(".")?Number.isFinite(e):Number.isSafeInteger(e))return e}return t}var dm=(t,e=[])=>{let[r,o]=eo(t,"=");return[...e,[r,pm(o)]]},mm=(t,e=[])=>[...e,eo(t,"=")],um=(t,e=[])=>[...e,eo(t,":")],Ui=new X.Option("-X, --method <method>","the HTTP method; GET by default, POST when --field, --raw-field or --input is given").argParser(t=>{let e=t.toUpperCase();if(!Si.includes(e))throw new X.InvalidArgumentError(`Use one of ${Si.join(", ")}.`);return e}),Di=new X.Option("-f, --field <key=value>","a request parameter; repeat for more. Sent in the query string of a GET and in the JSON body otherwise. true, false, null and numbers are sent as JSON values; in a JSON body, key[]=value adds the value to an array").argParser(dm),Pi=new X.Option("-F, --raw-field <key=value>","like --field, but the value is always a string").argParser(mm),bi=new X.Option("--input <file>",'send the JSON in this file as the body, or the JSON from stdin with "-"; fields then go to the query string'),Ni=new X.Option("-H, --header <key:value>","an HTTP header to send; repeat for more").argParser(um),Li=new X.Option("-i, --include","print the HTTP status line and the response headers before the body");async function Bi(t,e){await w(async r=>{Pt(),await Ai(t,r)},e)}var yt=require("@commander-js/extra-typings");var ro="(required)",at=(t=ro)=>new yt.Option("-k, --key <record-key>",`the record key from the Currents dashboard ${t}`).env(_.recordKey.env),ct=(t=ro)=>new yt.Option("--api-key <api-key>",`an API key from the Currents dashboard ${t}`).env(_.apiKey.env),Z=()=>new yt.Option("-p, --project-id <id>",`the project ID from the Currents dashboard ${ro}`).env(_.projectId.env),Nt=t=>new yt.Option("--ci-build-id <id>",`the CI build ID the run was recorded with${t}`).env(_.ciBuildId.env),Lt=t=>new yt.Option("-t, --tag <tag>",`${t}; comma-separated or repeated`).argParser(Ie),P=()=>new yt.Option("--debug","print debug logs; keys are hidden in them").env(_.debug.env).default(!1);var Le=require("@commander-js/extra-typings");var vi=new Le.Option("-o, --output <path>","write the JSON to this file instead of stdout").env(N(ue,"output")),Mi=Nt("; cannot be combined with --branch or --tag. The environment variable is ignored when --branch or --tag is set"),Fi=Lt("find the last run with these tags"),ki=new Le.Option("-b, --branch <branch>","find the last run of this git branch"),Gi=new Le.Option("--pw-last-run","print only the status and the failed tests of the run, in the format of Playwright's .last-run.json");var Be="get",oo="run",so=t=>[{comment:"Get the data of the run recorded under a CI build ID",commands:[`${t} ${oo} ${Be} --api-key <api-key> --project-id <project-id> --ci-build-id <ci-build-id>`]},{comment:"Get the data of the last run of a branch with the tags tagA and tagB",commands:[`${t} ${oo} ${Be} --api-key <api-key> --project-id <project-id> --branch <branch> --tag tagA,tagB`]},{comment:'Save the failed tests of a run where Playwright reads them, for "playwright test --last-failed"',commands:[`${t} ${oo} ${Be} --api-key <api-key> --project-id <project-id> --ci-build-id <ci-build-id> --pw-last-run --output test-results/.last-run.json`]}],lm=t=>[{comment:"Get a run, with the API key in CURRENTS_API_KEY",commands:[`${t} api /v1/runs/<run-id>`]},{comment:"List the failed runs of the main branch of a project",commands:[`${t} api /v1/projects/<project-id>/runs -X GET -f "branches[]=main" -f status=FAILED -f limit=20`]},{comment:"Cancel a run",commands:[`${t} api /v1/runs/<run-id>/cancel -X PUT`]},{comment:"Create a webhook from the JSON in webhook.json",commands:[`${t} api /v1/webhooks -X POST -F projectId=<project-id> --input webhook.json`]}],$i=t=>new no.Command().name("api").summary("Make an authenticated request to the Currents REST API").description(`Make an authenticated request to the Currents REST API and print the response body. The path is a REST API route, such as /v1/runs/<run-id>; v1/runs/<run-id> and runs/<run-id> are the same route. A response that is not 2xx prints its body on stderr and exits with 1.
32
+
33
+ The REST API routes: https://docs.currents.dev/resources/api/api-resources`).usage("<path> [options]").argument("<path>","the REST API route, such as /v1/runs/<run-id>").enablePositionalOptions().helpCommand(!1).addOption(ct()).addOption(Ui).addOption(Di).addOption(Pi).addOption(bi).addOption(Ni).addOption(Li).addOption(P()).addHelpText("after",y(lm(t))).showHelpAfterError("(add --help for additional information)").addCommand(io(t).name("get-run"),{hidden:!0}).action((r,o,n)=>r==="help"?n.help():Bi(r,o)),io=t=>new no.Command().name(Be).summary("Get the data of a run from the Currents API").description("Get the data of a run from the Currents API and print it as JSON, or write it to --output. Find the run by --ci-build-id, or the last run by --branch, --tag or both").addHelpText("after",y(so(t))).allowUnknownOption().addOption(ct()).addOption(P()).addOption(Mi).addOption(Z()).addOption(ki).addOption(Fi).addOption(vi).addOption(Gi).action(Ri);var ve=require("@commander-js/extra-typings");var fm=p.extend("cli");async function Ki(t){await w(async e=>{Yn(Wn(e));let r=dt();fm("Config: %o",h(r.values)),await $r()},t)}var gm=p.extend("cli");async function Hi(t){await w(async e=>{Jn(qn(e));let r=dt();gm("Config: %o",h(r.values)),await Kr()},t)}var Bt="cache",Me=t=>[{comment:"Save files to the cache under an ID",commands:[`${t} ${Bt} set --key <record-key> --id <id> --path <path-1,path-2,...path-n>`]},{comment:"Save Playwright's .last-run.json to the cache",commands:[`${t} ${Bt} set --key <record-key> --preset last-run`]}],Fe=t=>[{comment:"Restore the files saved in the cache under an ID",commands:[`${t} ${Bt} get --key <record-key> --id <id>`]},{comment:"Restore Playwright's .last-run.json from the cache, to rerun only the failed tests",commands:[`${t} ${Bt} get --key <record-key> --preset last-run`]},{comment:"Restore Playwright's .last-run.json to another folder",commands:[`${t} ${Bt} get --key <record-key> --preset last-run --output-dir <output-dir>`]}],ji=t=>new ve.Command().command(Bt).summary("Save files to the Currents cache and restore them").description("Save files to the Currents cache and restore them, e.g. in another CI job").addHelpText("after",y([...Me(t),...Fe(t)])).showHelpAfterError("(add --help for additional information)").allowUnknownOption().addCommand(hm(t)).addCommand(Em(t)),hm=t=>new ve.Command().name("set").description("Save files to the cache").addHelpText("after",y(Me(t))).allowUnknownOption().addOption(at()).addOption(Nn).addOption(vn).addOption(Bn).addOption(P()).addOption(kn).addOption(Ur).addOption(Dr).addOption(Hn).action(Hi),Em=t=>new ve.Command().name("get").description("Restore files from the cache").addHelpText("after",y(Fe(t))).allowUnknownOption().addOption(at()).addOption(Ln).addOption(Mn).addOption(Fn).addOption(Gn).addOption(P()).addOption(Ur).addOption(Dr).addOption(Kn).action(Ki);var qi=require("@commander-js/extra-typings");var Im=p.extend("cli");async function Vi(t){await w(async({key:e,...r})=>{Ss({...r,recordKey:e});let o=we();Im("Config: %o",h(o??{})),await jr()},t)}var Ji=require("@commander-js/extra-typings");var Yi=Nt(" (required unless --run-id is set)"),Wi=new Ji.Option("--run-id <id>","the ID of the run to cancel, as printed when the run was created; wins over --ci-build-id").env(N(Q,"runId"));var vt="cancel",ke="run",te=t=>[{comment:"Cancel the run recorded under a CI build ID",commands:[`${t} ${ke} ${vt} --key <record-key> --project-id <id> --ci-build-id <build-id>`]},{comment:"Cancel a run by its ID, as printed when the run was created",commands:[`${t} ${ke} ${vt} --key <record-key> --project-id <id> --run-id <run-id>`]},{comment:"Cancel the run when a GitHub Actions workflow is cancelled (workflow step). It reads CURRENTS_RECORD_KEY, CURRENTS_PROJECT_ID and CURRENTS_CI_BUILD_ID from the environment",commands:[`- if: \${{ cancelled() }}
34
+ run: npx ${t} ${ke} ${vt}`]}],Ge=(t,{deprecated:e=!1}={})=>{let r=new qi.Command().name(vt).summary("Cancel a run in progress").description("Cancel a run in progress, e.g. when the CI job it belongs to is cancelled").addHelpText("after",y(te(t))).allowUnknownOption().addOption(at()).addOption(Z()).addOption(Yi).addOption(Wi).addOption(P()).action(Vi);return e&&r.hook("preAction",()=>{process.stderr.write(`'${t} ${vt}' is deprecated and will be removed in a future version. Use '${t} ${ke} ${vt}'.
35
+ `)}),r};var Ea=require("@commander-js/extra-typings");var zi={debug:_.debug,inputFormat:{name:"Input format",cli:"--input-format"},inputFiles:{name:"Input file",cli:"--input-file"},outputDir:{name:"Output folder",cli:"--output-dir"},framework:{name:"Framework",cli:"--framework"},frameworkVersion:{name:"Framework version",cli:"--framework-version"}};var Cm=p.extend("config"),Tm=["inputFormat","inputFiles","framework"],ao=null;function Qi(t){ao=U(zi,Tm,t),Cm("Resolved config: %o",ao)}function $e(){return ao}function Xi(t){return{inputFiles:t.inputFile,inputFormat:t.inputFormat,outputDir:t.outputDir,framework:t.framework,frameworkVersion:t.frameworkVersion,debug:t.debug}}var ho=l(require("fs-extra")),L=require("path");var oa=require("lodash"),na=l(require("crypto"));var j=require("path"),He=async(t,e,r,o)=>{if(t)for(let n of t)try{let s=(0,j.resolve)(o,n.path),i=(0,j.relative)(o,s);if(i.startsWith("..")||(0,j.isAbsolute)(i)){p("Skipping artifact outside workspace: %s (resolved: %s)",n.path,s);continue}let c=`${et(e+n.path)}.${(0,j.extname)(n.path).slice(1)||"bin"}`;await ce(s,(0,j.join)(r,c)),n.path=(0,j.join)("artifacts",c)}catch(s){p("Failed to copy artifact %s: %o",n.path,s)}};function ta(t){let e=ra(t.properties?.property??t.property);return Ke(e,"currents.artifact.instance.","spec")}function ea(t){let e=ra(t.properties?.property),r=Ke(e,"currents.artifact.test.","test"),o=new Map;ym(e).forEach((i,c)=>{o.has(c)||o.set(c,[]),o.get(c).push(...i)});let s=Ke(e,"currents.artifact.attempt.","attempt");return s.length>0&&(o.has(0)||o.set(0,[]),o.get(0).push(...s)),{testArtifacts:r,attemptArtifacts:o}}function ym(t){let e=new Map,r=/^currents\.artifact\.attempt\.(\d+)\.(.+)$/,o=new Map;for(let n of t){let s=n.value??n._;if(!n.name||!s)continue;let i=n.name.match(r);if(!i)continue;let[,c,m]=i,d=parseInt(c,10);o.has(d)||o.set(d,[]),o.get(d).push({name:`currents.artifact.attempt.${m}`,value:s})}for(let[n,s]of o.entries()){let i=Ke(s,"currents.artifact.attempt.","attempt");i.length>0&&e.set(n,i)}return e}function Ke(t,e,r){let o=[],n={};for(let s of t){let i=s.value??s._;if(!s.name||!i||!s.name.startsWith(e))continue;let c=s.name.slice(e.length);/^\d+\./.test(c)||["path","type","contentType","name"].includes(c)&&(n[c]&&(Zi(n)&&o.push({...n,level:r}),n={}),n[c]=i)}return Zi(n)&&o.push({...n,level:r}),o}function Zi(t){return!!(t.path&&t.type&&t.contentType)}function ra(t){return t?Array.isArray(t)?t:[t]:[]}function sa(t,e,r,o){let n=Rt(t.failure),s=n.length>0,i=e?.timestamp??"",c="skipped"in t,m=c?"pending":s?"failed":"passed",{testArtifacts:d,attemptArtifacts:f}=ea(t);return{_t:je(i),testId:uo(ee(t.name,o).join(", "),o),title:ee(t.name,o),state:m,isFlaky:Rm(),expectedStatus:"passed",timeout:_m(),location:wm(e?.file??""),retries:Om(n),artifacts:d,attempts:xm(t,n,lo(i),r,f,c)}}function uo(t,e){let r=`${t}${e}`;return na.default.createHash("sha256").update(r).digest("hex").substring(0,16)}function je(t){return ia(t)?new Date(t).getTime():new Date().getTime()}function lo(t){return ia(t)?new Date(t).toISOString():new Date().toISOString()}function ia(t){let e=new Date(t);return!isNaN(e.getTime())}function ee(t,e){return[e,t].filter(Boolean)}function Rm(){return!1}function _m(){return 0}function wm(t){return{column:1,file:t,line:1}}function Om(t){let e=0;return t.forEach(r=>{typeof r!="string"&&e++}),e}function xm(t,e,r,o,n,s){let i=t.time?Ve(t.time):0;if(s)return[{_s:"pending",attempt:0,startTime:r,steps:[],duration:i,status:"skipped",stdout:co(t?.["system-out"]),stderr:po(t?.["system-err"]),artifacts:n.get(0),errors:[],error:void 0}];if(e.length===0){let c=[];return n.forEach(m=>{c.push(...m)}),[{_s:"passed",attempt:0,startTime:r,steps:[],duration:i,status:"passed",stdout:co(t?.["system-out"]),stderr:po(t?.["system-err"]),artifacts:c,errors:[],error:void 0}]}return e.reduce((c,m,d)=>{if(m!=="true"&&m!=="false"){let f=Am(m);c.push({_s:"failed",attempt:d,startTime:Sm(o,r),steps:[],duration:i,status:"failed",stdout:co(t?.["system-out"]),stderr:po(t?.["system-err"]),artifacts:n.get(d),errors:f,error:f[0]})}return c},[])}function co(t){return t?[t]:[]}function po(t){return t?[t]:[]}function Am(t){return t==="true"||t==="false"?[]:[typeof t=="string"?{message:t}:{message:t.message,stack:t._,value:t.type}]}function Sm(t,e){let r=je(e)+t;return new Date(r).toISOString()}function Rt(t){return t?Array.isArray(t)?t:[t]:[]}function Um(t){return Math.round(t*1e3)}function Ve(t){let e=parseFloat(t);return isNaN(e)?0:Um(e)}function Je(t,e,r){let o=(0,oa.isNumber)(r)&&r>0,n=!!t.id&&mo(e,"id",t.id);if(t.file){let s=mo(e,"file",t.file);return s&&!n?`${t.file} - ${t.id}`:s&&o?`${t.file} - ${r}`:t.file}if(t.name){let s=mo(e,"name",t.name);return s&&!n?`${t.name} - ${t.id}`:s&&o?`${t.name} - ${r}`:t.name}return t.id?n&&o?`${t.id} - ${r}`:t.id:o?`unknown - ${r}`:"unknown"}function mo(t,e,r){return t.filter(n=>n[e]===r).length>1}function aa(t){let e=[];return t.forEach(r=>{let o=Rt(r.testsuites?.testsuite),n={name:r.testsuites?.name??"No name",tags:[],tests:[]};o?.forEach(s=>{let i=Je(s,o);Rt(s?.testcase)?.forEach(m=>{let d={title:ee(m.name,i),spec:i,tags:[],testId:uo(ee(m.name,i).join(", "),i)};n.tests.push(d)})}),e.push(n)}),e}var lt=require("@commander-js/extra-typings"),ca=l(require("globby")),fo=(e=>(e.junit="junit",e))(fo||{}),Ye=t=>new lt.Option("--input-format <format>",["the format of the reports to convert",t].filter(Boolean).join(" ")).choices(Object.values(fo)),We=t=>new lt.Option("--input-file <patterns>",`comma-separated glob patterns of the report files, e.g. "reports/*.xml,other.xml"; quote them so that the shell does not expand them ${t}`).argParser(Dm),qe=new lt.Option("-o, --output-dir <folder>","the folder to save the converted reports to; it must be empty, not exist, or hold only the reports being converted"),go=(n=>(n.postman="postman",n.node="node",n.vitest="vitest",n.wdio="wdio",n))(go||{}),ze=t=>new lt.Option("--framework <framework>",`the test framework that wrote the reports ${t}`).choices(Object.values(go)),Qe=new lt.Option("--framework-version <version>","the version of the test framework that wrote the reports");function Dm(t){let e=t.split(",").map(o=>o.trim()),r=ca.sync(e);if(r.length===0)throw new lt.InvalidArgumentError("No files found with the provided patterns");return r}async function V(t){let e=new Map;return t.forEach(r=>{let o=Rt(r.testsuites?.testsuite),n=r.testsuites?.name??"No name";o.forEach((s,i)=>{let c=Je(s,o,i),m=Pm(s,n,c),d=et(n+c);m.results.tests.length!==0&&e.set(d,m)})}),e}function Pm(t,e,r){let o=lo(t.timestamp??""),n=t.time?Ve(t.time):0,s=new Date(je(t.timestamp??"")+n),i=Rt(t.testcase),c=[t["system-out"],t["system-err"],...i.flatMap(g=>[g["system-out"],g["system-err"]])].filter(g=>g).join(`
36
+ `),m=0,d=i.filter(g=>"failure"in g).length,f=i.filter(g=>"skipped"in g).length,u=i.length-d-f;return{groupId:e,spec:r,startTime:o,artifacts:ta(t),_stdout:c,results:{stats:{suites:1,tests:i.length,passes:u,pending:f,skipped:0,failures:d,flaky:0,wallClockStartedAt:o,wallClockEndedAt:s.toISOString(),wallClockDuration:n},tests:i?.map(g=>(i[0]?.time&&(m+=Ve(i[0].time)),sa(g,t,m,r)))}}}async function pa({inputFormat:t,framework:e,parsedXMLArray:r}){return t==="junit"?bm(e,r):new Map}async function bm(t,e){switch(t){case"node":return V(e);case"postman":return V(e);case"vitest":return V(e);case"wdio":return V(e);default:return E("Unsupported framework: %s",t),new Map}}var da=require("fs-extra"),ma=require("xml2js");async function ua(t){let e=await Promise.all(t.map(o=>(0,da.readFile)(o,"utf-8"))),r=(await Promise.all(e.map(Nm))).filter(Boolean);return e.length!==r.length&&E("Some files could not be parsed. Enable debug logging for more details"),r}async function Nm(t){let e=t.trim();if(!e)return null;try{return await(0,ma.parseStringPromise)(e,{explicitArray:!1,mergeAttrs:!0})||null}catch(r){return p("Error parsing XML input",r),null}}function la(t){return{framework:t.inputFormat,frameworkVersion:t.frameworkVersion??null,frameworkConfig:{originFramework:t.framework,originFrameworkVersion:t.frameworkVersion}}}async function fa(){try{let t=$e();if(!t)throw new Error("Config is missing!");t.outputDir&&await Lm(t.outputDir,t.inputFiles);let e=t.outputDir?await It(t.outputDir):await Ho(process.cwd(),".currents"),r=await It((0,L.join)(e,"instances")),o=la(t);p("Report config:",o),T("[currents] Convertion files: %s",t.inputFiles.join(", ")),await Vt((0,L.join)(e,"config.json"),JSON.stringify(o));let n=await ua(t.inputFiles);if(n.length===0)throw new Error("No valid XML JUnit report was found.");let s=aa(n);await Vt(Tt(e),JSON.stringify(s));let i=await pa({inputFormat:t.inputFormat,framework:t.framework,parsedXMLArray:n}),c=await It((0,L.join)(e,"artifacts")),m=process.cwd();return await Promise.all(Array.from(i.values()).map(async d=>{if(await He(d.artifacts,d.spec,c,m),d._stdout){let f=`${et(d.spec)}.stdout.txt`;await Vt((0,L.join)(c,f),d._stdout),d.artifacts||(d.artifacts=[]),d.artifacts.push({path:(0,L.join)("artifacts",f),type:"stdout",contentType:"text/plain",level:"spec"}),delete d._stdout}for(let f of d.results.tests){await He(f.artifacts,f.testId,c,m);for(let u of f.attempts)await He(u.artifacts,f.testId+u.attempt,c,m)}})),await Promise.all(Array.from(i.entries()).map(([d,f])=>Vt((0,L.join)(r,`${et(d)}.json`),JSON.stringify(f)))),T("[currents] Conversion completed, report saved to: %s",e),e}catch(t){throw p("Failed to convert: %o",t),t}}async function Lm(t,e){let r=(0,L.resolve)(t),o=new Set(e.map(c=>(0,L.resolve)(c))),n=[(0,L.join)(r,"config.json"),Tt(r),(0,L.join)(r,"instances"),(0,L.join)(r,"artifacts")],s=[...o].find(c=>n.some(m=>c===m||c.startsWith(m+L.sep)));if(s)throw new Error(`The report "${s}" is where the conversion writes its own files. Move the reports out of "${t}", or leave out --output-dir to convert into a new folder in .currents.`);if(await ho.default.pathExists(r)?await ga(r,o):void 0)throw new Error(`The folder "${t}" is not empty. Reports already in it would be uploaded with the converted ones. Remove the folder, or leave out --output-dir to convert into a new folder in .currents.`)}async function ga(t,e){for(let r of await ho.default.readdir(t,{withFileTypes:!0})){let o=(0,L.join)(t,r.name),n=r.isDirectory()?await ga(o,e):e.has(o)?void 0:o;if(n)return n}}var Bm=p.extend("cli");async function Eo(t){return Qi(Xi(t)),Bm("Config: %o",$e()),fa()}async function ha(t){await w(async e=>{await Eo(e)},t)}var Io="convert",vm=t=>[{comment:"Convert JUnit test reports to the Currents format, to check the result before an upload",commands:[`${t} ${Io} --input-format junit --input-file "./*.xml" --framework postman`]}],Ia=t=>new Ea.Command().name(Io).command(Io).showHelpAfterError("(add --help for additional information)").allowUnknownOption().summary("Convert JUnit XML reports to the Currents format").description("Convert JUnit XML reports to the Currents format, without uploading them. The converted reports are saved to --output-dir or a new folder in .currents").addHelpText("after",y(vm(t))).addOption(P()).addOption(Ye("(required)")).addOption(We("(required)")).addOption(qe).addOption(ze("(required)")).addOption(Qe).action(r=>ha(r));var Do=require("@commander-js/extra-typings");var{apiKey:Mm,recordKey:Fm,projectId:km,ciBuildId:Gm,machineId:$m,debug:Km}=_,F={apiKey:Mm,recordKey:Fm,projectId:km,ciBuildId:Gm,machineId:$m,sessionId:{name:"Session ID",env:"CURRENTS_SESSION_ID",cli:"--session-id"},title:{name:"Title",cli:"--title"},debug:Km};var Xe=p.extend("config");function Ca(t){let e=U(F,["apiKey","projectId","title"],t);return Xe("Resolved config: %o",h(e)),e}function Ta(t){let e=U(F,["apiKey"],t);return Xe("Resolved config: %o",h(e)),e}function ya(t){let e=U(F,["apiKey"],t);return Xe("Resolved config: %o",h(e)),e}function Ra(t){let e=U(F,["projectId"],t,Hm);return Xe("Resolved config: %o",h(e)),e}function Hm(t){if(!(t.recordKey||t.apiKey))throw new W(`${F.recordKey.name} or ${F.apiKey.name} is required. Set ${F.recordKey.env} or ${F.apiKey.env}, or pass ${F.recordKey.cli} or ${F.apiKey.cli}`)}var Mt=l(require("fs-extra")),tr=l(require("path"));var wa=l(require("path"));var _a=["trace","screenshot","video","attachment"];var jm=["image/png","image/jpeg","image/webp","image/gif"],Oa=t=>wa.default.extname(t).toLowerCase()===".zip";function xa(t){return _a.includes(t)}function Co(t){return Oa(t)?"application/zip":Yr(t)?.contentType??"application/octet-stream"}function Vm(t){return Oa(t)?"trace":Yr(t)?.type??"attachment"}function To(t,e){let r=Vm(t);return e.includes(r)?r:"attachment"}function Aa(t,e,r){if(!r.includes(e))throw new Error(`Cannot attach "${t}" as type "${e}" here. The target takes: ${r.join(", ")}`)}function Sa(t,e){let r=Co(t);if(!(e==="attachment"||e==="trace"&&r==="application/zip"||e==="screenshot"&&jm.includes(r)||e==="video"&&r.startsWith("video/")))throw new Error(`Cannot attach "${t}" as type "${e}": its content type is ${r}`)}var Ua=l(require("archiver")),_t=l(require("fs-extra")),Ze=l(require("path")),Da=l(require("unzipper")),Pa=require("tmp-promise");async function ba(t){try{return(await Da.default.Open.file(t)).files.some(r=>r.path==="trace.trace")}catch{return!1}}var Na=/^trace-.*\.trace$/,Jm=/^trace-.*\.network$/;async function yo(t){return(await _t.default.readdir(t)).some(r=>Na.test(r))}function Ym(t){if(!t)return!1;try{let e=JSON.parse(t),r=e.snapshot?.response;if(e.type!=="resource-snapshot"||!r)return!0;let o=r.status>=200&&r.status<400,n=/javascript|ecmascript/i.test(r.content?.mimeType??"");return!(o&&n)}catch{return!0}}async function La(t,e){return(await _t.default.readdir(t)).filter(o=>e.test(o)).sort().map(o=>Ze.default.join(t,o))}async function Wm(t){return(await Promise.all((await La(t,Na)).map(r=>_t.default.readFile(r,"utf8")))).map(r=>r.endsWith(`
37
+ `)?r:r+`
38
+ `).join("")}async function qm(t){let e=await La(t,Jm),r=[];for(let o of e)r.push(...(await _t.default.readFile(o,"utf8")).split(`
39
+ `));return r.filter(Ym).join(`
40
+ `)}async function Ba(t){let{path:e,cleanup:r}=await(0,Pa.dir)({unsafeCleanup:!0}),o=Ze.default.join(e,"trace.zip");try{let n=(0,Ua.default)("zip",{zlib:{level:9}}),s=_t.default.createWriteStream(o),i=new Promise((c,m)=>{s.on("close",()=>c()),s.on("error",m),n.on("error",m)});n.pipe(s),n.append(await Wm(t),{name:"trace.trace"}),n.append(await qm(t),{name:"trace.network"});for(let c of["screencast","resources"]){let m=Ze.default.join(t,c);await _t.default.pathExists(m)&&n.directory(m,c)}await n.finalize(),await i}catch(n){throw await r(),n}return{zipPath:o,cleanup:r}}var zm=1024**3,va=/^\.env($|[._-])|^\.envrc$|\.env$/i,Qm=/\.(pem|key)$|^id_(rsa|ed25519|ecdsa|dsa)/i;function Xm(t){if(va.test(t))throw new Error(`"${t}" looks like an environment file with secrets and is not attached`)}async function Ro(t,e,r){Xm(e);let o=r.type??To(e,r.allowedTypes);r.type?(Sa(e,r.type),Aa(e,r.type,r.allowedTypes)):o==="trace"&&!await ba(t)&&(o="attachment");let n=await Mt.default.stat(t);if(n.size>zm)throw new Error(`"${e}" is larger than 1 GiB`);if(n.size===0)throw new Error(`"${e}" is empty`);return{path:t,name:e,type:o,contentType:Co(e),sizeBytes:n.size}}async function Zm(t,e,r){let o=[];for(let n of await Mt.default.readdir(t,{withFileTypes:!0})){let s=tr.default.join(t,n.name);if(n.name.startsWith("."))E(`Skipping the hidden file "${s}"`);else if(Qm.test(n.name)||va.test(n.name))E(`Skipping "${s}", which looks like a key or secrets file`);else if(n.isSymbolicLink())E(`Skipping the link "${s}"`);else if(n.isDirectory()){if(s===r)continue;E(`Skipping the folder "${s}"`)}else if(n.isFile()){if((await Mt.default.stat(s)).size===0){E(`Skipping the empty file "${s}"`);continue}o.push(await Ro(s,n.name,e))}}return o}async function Ma(t,e){let r=[],o=[],n=async()=>{await Promise.all(o.map(i=>i()))},s=async i=>{let c=await Ba(i);o.push(c.cleanup),r.push(await Ro(c.zipPath,`trace-${Cr(8)}.zip`,{...e,type:e.type??To("trace.zip",e.allowedTypes)}))};try{for(let i of t){let c=await Mt.default.stat(i).catch(()=>null);if(!c)throw new Error(`"${i}" does not exist`);if(!c.isDirectory()){r.push(await Ro(i,tr.default.basename(i),e));continue}if(await yo(i)){await s(i);continue}let m=tr.default.join(i,"traces"),d;await Mt.default.pathExists(m)&&await yo(m)&&(await s(m),d=m),r.push(...await Zm(i,e,d))}}catch(i){throw await n(),i}if(r.length===0)throw new Error("There are no files to attach");return{files:r,cleanup:n}}var Fa={run:["attachment"],instance:["attachment","video","screenshot"],test:["attachment"],attempt:["attachment","video","screenshot","trace"]},ka=["attachment","video","screenshot","trace"];function Ga(t){return t.testId||t.testTitle?t.attempt===void 0?"test":"attempt":t.instanceId||t.spec?"instance":"run"}var $a=4;async function Ka(t){let e=[];for(let r=0;r<t.length;r+=$a)e.push(...await Promise.all(t.slice(r,r+$a).map(async({file:o,uploadUrl:n,uploadHeaders:s})=>{try{return await ms({name:o.name,path:o.path,sizeBytes:o.sizeBytes,uploadUrl:n,contentType:o.contentType,headers:s}),{file:o}}catch(i){return{file:o,error:i}}})));return e}var tu=p.extend("files");function eu(t=[]){let e=new Map;for(let r of t){let o=r.indexOf("=");if(o<1)throw new Error(`--meta expects key=value, got "${r}"`);let n=r.slice(0,o);if(!/^[A-Za-z0-9_-]{1,64}$/.test(n))throw new Error(`--meta key "${n}" can only hold up to 64 letters, digits, "_" and "-"`);let s=r.slice(o+1);if(s.length>256)throw new Error(`--meta value of "${n}" is longer than 256 characters`);e.set(n,s)}return e.size>0?Object.fromEntries(e):void 0}function ru(t){if(t!==void 0){if(!xa(t))throw new Error(`--type must be one of trace, screenshot, video, attachment, got "${t}"`);return t}}var ou=50,nu=100*1024**2,Ha=200;function su(t,e={count:ou,bytes:nu}){let r=[],o=0;for(let n of t){let s=r[r.length-1];!s||s.length>=e.count||o+n.sizeBytes>e.bytes?(r.push([n]),o=n.sizeBytes):(s.push(n),o+=n.sizeBytes)}return r}async function _o(t){if(!t.credentials.apiKey&&!t.credentials.recordKey)throw new Error("Pass an API key or a record key");let e=ru(t.type),r=eu(t.meta),o=t.target??{},n="sessionId"in t.owner?ka:Fa[Ga(o)],{files:s,cleanup:i}=await Ma(t.paths,{type:e,allowedTypes:n});s.length>Ha&&E(`Attaching ${s.length} files. An instance takes up to ${Ha} files through the API, so the rest may be refused`);let c=[],m=[];try{for(let d of su(s)){let f=d.map(g=>({name:g.name,type:g.type,contentType:g.contentType,sizeBytes:g.sizeBytes,caption:t.caption,meta:r})),u;try{u=await On(t.credentials,t.owner,o,f)}catch(g){throw new Error(`${g.message}
41
+ ${c.length} of ${s.length} files were attached before this`)}if(tu("Created %d attachments at level %s",u.attachments.length,u.level??"session"),u.attachments.length!==d.length)throw new Error(`The API returned ${u.attachments.length} upload URLs for ${d.length} files`);let I=await Ka(d.map((g,S)=>{if(u.attachments[S].name!==g.name)throw new Error(`The API answered "${u.attachments[S].name}" where "${g.name}" was declared`);let{uploadUrl:J,uploadHeaders:Ot}=u.attachments[S];return{file:g,uploadUrl:J,uploadHeaders:Ot}}));for(let g of I)g.error?(C("Failed %s: %s",g.file.name,g.error.message),m.push(g)):(T("Attached %s (%s)",g.file.name,g.file.type),c.push(g.file))}}finally{await i().catch(d=>E("Could not remove temporary files: %s",d.message))}if(m.length>0)throw new Error(`${m.length} of ${s.length} files could not be uploaded`);return{files:c.map(({name:d,type:f,sizeBytes:u})=>({name:d,type:f,sizeBytes:u}))}}var wt=l(require("fs-extra")),re=l(require("path")),iu=".currents-session",ja=()=>re.default.join(process.cwd(),iu,"session.json");async function au(t){let e=re.default.join(t,".gitignore");await wt.default.pathExists(e)||await wt.default.writeFile(e,`*
42
+ `)}async function Va(t){let e=ja();await wt.default.ensureDir(re.default.dirname(e)),await au(re.default.dirname(e)),await wt.default.writeJson(e,t,{spaces:2})}async function cu(){let t=ja();if(!await wt.default.pathExists(t))return null;let e=await wt.default.readJson(t),r=e?.sessionId||e?.runId;if(typeof r!="string"||!r.trim())return null;let o=typeof e.projectId=="string"?e.projectId:void 0;return{sessionId:r,projectId:o}}async function wo(t){if(t)return t;let e=await cu();if(!e)throw new Error('No session found. Run "currents session start" first, or pass --session-id');return e.sessionId}var pu=p.extend("session");async function du(){try{let{sha:t,branch:e,message:r,authorName:o,authorEmail:n,remoteOrigin:s}=await Oe();return{sha:t,branch:e,message:r,authorName:o,authorEmail:n,remoteOrigin:s}}catch(t){pu("No git info: %o",t);return}}function mu(t){if(t)return/^\d+$/.test(t)?{id:t}:{link:t}}function Ja(){let{provider:t,params:e}=rt();return{provider:t,params:e}}function uu(){if(rt().ciBuildId.source!=="server")throw new Error("The CI build ID is unknown. Pass --ci-build-id or set CURRENTS_CI_BUILD_ID to the value the run was recorded with")}async function Ya(t){let e=await wn(t.apiKey,{projectId:t.projectId,title:t.title,status:t.status,error:t.error,tags:t.tag,commit:await du(),ci:Ja(),pr:mu(t.pr)});return await Va({sessionId:e.sessionId,projectId:t.projectId}),t.json?process.stdout.write(JSON.stringify({sessionId:e.sessionId})+`
43
+ `):T("Session started: %s",e.sessionId),e}async function Wa(t,e){let r=await wo(t.sessionId);return _o({credentials:{apiKey:t.apiKey},owner:{sessionId:r},paths:e,type:t.type,caption:t.caption,meta:t.meta})}async function qa(t){let e=await wo(t.sessionId),r=await xn(t.apiKey,{sessionId:e,purpose:"report",expiresInDays:t.expiresInDays});return T(r.pageUrl),T("Markdown: %s",r.url),r}async function za(t,e){if(t.testTitle&&!t.spec)throw new Error("--test-title needs --spec, the spec file of the test");if(t.attempt!==void 0&&!t.testTitle)throw new Error("--attempt needs --test-title");if(t.group&&!t.spec)throw new Error("--group needs --spec: it picks the spec file of a group");return t.ciBuildId||uu(),_o({credentials:{apiKey:t.apiKey,recordKey:t.recordKey},owner:t.ciBuildId?{projectId:t.projectId,ciBuildId:t.ciBuildId}:{projectId:t.projectId,ci:Ja()},target:{spec:t.spec,testTitle:t.testTitle,groupId:t.group,attempt:t.attempt,machineId:t.spec?void 0:t.machineId},paths:e,type:t.type,caption:t.caption,meta:t.meta})}var A=require("@commander-js/extra-typings");var Qa=t=>N(F,t),er="(required; needs write access)",Xa=Nt(". Leave it out only if the run was recorded without one, on a CI the reporters recognize"),Za=new A.Option("--machine-id <id>","the CI machine the files come from; run-level files are listed by machine when it is set").env(Qa("machineId")),xo=new A.Option("--session-id <id>",'the session to use instead of the one saved by "session start"').env(Qa("sessionId")),tc=new A.Option("--title <text>","what the session shows, used as the session title (required)"),ec=new A.Option("--status <status>","the result of the session").choices(["passed","failed"]).default("passed"),rc=new A.Option("--error <text>","what went wrong, for a failed session"),oc=Lt("tags to add to the session"),nc=new A.Option("--pr <url|number>","the pull request the session is about; by default taken from the CI environment"),sc=new A.Option("--json",'print the session ID as JSON on stdout, e.g. {"sessionId": "..."}'),ic=new A.Option("--spec <spec>","attach to this spec file of the run"),ac=new A.Option("--test-title <title>",'attach to this test of --spec: the full title joined with " > ", or its last part'),cc=new A.Option("--group <id>","the group of the spec file; a spec that runs once per Playwright project matches more than once without it"),pc=new A.Option("--attempt <n>","attach to this attempt of the test; the first attempt is 0").argParser(t=>{let e=Number(t);if(!Number.isInteger(e)||e<0)throw new Error("--attempt must be a whole number from 0");return e}),dc=["trace","screenshot","video","attachment"],mc="by default taken from the file: a .zip holding trace.trace is a trace; .png, .jpg, .jpeg, .webp and .gif are screenshots; .webm and .mp4 are videos; anything else is an attachment",uc=new A.Option("--type <type>",`the type of every file; ${mc}`).choices(dc),lc=new A.Option("--type <type>",`the type of every file; ${mc}. The whole run and a test take attachments only, a spec file also takes screenshots and videos, and an attempt (--attempt) takes all four types, including traces. A file of a type its target does not take is attached as an attachment, and a --type the target does not take is an error`).choices(dc),rr="files or folders to attach. A folder adds the files directly in it; hidden files, links, subfolders and empty files in it are skipped. A folder of Playwright MCP trace-*.trace files is packed into one trace and nothing else in it is attached; a folder with such a traces/ subfolder adds the packed trace and its own files. Files named .env or .env.* are refused, and each file can be at most 1 GiB",or=new A.Option("--caption <text>","a short description shown with each file"),lu=(t,e=[])=>[...e,t],nr=new A.Option("--meta <key=value>","a label for each file; repeat for more").argParser(lu),Oo=["1","3","7"],fc=new A.Option("--expires-in-days <days>","the number of days the link works").choices(Oo).default(7).argParser(t=>{if(!Oo.includes(t))throw new A.InvalidArgumentError(`Allowed choices are ${Oo.join(", ")}.`);return Number(t)});var xc=require("@commander-js/extra-typings");var Ft=require("@commander-js/extra-typings");var gc=new Ft.Option("--ci-build-id <id>","the CI build ID to record the run with; by default taken from the CI environment, or a random value").env(N(nt,"ciBuildId")),hc=Lt("tags to add to the run").env(N(nt,"tag")),Ec=new Ft.Option("--remove-title-tags","remove tags from test names in Currents, e.g. `Test name @smoke` becomes `Test name` in the dashboard").env(N(nt,"removeTitleTags")).default(!1),Ic=new Ft.Option("--disable-title-tags","do not read tags from test names, e.g. `Test name @smoke` is not tagged with `smoke` in the dashboard").env(N(nt,"disableTitleTags")).default(!1),Cc=new Ft.Option("--machine-id <id>","the ID of the machine that ran the tests; by default a random value").env(N(nt,"machineId")),Tc=new Ft.Option("--report-dir <folder>","the folder of the reports to upload; by default the newest folder in .currents").env(N(nt,"reportDir"));var So=require("path");var _c=l(require("fs"));var yc=require("tmp-promise"),Rc=async()=>{let{path:t}=await(0,yc.file)();return t};var Ao=p.extend("cli"),sr=class{constructor(e){this.configFilePath=null;this.cliOptions=e,Ao("CLI options: %o",h(this.cliOptions)),this.parsedConfig=vs(this.cliOptions),Ao("Parsed config from CLI options: %o",h(this.parsedConfig))}async getConfigFilePath(){if(this.configFilePath)return this.configFilePath;let e=await Rc();return _c.default.writeFileSync(e,JSON.stringify(this.parsedConfig)),Ao("CLI options temp file path: %s",e),this.configFilePath=e,e}};async function wc(t){await w(async e=>{let r=e.inputFormat?await fu(e):e.reportDir,o=new sr({...e,reportDir:r});Bs(o.parsedConfig);let n=xe();T("Currents config: %o",h(n)),await to()},t)}async function fu({inputFormat:t,inputFile:e,framework:r,frameworkVersion:o,outputDir:n,reportDir:s,debug:i}){if(n&&s&&(0,So.resolve)(n)!==(0,So.resolve)(s))throw new Error("--output-dir and --report-dir name different folders. With --input-format, the converted reports are saved to one folder and uploaded from it: pass one of the two options.");return Eo({inputFormat:t,inputFile:e,framework:r,frameworkVersion:o,outputDir:n??s,debug:i})}var kt="upload",Oc="(required with --input-format)",ir="run",Gt=t=>[{comment:"Upload test results to Currents",commands:[`${t} ${ir} ${kt} --key <record-key> --project-id <id> --ci-build-id <build-id>`]},{comment:"Convert JUnit XML reports to the Currents format, then upload them",commands:[`${t} ${ir} ${kt} --key <record-key> --project-id <id> --ci-build-id <build-id> --input-format junit --input-file "./*.xml" --framework postman`]},{comment:'Upload test results and add the tags "tagA" and "tagB" to the run',commands:[`${t} ${ir} ${kt} --key <record-key> --project-id <id> --ci-build-id <build-id> --tag tagA --tag tagB`]},{comment:"Upload test results from another folder",commands:[`${t} ${ir} ${kt} --key <record-key> --project-id <id> --ci-build-id <build-id> --report-dir <report-dir>`]}],ar=t=>new xc.Command().name(kt).command(kt).showHelpAfterError("(add --help for additional information)").allowUnknownOption().summary("Upload test results of Currents reporters or JUnit").description(`Upload test results created by Currents reporters to https://currents.dev
44
+
45
+ With --input-format, first convert the reports in --input-file to the Currents
46
+ format, then upload the converted reports. They are saved to --output-dir, or
47
+ --report-dir, or a new folder in .currents. A folder you name may hold only the
48
+ reports being converted.`).addHelpText("after",y(Gt(t))).addOption(gc).addOption(at()).addOption(Z()).addOption(hc).addOption(Ec).addOption(Ic).addOption(Cc).addOption(P()).addOption(Tc).addOption(Ye()).addOption(We(Oc)).addOption(ze(Oc)).addOption(Qe).addOption(qe).action(r=>wc(r));var Uo="run",cr=t=>[{comment:"Attach the Docker logs of a CI machine to the run, after the tests finished",commands:[`${t} ${Uo} attach --key <record-key> --project-id <id> --ci-build-id <build-id> --machine-id shard-1 docker-logs.zip`]},{comment:"Attach a screenshot to the first attempt of a test",commands:[`${t} ${Uo} attach --key <record-key> --project-id <id> --ci-build-id <build-id> --spec tests/cart.spec.ts --test-title "adds an item" --attempt 0 screenshot.png`]}],gu=t=>new Do.Command().name("attach").addHelpText("after",y(cr(t))).description("Upload files to a run recorded in CI").argument("<paths...>",rr).addOption(at("(required unless --api-key is set)")).addOption(ct("(used when --key is not set; needs write access)")).addOption(Z()).addOption(Xa).addOption(Za).addOption(ic).addOption(cc).addOption(ac).addOption(pc).addOption(lc).addOption(or).addOption(nr).addOption(P()).action(async(e,r)=>{await w(async({key:o,...n})=>{await za(Ra({...n,recordKey:o}),e)},r)}),Ac=t=>new Do.Command().name(Uo).summary("Upload test results, attach files, get or cancel a run").description("Upload test results to a run, attach files to it, get its data or cancel it").addHelpText("after",y([...Gt(t).slice(0,2),cr(t)[0],so(t)[0],te(t)[0]])).showHelpAfterError("(add --help for additional information)").addCommand(ar(t)).addCommand(gu(t)).addCommand(io(t)).addCommand(Ge(t));var oe=require("@commander-js/extra-typings");var pr="session",$t=t=>{let e=`${t} ${pr} start --api-key <api-key> --project-id <id> --title "Checkout fails on empty cart" --status failed`,r=`${t} ${pr} attach before.png .playwright-mcp/traces`,o=`${t} ${pr} share --expires-in-days 7`;return{session:[{comment:"Start a session, attach what you captured and get a link to share",commands:[e,r,o]}],start:[{comment:"Start a session for a failed check",commands:[e]}],attach:[{comment:"Attach a screenshot and a Playwright MCP trace folder",commands:[r]}],share:[{comment:"Print a link that expires in 7 days",commands:[o]}]}},hu=t=>new oe.Command().name("start").addHelpText("after",y($t(t).start)).summary("Create a session").description('Create a session and save its ID to .currents-session/session.json in the current folder, where "attach" and "share" read it').addOption(ct(er)).addOption(Z()).addOption(tc).addOption(ec).addOption(rc).addOption(oc).addOption(nc).addOption(sc).addOption(P()).action(async e=>{await w(async r=>{r.json&&Pt(),await Ya(Ca(r))},e)}),Eu=t=>new oe.Command().name("attach").summary("Upload screenshots, traces and other files").addHelpText("after",y($t(t).attach)).description("Upload files, folders or a Playwright MCP trace folder to the session").argument("<paths...>",rr).addOption(ct(er)).addOption(xo).addOption(uc).addOption(or).addOption(nr).addOption(P()).action(async(e,r)=>{await w(async o=>{await Wa(Ta(o),e)},r)}),Iu=t=>new oe.Command().name("share").addHelpText("after",y($t(t).share)).summary("Print a public link to the session page").description('Create a public link to the session page and print it. The second line, "Markdown: <url>", is the address of the same content as Markdown, for agents').addOption(ct(er)).addOption(xo).addOption(fc).addOption(P()).action(async e=>{await w(async r=>{await qa(ya(r))},e)}),Sc=t=>new oe.Command().name(pr).summary("Capture agent or browser sessions as evidence").description("Capture ad-hoc, one-off agent or browser sessions as evidence: a bug before and after a fix, or proof that something works. Create a session, attach screenshots, traces, videos and other files to it, and print a link to share it.").addHelpText("after",y($t(t).session)).showHelpAfterError("(add --help for additional information)").addCommand(hu(t)).addCommand(Eu(t)).addCommand(Iu(t));var Ht=require("@commander-js/extra-typings");var tt=l(require("fs-extra")),G=l(require("path")),pt="currents-cli",Kt=G.default.join(".agents","skills");function Uc(t=__dirname){let e=t;for(;;){let r=G.default.join(e,"skills",pt);if(tt.default.existsSync(G.default.join(r,"SKILL.md")))return r;let o=G.default.dirname(e);if(o===e)throw new Error(`The ${pt} skill is missing from this package`);e=o}}async function Po(t,e=""){let r=[];for(let o of await tt.default.readdir(G.default.join(t,e),{withFileTypes:!0})){let n=G.default.join(e,o.name);o.isDirectory()?r.push(...await Po(t,n)):r.push(n)}return r.sort()}async function Cu(t,e){let[r,o]=await Promise.all([Po(t),Po(e)]);if(r.join(`
49
+ `)!==o.join(`
50
+ `))return!1;for(let n of r){let[s,i]=await Promise.all([tt.default.readFile(G.default.join(t,n)),tt.default.readFile(G.default.join(e,n))]);if(!s.equals(i))return!1}return!0}async function Dc(){let t=await tt.default.readFile(G.default.join(Uc(),"SKILL.md"),"utf8");await new Promise((e,r)=>process.stdout.write(t,o=>o?r(o):e()))}async function Pc({dir:t=Kt,force:e=!1}){let r=Uc(),o=G.default.resolve(t,pt),n=G.default.relative(process.cwd(),o)||".";if(await tt.default.pathExists(o)){if(!(await tt.default.stat(o)).isDirectory())throw new Error(`${n} exists and is not a folder`);if(await Cu(r,o))return T("The %s skill is already in %s",pt,n),o;if(!e)throw new Error(`${n} exists and differs from the skill of this version. Pass --force to replace it`);await tt.default.remove(o)}return await tt.default.copy(r,o),T("Wrote the %s skill to %s",pt,n),o}var dr="skill",Tu=t=>[{comment:"Print the skill",commands:[`${t} ${dr}`]},{comment:`Add the skill to the project, in ${Kt}/${pt}`,commands:[`${t} ${dr} --install`]},{comment:"Add the skill for Claude Code",commands:[`${t} ${dr} --install --dir .claude/skills`]}],bc=t=>new Ht.Command().name(dr).summary("Print or install the agent skill for this CLI").description(`Print SKILL.md of the ${pt} skill, which tells coding agents how to use this CLI, or install the skill in the project. Install it to get the reference files too.
51
+
52
+ Agents read project skills from these folders:
53
+ Codex, Cursor ${Kt}
54
+ Claude Code .claude/skills`).addHelpText("after",y(Tu(t))).addOption(new Ht.Option("--install",`write the skill folder to <dir>/${pt}`)).addOption(new Ht.Option("--dir <path>","the skills folder to install to").default(Kt)).addOption(new Ht.Option("--force","replace an installed copy of the skill that differs from this version")).action(async e=>{await w(async r=>{if(!r.install&&(r.force||r.dir!==Kt))throw new Error("--dir and --force work with --install only");r.install?await Pc({dir:r.dir,force:r.force}):await Dc()},e)});var O="currents",Lc=()=>{let t=ar(O),e=new Nc.Command(O).version(xt).description("Currents CLI: upload test results and files to Currents, get and cancel runs, capture agent or browser sessions as evidence, and cache files between CI jobs").showHelpAfterError(`(run '${O} --help' for usage)`).enablePositionalOptions().hook("preAction",(i,c)=>{Dn(c),Pn(c)}).addCommand(t,{hidden:!0}).addCommand(Ia(O),{hidden:!0}).addCommand(Ge(O,{deprecated:!0}),{hidden:!0}).commandsGroup("Test runs:").addCommand(Ac(O)).commandsGroup("Evidence:").addCommand(Sc(O)).commandsGroup("CI utilities:").addCommand(ji(O)).commandsGroup("Other:").addCommand($i(O)).addCommand(bc(O)).helpCommand(!0).addHelpText("after",`${y([Gt(O)[0],Gt(O)[1],Me(O)[1],Fe(O)[1],te(O)[0],cr(O)[0],...$t(O).session])}
55
+ Run '${O} <command> --help' for the options and examples of a command.
56
+
57
+ Agent skill: ${O} skill --install
58
+ Documentation: https://docs.currents.dev
59
+ 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 yu(){Lc().parse()}yu();
93
62
  /*! For license information please see index.js.LEGAL.txt */
94
63
  //# sourceMappingURL=index.js.map