37audits-cli 1.0.0 → 1.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -94,7 +94,7 @@ GitHub Actions:
94
94
  env:
95
95
  THIRTYSEVENAUDITS_API_KEY: ${{ secrets.THIRTYSEVENAUDITS_API_KEY }}
96
96
  run: |
97
- npx -y 37audits-cli@1.0.0 mw start \
97
+ npx -y 37audits-cli@1.0.2 mw start \
98
98
  --project "${{ secrets.THIRTYSEVENAUDITS_PROJECT_ID }}" \
99
99
  --run-auditors --wait --ends-in 30m \
100
100
  --reason "Deploy of my-app at ${GITHUB_REF_NAME}@${GITHUB_SHA::7}"
@@ -106,7 +106,7 @@ GitHub Actions:
106
106
  continue-on-error: true
107
107
  env:
108
108
  THIRTYSEVENAUDITS_API_KEY: ${{ secrets.THIRTYSEVENAUDITS_API_KEY }}
109
- run: npx -y 37audits-cli@1.0.0 mw end "${{ steps.maintenance.outputs.window_id }}" --project "${{ secrets.THIRTYSEVENAUDITS_PROJECT_ID }}"
109
+ run: npx -y 37audits-cli@1.0.2 mw end "${{ steps.maintenance.outputs.window_id }}" --project "${{ secrets.THIRTYSEVENAUDITS_PROJECT_ID }}"
110
110
  ```
111
111
 
112
112
  `mw start` writes `window_id` (and `audit run` writes `group_id`) to
package/dist/cli.cjs CHANGED
@@ -41,7 +41,7 @@ Expecting one of '${r.join("', '")}'`);let i=`${t}Help`;return this.on(i,o=>{let
41
41
  </style>
42
42
  </head>
43
43
  <body><main><h1>${n}</h1><p>${t}</p></main></body>
44
- </html>`}function an(n){return new Promise((t,e)=>{let r=(0,Ge.createServer)();r.once("error",e),r.listen(n,"127.0.0.1",()=>{r.off("error",e),t(r)})})}async function We(n=Pe){let t,e=0;for(let l of n)try{t=await an(l),e=l;break}catch(c){if(c.code!=="EADDRINUSE")throw new y(`Could not start the login callback server on 127.0.0.1:${l}: ${c.message}`,"oauth_error")}if(!t)throw new y(`Ports ${n.join(", ")} on 127.0.0.1 are all in use. Free one of them and run \`37audits login\` again.`,"oauth_port_unavailable");let r=t,i,o,s=new Promise((l,c)=>{i=l,o=c});s.catch(()=>{});let a=setTimeout(()=>{r.close(),o(new y("Timed out after 5 minutes waiting for the browser. Run `37audits login` again.","oauth_timeout"))},nn);return r.on("request",(l,c)=>{let u=new URL(l.url??"/","http://127.0.0.1");if(u.pathname!==Xt){c.writeHead(404,{Connection:"close"}),c.end();return}let d=u.searchParams.get("code"),m=u.searchParams.get("state"),p=u.searchParams.get("error"),f=u.searchParams.get("error_description"),_=p?`Authorization ${p==="access_denied"?"denied":`failed: ${p}`}${f?` (${f})`:""}`:!d||!m?"The callback is missing the code or state parameter":null;c.writeHead(200,{"Content-Type":"text/html; charset=utf-8",Connection:"close"}),c.end(_?Ve("Sign-in failed",`${_}. Return to your terminal and try again.`):Ve("Signed in to 37 Audits","You can close this tab and return to your terminal."),()=>l.socket.destroy()),clearTimeout(a),r.close(),_?o(new y(_,"oauth_error")):d&&m&&i({code:d,state:m})}),{port:e,redirectUri:Le(e),waitForCallback:s,close(){clearTimeout(a),r.close()}}}async function qe(n,t,e){let r;try{r=await fetch(`${n}/oauth/token`,{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded",Accept:"application/json"},body:t,signal:AbortSignal.timeout(en)})}catch(i){let o=i instanceof Error&&i.name==="TimeoutError";throw new y(o?`${e} timed out after 30s. Check your connection and try again.`:`Could not reach the authorization server at ${n}. Check your connection and try again.`,"network_error")}if(!r.ok){let i="";try{let o=await r.json();i=String(o.error_description??o.msg??o.error_code??o.error??"")}catch{}throw new y(`${e} failed (HTTP ${r.status})${i?`: ${i}`:""}`,"oauth_error")}return sn(await r.json())}function Be(n){return qe(n.authUrl,new URLSearchParams({grant_type:"authorization_code",client_id:n.clientId,code:n.code,redirect_uri:n.redirectUri,code_verifier:n.codeVerifier}),"Token exchange")}function un(n){return qe(n.authUrl,new URLSearchParams({grant_type:"refresh_token",client_id:n.clientId,refresh_token:n.refreshToken}),"Token refresh")}function Zt(n,t){return{type:"oauth",auth_url:t.authUrl,client_id:t.clientId,access_token:n.access_token,access_token_expires_at:on(n.access_token),refresh_token:n.refresh_token}}function Me(n,t){return n.access_token_expires_at>t+rn}function pt(n,t={}){return rt(dt(),async()=>{let e=n;try{let s=mt()?.credential;s?.type==="oauth"&&(e=s)}catch{}let r=Math.floor(Date.now()/1e3);if(!t.force&&Me(e,r)||t.force&&e.access_token!==n.access_token&&Me(e,r))return e;let i;try{i=await un({authUrl:e.auth_url,clientId:e.client_id,refreshToken:e.refresh_token})}catch(s){throw s instanceof y&&s.code==="network_error"?s:new y(`Your session has expired. ${Qt}`,"auth_error")}let o=Zt(i,{authUrl:e.auth_url,clientId:e.client_id});return Yt({version:1,credential:o}),o})}async function Ke(n,t={}){let e=n?.trim();if(e)return{type:"api_key",key:e,source:"flag"};let r=process.env[O.apiKey]?.trim();if(r)return{type:"api_key",key:r,source:"env"};let i=mt();return i?i.credential.type==="api_key"?{type:"api_key",key:i.credential.api_key,source:"config"}:{type:"oauth",credential:t.refresh===!1?i.credential:await pt(i.credential),source:"config"}:null}function ze(n){return n.type==="api_key"?{"x-api-key":n.key}:{Authorization:`Bearer ${n.credential.access_token}`}}var ht=B(K(),1);function H(n,t){return n instanceof Error?n.message:t}function te(n){return n?!0:!process.stdout.isTTY}function Ye(n,t={}){typeof n=="string"&&!te(t.json)?console.log(n):console.log(JSON.stringify(n,null,2)),t.exitCode!==void 0&&process.exit(t.exitCode)}function A(n,t={}){let e=t.exitCode??1;if(te(t.json)){let r={message:n.message,code:n.code??"unknown"};typeof n.statusCode=="number"&&(r.statusCode=n.statusCode),console.error(JSON.stringify({error:r},null,2))}else console.error(`${ht.default.red("Error:")} ${n.message}`),typeof n.statusCode=="number"&&console.error(ht.default.dim(`[HTTP ${n.statusCode}]`));process.exit(e)}function D(n,t={}){te(t.json)?console.error(JSON.stringify({warning:{message:n}})):console.error(`${ht.default.yellow("Warning:")} ${n}`)}var ee={name:"37audits-cli",version:"1.0.0",description:"37 Audits CLI \u2014 run audits, read results and wrap deploys in maintenance windows from CI/CD",license:"MIT",type:"module",bin:{"37audits":"./dist/cli.cjs"},files:["dist/cli.cjs"],engines:{node:">=22"},repository:{type:"git",url:"git+https://github.com/37audits/37audits-cli.git"},homepage:"https://github.com/37audits/37audits-cli#readme",bugs:{url:"https://github.com/37audits/37audits-cli/issues"},keywords:["37audits","cli","audit","ci","maintenance-window"],scripts:{dev:"tsx src/cli.ts",build:"node scripts/build.mjs",lint:"biome check .","lint:fix":"biome check --write .",typecheck:"tsc --noEmit",test:"vitest run","test:e2e":"vitest run --config vitest.config.e2e.ts",prepack:"npm run build"},dependencies:{"@commander-js/extra-typings":"14.0.0",commander:"14.0.3",picocolors:"1.1.1"},devDependencies:{"@biomejs/biome":"2.4.11","@types/node":"24.12.4",esbuild:"0.28.1",tsx:"4.22.4",typescript:"5.9.3",vitest:"4.1.9"}};var ft=ee.version,Je=ee.name;var C=class extends Error{constructor(e,r,i,o){super(e);this.code=r;this.statusCode=i;this.body=o;this.name="ApiError"}code;statusCode;body},Xe=3e4,gt=[1e3,2e3,4e3],cn=new Set([429,502,503,504]),_t=n=>new Promise(t=>setTimeout(t,n));function dn(n){switch(n){case 401:return"auth_error";case 402:return"insufficient_credits";case 403:return"forbidden";case 404:return"not_found";case 409:return"conflict";default:return n>=500?"server_error":"request_error"}}function mn(n,t,e){if(typeof n=="object"&&n!==null){let o=n;for(let s of["detail","message","title","error"])if(typeof o[s]=="string"&&o[s].trim())return o[s]}let r=t.trim(),i=r.startsWith("{")||r.startsWith("[");return r&&!i&&r.length<=300?r:`HTTP ${e}`}var Y=class{constructor(t,e=He()){this.auth=t;this.baseUrl=e}auth;baseUrl;get authKind(){return this.auth.type}get authSource(){return this.auth.source}get credential(){return this.auth}async request(t,e,r={}){let i=new URL(`${this.baseUrl}${e}`);for(let[l,c]of Object.entries(r.query??{}))for(let u of Array.isArray(c)?c:[c])u!=null&&i.searchParams.append(l,String(u));let o=r.retry??t==="GET",s=0,a=!1;for(;;){let l={...ze(this.auth),Accept:"application/json","User-Agent":`37audits-cli/${ft}`},c={method:t,headers:l,signal:AbortSignal.timeout(r.timeoutMs??Xe)};r.body!==void 0&&(l["Content-Type"]="application/json",c.body=JSON.stringify(r.body));let u;try{u=await fetch(i,c)}catch(p){if(o&&s<gt.length){await _t(gt[s++]);continue}let f=p instanceof Error&&p.name==="TimeoutError";throw new C(f?`Request to ${i.host} timed out after ${(r.timeoutMs??Xe)/1e3}s.`:`Could not reach ${i.host}: ${p.message}`,"network_error")}if(u.status===401&&this.auth.type==="oauth"&&!a){a=!0;try{let p=await pt(this.auth.credential,{force:!0});this.auth={type:"oauth",credential:p,source:"config"};continue}catch(p){throw p instanceof y?new C(p.message,p.code,401):p}}if(o&&cn.has(u.status)&&s<gt.length){await _t(gt[s++]);continue}let d=await u.text(),m;try{m=d?JSON.parse(d):void 0}catch{m=void 0}if(!u.ok){let p=dn(u.status),f=mn(m,d,u.status);throw u.status===401&&(f=this.auth.type==="api_key"?`The API key was rejected (${this.auth.source==="env"?O.apiKey:this.auth.source}). Check it or run \`37audits login\`.`:"Your session was rejected. Run `37audits login` to sign in again."),new C(f,p,u.status,m)}return m}}};async function R(n){let t;try{t=await Ke(n.apiKey)}catch(e){let r=e instanceof y?e.code:"auth_error";return A({message:e.message,code:r},{json:n.json})}return t?new Y(t):A({message:`Not authenticated. Run \`37audits login\`, pass --api-key, or set ${O.apiKey}.`,code:"not_authenticated"},{json:n.json})}var Qe=require("node:util"),pn=/[\x00-\x08\x0B\x0C\x0E-\x1F\x7F]|\r(?!\n)/g,re=n=>(0,Qe.stripVTControlCharacters)(String(n)).replace(pn,"");function wt(n){return typeof n=="string"?re(n):Array.isArray(n)?n.map(wt):n!==null&&typeof n=="object"?Object.fromEntries(Object.entries(n).map(([t,e])=>[t,wt(e)])):n}var yt=B(K(),1);function J(){return!(!process.stdin.isTTY||!process.stdout.isTTY||process.env.CI==="true"||process.env.CI==="1"||process.env.GITHUB_ACTIONS||process.env.TERM==="dumb")}var W=process.platform!=="win32"||!!process.env.WT_SESSION||process.env.TERM_PROGRAM==="vscode";var hn=W?String.fromCodePoint(10004):"v",fn=W?String.fromCodePoint(9888):"!",gn=W?String.fromCodePoint(10007):"x",_n=[10297,10296,10292,10278,10247,10255,10265,10297].map(n=>String.fromCodePoint(n)),wn=80;function G(n,t){if(t||!J())return{update(){},stop(){},warn(){},fail(){}};let e=W?_n:["-","\\","|","/"],r=0,i=n,o=setInterval(()=>{process.stderr.write(`\r\x1B[2K ${e[r++%e.length]} ${i}`)},wn);return{update(s){i=s},stop(s){clearInterval(o),s?process.stderr.write(`\r\x1B[2K ${yt.default.green(hn)} ${s}
44
+ </html>`}function an(n){return new Promise((t,e)=>{let r=(0,Ge.createServer)();r.once("error",e),r.listen(n,"127.0.0.1",()=>{r.off("error",e),t(r)})})}async function We(n=Pe){let t,e=0;for(let l of n)try{t=await an(l),e=l;break}catch(c){if(c.code!=="EADDRINUSE")throw new y(`Could not start the login callback server on 127.0.0.1:${l}: ${c.message}`,"oauth_error")}if(!t)throw new y(`Ports ${n.join(", ")} on 127.0.0.1 are all in use. Free one of them and run \`37audits login\` again.`,"oauth_port_unavailable");let r=t,i,o,s=new Promise((l,c)=>{i=l,o=c});s.catch(()=>{});let a=setTimeout(()=>{r.close(),o(new y("Timed out after 5 minutes waiting for the browser. Run `37audits login` again.","oauth_timeout"))},nn);return r.on("request",(l,c)=>{let u=new URL(l.url??"/","http://127.0.0.1");if(u.pathname!==Xt){c.writeHead(404,{Connection:"close"}),c.end();return}let d=u.searchParams.get("code"),m=u.searchParams.get("state"),p=u.searchParams.get("error"),f=u.searchParams.get("error_description"),_=p?`Authorization ${p==="access_denied"?"denied":`failed: ${p}`}${f?` (${f})`:""}`:!d||!m?"The callback is missing the code or state parameter":null;c.writeHead(200,{"Content-Type":"text/html; charset=utf-8",Connection:"close"}),c.end(_?Ve("Sign-in failed",`${_}. Return to your terminal and try again.`):Ve("Signed in to 37 Audits","You can close this tab and return to your terminal."),()=>l.socket.destroy()),clearTimeout(a),r.close(),_?o(new y(_,"oauth_error")):d&&m&&i({code:d,state:m})}),{port:e,redirectUri:Le(e),waitForCallback:s,close(){clearTimeout(a),r.close()}}}async function qe(n,t,e){let r;try{r=await fetch(`${n}/oauth/token`,{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded",Accept:"application/json"},body:t,signal:AbortSignal.timeout(en)})}catch(i){let o=i instanceof Error&&i.name==="TimeoutError";throw new y(o?`${e} timed out after 30s. Check your connection and try again.`:`Could not reach the authorization server at ${n}. Check your connection and try again.`,"network_error")}if(!r.ok){let i="";try{let o=await r.json();i=String(o.error_description??o.msg??o.error_code??o.error??"")}catch{}throw new y(`${e} failed (HTTP ${r.status})${i?`: ${i}`:""}`,"oauth_error")}return sn(await r.json())}function Be(n){return qe(n.authUrl,new URLSearchParams({grant_type:"authorization_code",client_id:n.clientId,code:n.code,redirect_uri:n.redirectUri,code_verifier:n.codeVerifier}),"Token exchange")}function un(n){return qe(n.authUrl,new URLSearchParams({grant_type:"refresh_token",client_id:n.clientId,refresh_token:n.refreshToken}),"Token refresh")}function Zt(n,t){return{type:"oauth",auth_url:t.authUrl,client_id:t.clientId,access_token:n.access_token,access_token_expires_at:on(n.access_token),refresh_token:n.refresh_token}}function Me(n,t){return n.access_token_expires_at>t+rn}function pt(n,t={}){return rt(dt(),async()=>{let e=n;try{let s=mt()?.credential;s?.type==="oauth"&&(e=s)}catch{}let r=Math.floor(Date.now()/1e3);if(!t.force&&Me(e,r)||t.force&&e.access_token!==n.access_token&&Me(e,r))return e;let i;try{i=await un({authUrl:e.auth_url,clientId:e.client_id,refreshToken:e.refresh_token})}catch(s){throw s instanceof y&&s.code==="network_error"?s:new y(`Your session has expired. ${Qt}`,"auth_error")}let o=Zt(i,{authUrl:e.auth_url,clientId:e.client_id});return Yt({version:1,credential:o}),o})}async function Ke(n,t={}){let e=n?.trim();if(e)return{type:"api_key",key:e,source:"flag"};let r=process.env[O.apiKey]?.trim();if(r)return{type:"api_key",key:r,source:"env"};let i=mt();return i?i.credential.type==="api_key"?{type:"api_key",key:i.credential.api_key,source:"config"}:{type:"oauth",credential:t.refresh===!1?i.credential:await pt(i.credential),source:"config"}:null}function ze(n){return n.type==="api_key"?{"x-api-key":n.key}:{Authorization:`Bearer ${n.credential.access_token}`}}var ht=B(K(),1);function H(n,t){return n instanceof Error?n.message:t}function te(n){return n?!0:!process.stdout.isTTY}function Ye(n,t={}){typeof n=="string"&&!te(t.json)?console.log(n):console.log(JSON.stringify(n,null,2)),t.exitCode!==void 0&&process.exit(t.exitCode)}function A(n,t={}){let e=t.exitCode??1;if(te(t.json)){let r={message:n.message,code:n.code??"unknown"};typeof n.statusCode=="number"&&(r.statusCode=n.statusCode),console.error(JSON.stringify({error:r},null,2))}else console.error(`${ht.default.red("Error:")} ${n.message}`),typeof n.statusCode=="number"&&console.error(ht.default.dim(`[HTTP ${n.statusCode}]`));process.exit(e)}function D(n,t={}){te(t.json)?console.error(JSON.stringify({warning:{message:n}})):console.error(`${ht.default.yellow("Warning:")} ${n}`)}var ee={name:"37audits-cli",version:"1.0.2",description:"37 Audits CLI \u2014 run audits, read results and wrap deploys in maintenance windows from CI/CD",license:"MIT",type:"module",bin:{"37audits":"./dist/cli.cjs"},files:["dist/cli.cjs"],engines:{node:">=22"},repository:{type:"git",url:"git+https://github.com/37audits/37audits-cli.git"},homepage:"https://github.com/37audits/37audits-cli#readme",bugs:{url:"https://github.com/37audits/37audits-cli/issues"},keywords:["37audits","cli","audit","ci","maintenance-window"],scripts:{dev:"tsx src/cli.ts",build:"node scripts/build.mjs",lint:"biome check .","lint:fix":"biome check --write .",typecheck:"tsc --noEmit",test:"vitest run","test:e2e":"vitest run --config vitest.config.e2e.ts",prepack:"npm run build"},dependencies:{"@commander-js/extra-typings":"14.0.0",commander:"14.0.3",picocolors:"1.1.1"},devDependencies:{"@biomejs/biome":"2.4.11","@types/node":"24.12.4",esbuild:"0.28.1",tsx:"4.22.4",typescript:"5.9.3",vitest:"4.1.9"}};var ft=ee.version,Je=ee.name;var C=class extends Error{constructor(e,r,i,o){super(e);this.code=r;this.statusCode=i;this.body=o;this.name="ApiError"}code;statusCode;body},Xe=3e4,gt=[1e3,2e3,4e3],cn=new Set([429,502,503,504]),_t=n=>new Promise(t=>setTimeout(t,n));function dn(n){switch(n){case 401:return"auth_error";case 402:return"insufficient_credits";case 403:return"forbidden";case 404:return"not_found";case 409:return"conflict";default:return n>=500?"server_error":"request_error"}}function mn(n,t,e){if(typeof n=="object"&&n!==null){let o=n;for(let s of["detail","message","title","error"])if(typeof o[s]=="string"&&o[s].trim())return o[s]}let r=t.trim(),i=r.startsWith("{")||r.startsWith("[");return r&&!i&&r.length<=300?r:`HTTP ${e}`}var Y=class{constructor(t,e=He()){this.auth=t;this.baseUrl=e}auth;baseUrl;get authKind(){return this.auth.type}get authSource(){return this.auth.source}get credential(){return this.auth}async request(t,e,r={}){let i=new URL(`${this.baseUrl}${e}`);for(let[l,c]of Object.entries(r.query??{}))for(let u of Array.isArray(c)?c:[c])u!=null&&i.searchParams.append(l,String(u));let o=r.retry??t==="GET",s=0,a=!1;for(;;){let l={...ze(this.auth),Accept:"application/json","User-Agent":`37audits-cli/${ft}`},c={method:t,headers:l,signal:AbortSignal.timeout(r.timeoutMs??Xe)};r.body!==void 0&&(l["Content-Type"]="application/json",c.body=JSON.stringify(r.body));let u;try{u=await fetch(i,c)}catch(p){if(o&&s<gt.length){await _t(gt[s++]);continue}let f=p instanceof Error&&p.name==="TimeoutError";throw new C(f?`Request to ${i.host} timed out after ${(r.timeoutMs??Xe)/1e3}s.`:`Could not reach ${i.host}: ${p.message}`,"network_error")}if(u.status===401&&this.auth.type==="oauth"&&!a){a=!0;try{let p=await pt(this.auth.credential,{force:!0});this.auth={type:"oauth",credential:p,source:"config"};continue}catch(p){throw p instanceof y?new C(p.message,p.code,401):p}}if(o&&cn.has(u.status)&&s<gt.length){await _t(gt[s++]);continue}let d=await u.text(),m;try{m=d?JSON.parse(d):void 0}catch{m=void 0}if(!u.ok){let p=dn(u.status),f=mn(m,d,u.status);throw u.status===401&&(f=this.auth.type==="api_key"?`The API key was rejected (${this.auth.source==="env"?O.apiKey:this.auth.source}). Check it or run \`37audits login\`.`:"Your session was rejected. Run `37audits login` to sign in again."),new C(f,p,u.status,m)}return m}}};async function R(n){let t;try{t=await Ke(n.apiKey)}catch(e){let r=e instanceof y?e.code:"auth_error";return A({message:e.message,code:r},{json:n.json})}return t?new Y(t):A({message:`Not authenticated. Run \`37audits login\`, pass --api-key, or set ${O.apiKey}.`,code:"not_authenticated"},{json:n.json})}var Qe=require("node:util"),pn=/[\x00-\x08\x0B\x0C\x0E-\x1F\x7F]|\r(?!\n)/g,re=n=>(0,Qe.stripVTControlCharacters)(String(n)).replace(pn,"");function wt(n){return typeof n=="string"?re(n):Array.isArray(n)?n.map(wt):n!==null&&typeof n=="object"?Object.fromEntries(Object.entries(n).map(([t,e])=>[t,wt(e)])):n}var yt=B(K(),1);function J(){return!(!process.stdin.isTTY||!process.stdout.isTTY||process.env.CI==="true"||process.env.CI==="1"||process.env.GITHUB_ACTIONS||process.env.TERM==="dumb")}var W=process.platform!=="win32"||!!process.env.WT_SESSION||process.env.TERM_PROGRAM==="vscode";var hn=W?String.fromCodePoint(10004):"v",fn=W?String.fromCodePoint(9888):"!",gn=W?String.fromCodePoint(10007):"x",_n=[10297,10296,10292,10278,10247,10255,10265,10297].map(n=>String.fromCodePoint(n)),wn=80;function G(n,t){if(t||!J())return{update(){},stop(){},warn(){},fail(){}};let e=W?_n:["-","\\","|","/"],r=0,i=n,o=setInterval(()=>{process.stderr.write(`\r\x1B[2K ${e[r++%e.length]} ${i}`)},wn);return{update(s){i=s},stop(s){clearInterval(o),s?process.stderr.write(`\r\x1B[2K ${yt.default.green(hn)} ${s}
45
45
  `):process.stderr.write("\r\x1B[2K")},warn(s){clearInterval(o),process.stderr.write(`\r\x1B[2K ${yt.default.yellow(fn)} ${s}
46
46
  `)},fail(s){clearInterval(o),process.stderr.write(`\r\x1B[2K ${yt.default.red(gn)} ${s}
47
47
  `)}}}function v(n){return n.optsWithGlobals()}function yn(n){return!n.json&&J()}async function b(n,t,e,r="unexpected_error"){let i=G(t,n.quiet);try{let o=await e();return i.stop(),o}catch(o){return i.stop(),o instanceof C?A({message:o.message,code:o.code,statusCode:o.statusCode},{json:n.json}):o instanceof y?A({message:o.message,code:o.code},{json:n.json}):A({message:H(o,"Unknown error"),code:r},{json:n.json})}}function x(n,t,e){yn(n)?e(wt(t)):Ye(t,{json:n.json})}function g(n,t,e){return A({message:t,code:e},{json:n.json})}function bt(n){if(n==="fail"||n==="warning")return n;throw new Error(`Invalid --fail-on "${n}". Use "fail" or "warning".`)}function bn(n){return n==="warning"?new Set(["fail","error","warning"]):new Set(["fail","error"])}function Ct(n,t){let e=bn(t);return n.filter(r=>e.has(r.status)).length}var L=B(K(),1);var E=W?{h:String.fromCodePoint(9472),v:String.fromCodePoint(9474),tl:String.fromCodePoint(9484),tr:String.fromCodePoint(9488),bl:String.fromCodePoint(9492),br:String.fromCodePoint(9496),lm:String.fromCodePoint(9500),rm:String.fromCodePoint(9508),tm:String.fromCodePoint(9516),bm:String.fromCodePoint(9524),mm:String.fromCodePoint(9532)}:{h:"-",v:"|",tl:"+",tr:"+",bl:"+",br:"+",lm:"+",rm:"+",tm:"+",bm:"+",mm:"+"},Cn=/\x1B\[[0-9;]*m/g,Ze=n=>n.replace(Cn,"").length,xn=(n,t)=>n+" ".repeat(Math.max(0,t-Ze(n)));function On(n,t){let e=Math.max(...n.map(r=>r.length));return t.map((r,i)=>{let o=String(i+1),s=`${E.h}${E.h} ${o} ${E.h.repeat(Math.max(0,56-o.length))}`,a=n.map((l,c)=>` ${l.padEnd(e)} ${r[c]}`);return[s,...a].join(`
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "37audits-cli",
3
- "version": "1.0.0",
3
+ "version": "1.0.2",
4
4
  "description": "37 Audits CLI — run audits, read results and wrap deploys in maintenance windows from CI/CD",
5
5
  "license": "MIT",
6
6
  "type": "module",