@jerryc05/hi-tools 0.2.3 → 0.2.4

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.
Files changed (2) hide show
  1. package/dist/index.js +12 -12
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -1,23 +1,23 @@
1
1
  #!/usr/bin/env node
2
- typeof globalThis.CustomEvent>"u"&&(globalThis.CustomEvent=class extends Event{constructor(n,t={}){super(n,t),this.detail=t.detail}});import{readFile as Le}from"node:fs/promises";import{join as je}from"node:path";import{intro as Ue}from"@clack/prompts";import Je from"yargs";import{hideBin as Ge}from"yargs/helpers";import{networkInterfaces as pe}from"node:os";function S(e){let n=pe(),t={};for(let[i,o]of Object.entries(n))o=o?.filter(s=>e?.["only-ipv4"]?s.family==="IPv4":e?.["only-ipv6"]?s.family==="IPv6":!(s.family==="IPv6"&&le(s.address))),o?.length&&(t[i]=o);return t}function le(e){let n=e.toLowerCase().split("%")[0];return/^fe[89ab][0-9a-f](?::|$)/i.test(n??"")}var ue={"only-ipv4":{alias:"4",desc:"IPv4 only",boolean:!0},"only-ipv6":{alias:"6",desc:"IPv6 only",boolean:!0}},P=[{command:"ips",describe:"Show current machine's IP addrs",builder:ue,handler(e){let n=S(e),t={};for(let[i,o]of Object.entries(n))o&&(t[i]=e.verbose?o:o.map(s=>s.address));console.log(n)}}];import{hostname as me}from"node:os";var D=[{command:"mdns",describe:"Show mdns [hostname].local",handler(){let e=me();console.log(e.toLowerCase().endsWith(".local")?e:`${e}.local`)}}];import{spinner as de}from"@clack/prompts";async function A(){let{execa:e}=await import("execa");try{let{stdout:n}=await e`git rev-parse --abbrev-ref --symbolic-full-name @{u}`;return n.split("/")[0]||"origin"}catch{return"origin"}}async function E({updBranch:e,branch:n,verbose:t}){let i=de();i.start(`${e?"Updating":"Fetching"} ${n}...`);let{execa:o}=await import("execa");await o({stdio:"inherit",env:t?{GIT_TRACE:"1"}:{}})`git fetch ${await A()} ${n}${e?`:${n}`:""}`,i.message("Merging ..."),await o({stdio:"inherit",env:t?{GIT_TRACE:"1"}:{}})`git merge ${await A()}/${n} --no-verify --no-edit ${t?"":"-q"}`,i.stop("Done")}var R={branch:{alias:"b",default:"master",desc:'Default=master, or "main" if you wish'}},N=[{command:"mm",describe:"[M]erge [M]aster: Update local master to remote's, then merge into current branch",builder:R,handler(e){let{branch:n=R.branch.default,verbose:t}=e;E({updBranch:!0,branch:n,verbose:t})}},{command:"mmm",describe:"[M]erge [M]aster (don't [M]odify local master): Merge remote's master into current branch, without updating local master",builder:R,handler(e){let{branch:n=R.branch.default,verbose:t}=e;E({updBranch:!1,branch:n,verbose:t})}}];import{log as O,spinner as T}from"@clack/prompts";var L=[{command:"tschk",describe:"My ts-check rules",handler:async()=>{let{execa:e}=await import("execa");{let{stdout:n}=await e({reject:!1,stderr:"ignore"})`npx tsc --build --noEmit --emitDeclarationOnly false`,t=T();t.start("Running custom tsc type-check...");let i=["2322","2551","6133","6192","18048"],o=n.split(`
3
- `).filter(s=>{if(s.includes("/node_modules/"))return!1;let r=s.match(/error TS(\d+):/);return!(!r?.[1]||i.includes(r[1]))});o.length>0?(o.map(s=>O.error(s)),t.stop("Type-check failed"),process.exit(1)):t.stop("Type-check passed")}{let n=T();n.start("Running knip deps check...");let{stdout:t,exitCode:i}=await e({reject:!1,stderr:"ignore"})`pnpm dlx knip --strict --dependencies`;i!==0&&(O.error(t),n.stop("Dep check failed"),process.exit(1)),n.stop("Dep check passed")}}}];var j=[{command:"bam",describe:"Update BAM code-gen",handler:async()=>{let{execa:e}=await import("execa");await e({stdio:"inherit"})`pnpm dlx @byted-arch-fe/bam-code-generator update`}}];import{cancel as B,isCancel as M,log as g,note as q,select as F}from"@clack/prompts";import m from"picocolors";var U="https://bits.bytedance.net";async function _(e,n,t,i){let o={...e,pageNum:e.pageNum??1},s=`${U}/api/v1/pipelines/runs?${new URLSearchParams(o).toString()}`,r=await fetch(s,{method:"GET",headers:{"Content-Type":"application/json","X-jwt-token":n,Username:t.username},signal:i??null});return{response:r,getJson:async()=>await r.json()}}async function J(e,n,t){let i=`${U}/api/v1/pipelines/runs/${e}`,o=await fetch(i,{method:"GET",headers:{"Content-Type":"application/json","X-jwt-token":n,Username:t.username}});return{response:o,getJson:async()=>await o.json()}}var h={RUNNING:2,CANCELLED:7,SUCCESS:8,FAIL:9};function w(e){let n=new Date(e),t=new Intl.DateTimeFormat("en-US",{timeZoneName:"longOffset"}).formatToParts(n).find(i=>i.type==="timeZoneName")?.value.replace("GMT","");return`${n.toLocaleDateString("zh-CN")} ${n.toTimeString().split(" ")[0]} ${t??""}`}import{log as fe,spinner as ge}from"@clack/prompts";import G from"picocolors";var $;async function H(){let e=ge();if(e.start("Logging in..."),!$){let{AIPaaSAuth:i}=await import("@byted/aipaas-auth");$=new i("cn")}let n=await $.getJwt(),t=await $.getUserInfo();return e.stop(`Hi ${G.magenta(t.username)} from ${G.blue(`${t.scope} ${t.work_country}`)}`),fe.info(`Login will expire on ${w(t.exp*1e3)}`),{jwtStr:n,jwtObj:t}}async function be({pipelineId:e,url:n,region:t,verbose:i}){let{jwtStr:o,jwtObj:s}=await H(),r=(()=>{if(e==null&&!n)throw new Error("pipelineId or url is required");return e??z(n??"")})(),p=await X(r,o,s,t);if(p.length<=0){g.error(`No Gecko info found${t?` matching region [${t}]`:""} in latest run`);return}let{default:c}=await import("qrcode");for(let a=0;a<p.length;a++){let l=p[a];try{let u=await c.toString(l?.qrCodeScheme??"",{type:"terminal",small:!0,errorCorrectionLevel:"L"});console.log(`
2
+ typeof globalThis.CustomEvent>"u"&&(globalThis.CustomEvent=class extends Event{constructor(n,t={}){super(n,t),this.detail=t.detail}});import{readFile as Le}from"node:fs/promises";import{join as je}from"node:path";import{intro as Ue}from"@clack/prompts";import Je from"yargs";import{hideBin as Ge}from"yargs/helpers";import{networkInterfaces as ae}from"node:os";function k(e){let n=ae(),t={};for(let[i,o]of Object.entries(n))o=o?.filter(s=>e?.["only-ipv4"]?s.family==="IPv4":e?.["only-ipv6"]?s.family==="IPv6":!(s.family==="IPv6"&&ce(s.address))),o?.length&&(t[i]=o);return t}function ce(e){let n=e.toLowerCase().split("%")[0];return/^fe[89ab][0-9a-f](?::|$)/i.test(n??"")}var pe={"only-ipv4":{alias:"4",desc:"IPv4 only",boolean:!0},"only-ipv6":{alias:"6",desc:"IPv6 only",boolean:!0}},P=[{command:"ips",describe:"Show current machine's IP addrs",builder:pe,handler(e){let n=k(e),t={};for(let[i,o]of Object.entries(n))o&&(t[i]=e.verbose?o:o.map(s=>s.address));console.log(n)}}];import{hostname as le}from"node:os";var E=[{command:"mdns",describe:"Show mdns [hostname].local",handler(){let e=le();console.log(e.toLowerCase().endsWith(".local")?e:`${e}.local`)}}];import{spinner as ue}from"@clack/prompts";async function A(){let{execa:e}=await import("execa");try{let{stdout:n}=await e`git rev-parse --abbrev-ref --symbolic-full-name @{u}`;return n.split("/")[0]||"origin"}catch{return"origin"}}async function D({updBranch:e,branch:n,verbose:t}){let i=ue();i.start(`${e?"Updating":"Fetching"} ${n}...`);let{execa:o}=await import("execa");await o({stdio:"inherit",env:t?{GIT_TRACE:"1"}:{}})`git fetch ${await A()} ${n}${e?`:${n}`:""}`,i.message("Merging ..."),await o({stdio:"inherit",env:t?{GIT_TRACE:"1"}:{}})`git merge ${await A()}/${n} --no-verify --no-edit ${t?"":"-q"}`,i.stop("Done")}var R={branch:{alias:"b",default:"master",desc:'Default=master, or "main" if you wish'}},N=[{command:"mm",describe:"[M]erge [M]aster: Update local master to remote's, then merge into current branch",builder:R,handler(e){let{branch:n=R.branch.default,verbose:t}=e;D({updBranch:!0,branch:n,verbose:t})}},{command:"mmm",describe:"[M]erge [M]aster (don't [M]odify local master): Merge remote's master into current branch, without updating local master",builder:R,handler(e){let{branch:n=R.branch.default,verbose:t}=e;D({updBranch:!1,branch:n,verbose:t})}}];import{log as me,spinner as de}from"@clack/prompts";var O=[{command:"tschk",describe:"My ts-check rules",handler:async()=>{let e=!0,{execa:n}=await import("execa");{let t=de();t.start("Running custom ts type-check...");let i="";try{({stdout:i}=await n({reject:!1,stderr:"ignore"})`pnpm --quiet exec tsgo --build --noEmit`)}catch(p){if(p.code!=="ENOENT")throw p;({stdout:i}=await n({reject:!1,stderr:"ignore"})`pnpm --quiet exec tsc --build --noEmit`)}let o=["2322","2551","6133","6192","18048"],s=/5\d\d\d/,r=i.split(`
3
+ `).filter(p=>{if(p.includes("/node_modules/"))return!1;let c=p.match(/error TS(\d+):/);return!(!c?.[1]||o.includes(c[1])||s.test(c[1]))});r.length>0?(r.map(p=>me.error(p)),t.stop("Type-check failed"),e=!1):t.stop("Type-check passed")}process.exit(e?0:1)}}];var T=[{command:"bam",describe:"Update BAM code-gen",handler:async()=>{let{execa:e}=await import("execa");await e({stdio:"inherit"})`pnpm dlx @byted-arch-fe/bam-code-generator update`}}];import{cancel as G,isCancel as H,log as g,note as B,select as M}from"@clack/prompts";import m from"picocolors";var L="https://bits.bytedance.net";async function _(e,n,t,i){let o={...e,pageNum:e.pageNum??1},s=`${L}/api/v1/pipelines/runs?${new URLSearchParams(o).toString()}`,r=await fetch(s,{method:"GET",headers:{"Content-Type":"application/json","X-jwt-token":n,Username:t.username},signal:i??null});return{response:r,getJson:async()=>await r.json()}}async function j(e,n,t){let i=`${L}/api/v1/pipelines/runs/${e}`,o=await fetch(i,{method:"GET",headers:{"Content-Type":"application/json","X-jwt-token":n,Username:t.username}});return{response:o,getJson:async()=>await o.json()}}var h={RUNNING:2,CANCELLED:7,SUCCESS:8,FAIL:9};function w(e){let n=new Date(e),t=new Intl.DateTimeFormat("en-US",{timeZoneName:"longOffset"}).formatToParts(n).find(i=>i.type==="timeZoneName")?.value.replace("GMT","");return`${n.toLocaleDateString("zh-CN")} ${n.toTimeString().split(" ")[0]} ${t??""}`}import{log as fe,spinner as ge}from"@clack/prompts";import U from"picocolors";var $;async function J(){let e=ge();if(e.start("Logging in..."),!$){let{AIPaaSAuth:i}=await import("@byted/aipaas-auth");$=new i("cn")}let n=await $.getJwt(),t=await $.getUserInfo();return e.stop(`Hi ${U.magenta(t.username)} from ${U.blue(`${t.scope} ${t.work_country}`)}`),fe.info(`Login will expire on ${w(t.exp*1e3)}`),{jwtStr:n,jwtObj:t}}async function be({pipelineId:e,url:n,region:t,verbose:i}){let{jwtStr:o,jwtObj:s}=await J(),r=(()=>{if(e==null&&!n)throw new Error("pipelineId or url is required");return e??X(n??"")})(),p=await F(r,o,s,t);if(p.length<=0){g.error(`No Gecko info found${t?` matching region [${t}]`:""} in latest run`);return}let{default:c}=await import("qrcode");for(let a=0;a<p.length;a++){let l=p[a];try{let u=await c.toString(l?.qrCodeScheme??"",{type:"terminal",small:!0,errorCorrectionLevel:"L"});console.log(`
4
4
 
5
5
  ${u}`),console.dir(l),a<p.length-1&&console.log(`
6
6
 
7
7
  -----------------
8
8
 
9
- `)}catch(u){console.error("Failed to generate QR:",u)}}}var ye={url:{alias:"u",desc:"Bits URL",string:!0,conflicts:["pipeline-id"]},"pipeline-id":{alias:"p",desc:"Pipeline ID (Overrides URL)",string:!0,conflicts:["url"]},region:{alias:"r",desc:"String-match based region filter",string:!0}},W=[{command:"gecko",describe:"Show gecko info by bits URL",builder:e=>e.options(ye).example("$0 tt-gecko -r us -u 'https://b??.net/devops/??/develop/detail/??/flow?devops_space_type=server_fe&pipelineId=1139212901634&stage=dev_gatekeeper_stage'","Example of URL mode, filtering us region"),handler(e){let{url:n,pipelineId:t,region:i,verbose:o}=e;be({url:n,pipelineId:t,region:i,verbose:o})}}];async function X(e,n,t,i){let{response:o,getJson:s}=await _({pipelineId:e,pageSize:1,withoutJob:!1},n,t);o.ok||(g.error(`[getRunInfoByPipelineID] failed: ${o.status} ${o.statusText}
10
- ${await o.text()}`),process.exit(1));let r=await s();r.pipelineRuns[0]?.runStatus!==h.SUCCESS&&g.warn(`Latest run (runId=${r.pipelineRuns[0]?.runId}) status=${V(r.pipelineRuns[0]?.runStatus)}. Gecko info may be unavailable.`);let p=K(r.pipelineRuns,i);if(p.length)return p;let c=await he(e,r.pipelineRuns);if(c)return X(c,n,t,i);let a=await we(e,n,t);return await Ie(a,n,t)}function K(e,n){return e.flatMap(t=>t.jobs.map(i=>{try{let o=i.jobAtom.output;if(!o)return null;let s=o.GECKO_packageInfo;if(!s)return null;let r=o.GECKO_region;if(n&&!r?.includes(n))return null;let p=JSON.parse(s),{qrCodeScheme:c,candidatePackage:a,channel:l,updatedAt:u,creator:f,distributeRule:y}=p.package,{scmVersion:k}=a,se=w(Number.parseInt(u,10)*1e3),ae=y.envLaneList.flatMap(ce=>ce.values);return{qrCodeScheme:c,region:r,scmVersion:k,channel:l,updatedDate:se,creator:f,envs:ae,runId:t.runId,runSeq:t.runSeq}}catch(o){return console.error(o),null}}).filter(i=>i!=null)).filter(t=>!!t)}async function he(e,n){let t=n.flatMap(s=>s.jobs.map(r=>r.jobAtom.inputs?.trigger_params).filter(r=>!!r).filter(r=>r.detail_url.length));if(!t.length)return;q(`Found ${t.length} possible alternative pipeline(s) you may want to try instead.`,"Mistyped the pipeline ID?");let i=[{value:"",label:`(Keep current pipeline id=${e})`}].concat(t.map(s=>({value:z(s.detail_url),label:`${m.underline(s.development_task_name)} by ${s.developer.join(",")}`,hint:s.detail_url}))),o=await F({message:"Select a pipeline to change, or cancel [ESC] to use the current pipeline.",options:i});if(M(o)||!o){B("Keep using current pipeline");return}return g.success(`Using new pipeline id=${o}`),o}async function we(e,n,t){let{response:o,getJson:s}=await _({pipelineId:e,pageSize:10,withoutJob:!0},n,t);o.ok||(g.error(`[getRunInfoByPipelineID] failed: ${o.status} ${o.statusText}
9
+ `)}catch(u){console.error("Failed to generate QR:",u)}}}var ye={url:{alias:"u",desc:"Bits URL",string:!0,conflicts:["pipeline-id"]},"pipeline-id":{alias:"p",desc:"Pipeline ID (Overrides URL)",string:!0,conflicts:["url"]},region:{alias:"r",desc:"String-match based region filter",string:!0}},q=[{command:"gecko",describe:"Show gecko info by bits URL",builder:e=>e.options(ye).example("$0 tt-gecko -r us -u 'https://b??.net/devops/??/develop/detail/??/flow?devops_space_type=server_fe&pipelineId=1139212901634&stage=dev_gatekeeper_stage'","Example of URL mode, filtering us region"),handler(e){let{url:n,pipelineId:t,region:i,verbose:o}=e;be({url:n,pipelineId:t,region:i,verbose:o})}}];async function F(e,n,t,i){let{response:o,getJson:s}=await _({pipelineId:e,pageSize:1,withoutJob:!1},n,t);o.ok||(g.error(`[getRunInfoByPipelineID] failed: ${o.status} ${o.statusText}
10
+ ${await o.text()}`),process.exit(1));let r=await s();r.pipelineRuns[0]?.runStatus!==h.SUCCESS&&g.warn(`Latest run (runId=${r.pipelineRuns[0]?.runId}) status=${K(r.pipelineRuns[0]?.runStatus)}. Gecko info may be unavailable.`);let p=W(r.pipelineRuns,i);if(p.length)return p;let c=await he(e,r.pipelineRuns);if(c)return F(c,n,t,i);let a=await we(e,n,t);return await Ie(a,n,t)}function W(e,n){return e.flatMap(t=>t.jobs.map(i=>{try{let o=i.jobAtom.output;if(!o)return null;let s=o.GECKO_packageInfo;if(!s)return null;let r=o.GECKO_region;if(n&&!r?.includes(n))return null;let p=JSON.parse(s),{qrCodeScheme:c,candidatePackage:a,channel:l,updatedAt:u,creator:f,distributeRule:y}=p.package,{scmVersion:S}=a,oe=w(Number.parseInt(u,10)*1e3),ie=y.envLaneList.flatMap(se=>se.values);return{qrCodeScheme:c,region:r,scmVersion:S,channel:l,updatedDate:oe,creator:f,envs:ie,runId:t.runId,runSeq:t.runSeq}}catch(o){return console.error(o),null}}).filter(i=>i!=null)).filter(t=>!!t)}async function he(e,n){let t=n.flatMap(s=>s.jobs.map(r=>r.jobAtom.inputs?.trigger_params).filter(r=>!!r).filter(r=>r.detail_url.length));if(!t.length)return;B(`Found ${t.length} possible alternative pipeline(s) you may want to try instead.`,"Mistyped the pipeline ID?");let i=[{value:"",label:`(Keep current pipeline id=${e})`}].concat(t.map(s=>({value:X(s.detail_url),label:`${m.underline(s.development_task_name)} by ${s.developer.join(",")}`,hint:s.detail_url}))),o=await M({message:"Select a pipeline to change, or cancel [ESC] to use the current pipeline.",options:i});if(H(o)||!o){G("Keep using current pipeline");return}return g.success(`Using new pipeline id=${o}`),o}async function we(e,n,t){let{response:o,getJson:s}=await _({pipelineId:e,pageSize:10,withoutJob:!0},n,t);o.ok||(g.error(`[getRunInfoByPipelineID] failed: ${o.status} ${o.statusText}
11
11
  ${await o.text()}`),process.exit(1));let r=await s();r.pipelineRuns.length<=0&&(g.error(`No pipeline runs found in the most recent 10 runs
12
- ${JSON.stringify(r,null,1)}`),process.exit(1)),q("The latest pipeline run may be ongoing/failed. Try a previous run to inspect.","Select a previous run");let p=r.pipelineRuns.map(a=>{let l=V(a.runStatus),u=Re(a),f=a.triggerInfo?.triggeredBy||a.createdBy||"?";return{value:a.runId,label:`#${a.runSeq} runId=${a.runId} ${l}`,hint:`${u} by ${f}`}}),c=await F({message:"Select the run ID to inspect",options:p});return M(c)&&(B("Run selection cancelled"),process.exit(0)),c}async function Ie(e,n,t){let{response:i,getJson:o}=await J(e,n,t);i.ok||(g.error(`[getRunDetailByRunID] failed: ${i.status} ${i.statusText}
13
- ${await i.text()}`),process.exit(1));let s=await o();return K([s.pipelineRun])}function z(e){let n=/\bpipelineId=(\d+)\b/,i=e.match(n)?.[1]?.trim();if(i){if(!/^\d+$/.test(i))throw new Error("Invalid pipelineId query from URL. Expecting a pipelineId query value with all numbers");return i}throw new Error(`Invalid URL. Expecting a url containing ${m.bold(m.yellow("pipelineId"))} query param. E.g. `+m.underline(m.gray(`https://b??.net/devops/??/develop/detail/??/flow?devops_space_type=server_fe&${m.bold(m.magenta("pipelineId=1139212901634"))}&stage=dev_gatekeeper_stage`)))}function V(e){switch(e){case h.RUNNING:return m.blue("RUNNING");case h.CANCELLED:return m.gray("CANCELLED");case h.SUCCESS:return m.green("SUCCESS");case h.FAIL:return m.red("FAIL")}return`status=${e}`}function Re(e){return e.startedAt?`started @ ${w(e.startedAt)}`:e.createdAt?`created @ ${w(e.createdAt)}`:"time=?"}import{access as $e,constants as ve}from"node:fs/promises";var Q=[{command:"i18n",describe:"I18n scan and sort",handler:async()=>{let e="starling.config.js",n="combine-lang.js";for(let o of[e,n])try{await $e(o,ve.R_OK)}catch(s){console.error(`tt i18n: Failed to read ${o}
14
- `,s),process.exit(1)}let{execa:t,execaNode:i}=await import("execa");await t({stdio:"inherit"})`pnpm dlx @ies/starling-cli scan -c ${e} --fallback --disable-browser`,await i({stdio:"inherit"})`${e}`,await t({stdio:"inherit"})`pnpm --package=json-sort-cli dlx sortjson ./src/lang`.catch(o=>console.error("tt i18n sortjson error:",o))}}];import{log as v,note as xe}from"@clack/prompts";async function Ce({repoId:e,hash:n,branch:t}){let i="SCM_USERNAME",o="SCM_PASSWORD",s=process.env[i],r=process.env[o];(!s||!r)&&(v.error(`Missing ${s?o:i} in env var.
15
- Go to https://luban.bytedance.net/npm/publish and get your personal SCM username+password.`),process.exit(1));let{execa:p}=await import("execa");try{let c=p`git log -1 --pretty=%s`,a,l;n||!n&&!t?n?a=n:a=(await p`git rev-parse HEAD`).stdout.trim():t?l=t:l=(await p`git branch --show-current`).stdout.trim();let u={repos:e,create_user:s,pub_base:a?"commit_base":"branch_base",base_commit_hash:a??"",branch_name:l??"",desc:`[${d?.version}] ${(await c).stdout.trim()}`,has_version_stage:!1};xe(`\u2139\uFE0F ${u.create_user} is publishing ${d?.name}@${d?.version} to repoId=${u.repos}
12
+ ${JSON.stringify(r,null,1)}`),process.exit(1)),B("The latest pipeline run may be ongoing/failed. Try a previous run to inspect.","Select a previous run");let p=r.pipelineRuns.map(a=>{let l=K(a.runStatus),u=Re(a),f=a.triggerInfo?.triggeredBy||a.createdBy||"?";return{value:a.runId,label:`#${a.runSeq} runId=${a.runId} ${l}`,hint:`${u} by ${f}`}}),c=await M({message:"Select the run ID to inspect",options:p});return H(c)&&(G("Run selection cancelled"),process.exit(0)),c}async function Ie(e,n,t){let{response:i,getJson:o}=await j(e,n,t);i.ok||(g.error(`[getRunDetailByRunID] failed: ${i.status} ${i.statusText}
13
+ ${await i.text()}`),process.exit(1));let s=await o();return W([s.pipelineRun])}function X(e){let n=/\bpipelineId=(\d+)\b/,i=e.match(n)?.[1]?.trim();if(i){if(!/^\d+$/.test(i))throw new Error("Invalid pipelineId query from URL. Expecting a pipelineId query value with all numbers");return i}throw new Error(`Invalid URL. Expecting a url containing ${m.bold(m.yellow("pipelineId"))} query param. E.g. `+m.underline(m.gray(`https://b??.net/devops/??/develop/detail/??/flow?devops_space_type=server_fe&${m.bold(m.magenta("pipelineId=1139212901634"))}&stage=dev_gatekeeper_stage`)))}function K(e){switch(e){case h.RUNNING:return m.blue("RUNNING");case h.CANCELLED:return m.gray("CANCELLED");case h.SUCCESS:return m.green("SUCCESS");case h.FAIL:return m.red("FAIL")}return`status=${e}`}function Re(e){return e.startedAt?`started @ ${w(e.startedAt)}`:e.createdAt?`created @ ${w(e.createdAt)}`:"time=?"}import{access as $e,constants as ve}from"node:fs/promises";var z=[{command:"i18n",describe:"I18n scan and sort",handler:async()=>{let e="starling.config.js",n="combine-lang.js";for(let o of[e,n])try{await $e(o,ve.R_OK)}catch(s){console.error(`tt i18n: Failed to read ${o}
14
+ `,s),process.exit(1)}let{execa:t,execaNode:i}=await import("execa");await t({stdio:"inherit"})`pnpm dlx @ies/starling-cli scan -c ${e} --fallback --disable-browser`,await i({stdio:"inherit"})`${e}`,await t({stdio:"inherit"})`pnpm --package=json-sort-cli dlx sortjson ./src/lang`.catch(o=>console.error("tt i18n sortjson error:",o))}}];import{log as v,note as Ce}from"@clack/prompts";async function xe({repoId:e,hash:n,branch:t}){let i="SCM_USERNAME",o="SCM_PASSWORD",s=process.env[i],r=process.env[o];(!s||!r)&&(v.error(`Missing ${s?o:i} in env var.
15
+ Go to https://luban.bytedance.net/npm/publish and get your personal SCM username+password.`),process.exit(1));let{execa:p}=await import("execa");try{let c=p`git log -1 --pretty=%s`,a,l;n||!n&&!t?n?a=n:a=(await p`git rev-parse HEAD`).stdout.trim():t?l=t:l=(await p`git branch --show-current`).stdout.trim();let u={repos:e,create_user:s,pub_base:a?"commit_base":"branch_base",base_commit_hash:a??"",branch_name:l??"",desc:`[${d?.version}] ${(await c).stdout.trim()}`,has_version_stage:!1};Ce(`\u2139\uFE0F ${u.create_user} is publishing ${d?.name}@${d?.version} to repoId=${u.repos}
16
16
  ${a?`hash=${a}`:`brch=${l}`}
17
- desc=${u.desc}`);let f=await fetch("https://scm.byted.org/api/v2/npm_versions/",{method:"POST",headers:{Authorization:`Basic ${Buffer.from(`${s}:${r}`).toString("base64")}`,Accept:"application/json","Content-Type":"application/json"},body:JSON.stringify(u)});if(!f.ok){let k=await f.text();v.error(`HTTP ${f.status} Error: ${k}`),process.exit(1)}let y=await f.json();v.success("\u{1F389} Successfully published:",y)}catch(c){v.error("Execution Failed:"),console.error(c),process.exit(1)}}var ke={"by-hash":{alias:"h",desc:"Publish pkg by hash (default)",string:!0,conflicts:["by-branch"]},"by-branch":{alias:"b",desc:"Publish pkg by branch",string:!0,conflicts:["by-hash"]}},Z=[{command:"luban <repoId>",describe:"Publish current repo pkg to Luban",builder:ke,handler(e){let{byHash:n,byBranch:t}=e,i=Number(e.repoId);Ce({repoId:i,hash:n,branch:t})}}];import{unlink as Se}from"node:fs/promises";import{join as _e}from"node:path";import{log as Y,note as Pe}from"@clack/prompts";import ee from"picocolors";import x from"base62";var b;(r=>{let e=0;r.RAX_WEBPAGE="/",r.RAX_DEVICE_INFO=`/${x.encode(e++)}`,r.RAX_CHANGE_ACCOUNT=`/${x.encode(e++)}`,r.RAX_SCRSHOT=`/${x.encode(e++)}`,r.RAX_OPEN_SCHEMA=`/${x.encode(e++)}`})(b||={});var C=["pnpm","dlx","--silent","--allow-build=better-sqlite3","--allow-build=sharp","@tiktok-fe/rax-cli@>=0.3.28"];async function De(e){let{execa:n}=await import("execa"),{default:t}=await import("express"),i=t();i.use(t.json()),i.get(b.RAX_WEBPAGE,(s,r)=>{r.sendFile(_e(import.meta.dirname,"index.html"))}),i.get(b.RAX_DEVICE_INFO,async(s,r)=>{let{stdout:p}=await n`${C} device info`;if(p.trim().startsWith("Error:")){r.status(400).send(p);return}let c=JSON.parse(p);delete c.appInfo.appInfo.appIconBase64,delete c.appInfo.appSettings.language;let{account:a}=c.appInfo.appSettings;a.current={customID:a.current.customID,nickname:a.current.nickname,userID:a.current.userID};for(let l=0;l<(a.loginAccountList?.length??0);l++){if(!a.loginAccountList)continue;let u=a.loginAccountList[l];u&&(a.loginAccountList[l]={customID:u.customID,nickname:u.nickname,userID:u.userID})}r.json(c)}),i.post(b.RAX_CHANGE_ACCOUNT,async(s,r)=>{let{userID:p}=s.body;if(!p){r.sendStatus(400);return}let{stdout:c}=await n`${C} app account change ${p} --json`,a=JSON.parse(c).content?.[0]?.text;r.type("json").send(a)}),i.get(b.RAX_SCRSHOT,async(s,r)=>{let{execa:p}=await import("execa"),{default:c}=await import("sharp"),{temporaryFile:a}=await import("tempy"),l=a({extension:"png"}),{stdout:u,stderr:f}=await p`${C} device screenshot --output ${l}`;if(u.trim().includes("Cannot screenshot")||u.trim().includes("no available device")){r.status(404).send(u);return}let y=a({extension:"webp"});await c(l).webp({quality:70,effort:5,smartSubsample:!0}).toFile(y),Se(l).catch(),r.sendFile(y)}),i.post(b.RAX_OPEN_SCHEMA,async(s,r)=>{let{execa:p}=await import("execa"),{schema:c}=s.body,{stdout:a}=await p`${C} device open-schema ${c}`;r.send(a)});let o=i.listen(e.port??0,()=>{let s=o.address(),r=typeof s!="string"?s?.port:void 0;r||(Y.error(`Failed to get port from addr [${s}]`),process.exit(1));let p=Object.values(S()??{"":["localhost"]}).flat().sort((c,a)=>c.internal&&!a.internal?-1:!c.internal&&a.internal?1:c.family==="IPv4"&&a.family==="IPv6"?-1:c.family==="IPv6"&&a.family==="IPv4"?1:c.address.localeCompare(a.address)).map(c=>` ${c.internal?ee.green("[LOCAL]"):ee.yellow("[ LAN ]")} http://${c.family==="IPv6"?`[${c.address}]`:c.address}:${r}
17
+ desc=${u.desc}`);let f=await fetch("https://scm.byted.org/api/v2/npm_versions/",{method:"POST",headers:{Authorization:`Basic ${Buffer.from(`${s}:${r}`).toString("base64")}`,Accept:"application/json","Content-Type":"application/json"},body:JSON.stringify(u)});if(!f.ok){let S=await f.text();v.error(`HTTP ${f.status} Error: ${S}`),process.exit(1)}let y=await f.json();v.success("\u{1F389} Successfully published:",y)}catch(c){v.error("Execution Failed:"),console.error(c),process.exit(1)}}var Se={"by-hash":{alias:"h",desc:"Publish pkg by hash (default)",string:!0,conflicts:["by-branch"]},"by-branch":{alias:"b",desc:"Publish pkg by branch",string:!0,conflicts:["by-hash"]}},V=[{command:"luban <repoId>",describe:"Publish current repo pkg to Luban",builder:Se,handler(e){let{byHash:n,byBranch:t}=e,i=Number(e.repoId);xe({repoId:i,hash:n,branch:t})}}];import{unlink as ke}from"node:fs/promises";import{join as _e}from"node:path";import{log as Q,note as Pe}from"@clack/prompts";import Z from"picocolors";import C from"base62";var b;(r=>{let e=0;r.RAX_WEBPAGE="/",r.RAX_DEVICE_INFO=`/${C.encode(e++)}`,r.RAX_CHANGE_ACCOUNT=`/${C.encode(e++)}`,r.RAX_SCRSHOT=`/${C.encode(e++)}`,r.RAX_OPEN_SCHEMA=`/${C.encode(e++)}`})(b||={});var x=["pnpm","dlx","--silent","--allow-build=better-sqlite3","--allow-build=sharp","@tiktok-fe/rax-cli@>=0.3.28"];async function Ee(e){let{execa:n}=await import("execa"),{default:t}=await import("express"),i=t();i.use(t.json()),i.get(b.RAX_WEBPAGE,(s,r)=>{r.sendFile(_e(import.meta.dirname,"index.html"))}),i.get(b.RAX_DEVICE_INFO,async(s,r)=>{let{stdout:p}=await n`${x} device info`;if(p.trim().startsWith("Error:")){r.status(400).send(p);return}let c=JSON.parse(p);delete c.appInfo.appInfo.appIconBase64,delete c.appInfo.appSettings.language;let{account:a}=c.appInfo.appSettings;a.current={customID:a.current.customID,nickname:a.current.nickname,userID:a.current.userID};for(let l=0;l<(a.loginAccountList?.length??0);l++){if(!a.loginAccountList)continue;let u=a.loginAccountList[l];u&&(a.loginAccountList[l]={customID:u.customID,nickname:u.nickname,userID:u.userID})}r.json(c)}),i.post(b.RAX_CHANGE_ACCOUNT,async(s,r)=>{let{userID:p}=s.body;if(!p){r.sendStatus(400);return}let{stdout:c}=await n`${x} app account change ${p} --json`,a=JSON.parse(c).content?.[0]?.text;r.type("json").send(a)}),i.get(b.RAX_SCRSHOT,async(s,r)=>{let{execa:p}=await import("execa"),{default:c}=await import("sharp"),{temporaryFile:a}=await import("tempy"),l=a({extension:"png"}),{stdout:u,stderr:f}=await p`${x} device screenshot --output ${l}`;if(u.trim().includes("Cannot screenshot")||u.trim().includes("no available device")){r.status(404).send(u);return}let y=a({extension:"webp"});await c(l).webp({quality:70,effort:5,smartSubsample:!0}).toFile(y),ke(l).catch(),r.sendFile(y)}),i.post(b.RAX_OPEN_SCHEMA,async(s,r)=>{let{execa:p}=await import("execa"),{schema:c}=s.body,{stdout:a}=await p`${x} device open-schema ${c}`;r.send(a)});let o=i.listen(e.port??0,()=>{let s=o.address(),r=typeof s!="string"?s?.port:void 0;r||(Q.error(`Failed to get port from addr [${s}]`),process.exit(1));let p=Object.values(k()??{"":["localhost"]}).flat().sort((c,a)=>c.internal&&!a.internal?-1:!c.internal&&a.internal?1:c.family==="IPv4"&&a.family==="IPv6"?-1:c.family==="IPv6"&&a.family==="IPv4"?1:c.address.localeCompare(a.address)).map(c=>` ${c.internal?Z.green("[LOCAL]"):Z.yellow("[ LAN ]")} http://${c.family==="IPv6"?`[${c.address}]`:c.address}:${r}
18
18
  `);Pe(`Server running at
19
- ${p.join("")}`),Y.info(`\u{1F680} Try ${p[0]}`)})}var Ae={port:{alias:"p",desc:"Port for helper",number:!0}},te=[{command:"rax",describe:"Start rax helper (web)",builder:Ae,handler:De}];var ne=[{command:"tt",describe:"TT/BD internal toolset",builder:e=>e.command([...j,...W,...Q,...Z,...te]).demandCommand(1),handler(){}}];import{lstatSync as Ee}from"node:fs";import{log as re,note as Ne,spinner as I}from"@clack/prompts";var Oe=e=>new Promise(n=>setTimeout(n,e));async function Te(e){let n=d.version,t=`${d.name}@${n}`,i=1e4,o=[...e.installCmdPrefix.split(" "),t];Ne(`\u{1F680} Monitoring ${t}...
19
+ ${p.join("")}`),Q.info(`\u{1F680} Try ${p[0]}`)})}var Ae={port:{alias:"p",desc:"Port for helper",number:!0}},Y=[{command:"rax",describe:"Start rax helper (web)",builder:Ae,handler:Ee}];var ee=[{command:"tt",describe:"TT/BD internal toolset",builder:e=>e.command([...T,...q,...z,...V,...Y]).demandCommand(1),handler(){}}];import{lstatSync as De}from"node:fs";import{log as te,note as Ne,spinner as I}from"@clack/prompts";var Oe=e=>new Promise(n=>setTimeout(n,e));async function Te(e){let n=d.version,t=`${d.name}@${n}`,i=1e4,o=[...e.installCmdPrefix.split(" "),t];Ne(`\u{1F680} Monitoring ${t}...
20
20
  \u{1F4C2} Target: ${e.target}
21
- \u{1F6E0} Install cmd: ${o.join(" ")}`);let{execa:s}=await import("execa");try{let r=I();r.start("Pulling latest changes in target repo..."),await s({cwd:e.target,stdio:"inherit",env:{GIT_TRACE:"1"}})`git pull`,r.stop("Latest commit pulled"),r=I();let p=Date.now();for(let c=1;;c++){r.start(`Waiting for ${t}, attempt ${c}`);let{exitCode:a}=await s({reject:!1,stdio:"inherit"})`npm view ${t} version`;if(a===0){r.stop(`${t} is live! Found it \u2705`);try{r=I(),r.start(`Installing ${t} via ${o}`),await s({cwd:e.target,stdio:"inherit"})`${o}`,r.stop(`${t} installed! \u2705`);break}catch{r.stop(`${t} not installed`),re.error("Registry updated but failed to install")}}(Date.now()-p)/1e3>=e.timeout&&(r.stop(`Didn't find ${t} in ${e.timeout} sec(s)`),process.exit(1)),await Oe(i)}r=I(),r.start("Committing changes..."),await s({stdio:"inherit"})`git commit -am 'chore: upd ${t}`,r.stop("Committed \u2705"),r=I(),r.start("Pushing to remote..."),await s({stdio:"inherit"})`git push`,r.stop("Pushed \u2705"),re.success("\u{1F389} DONE!")}catch(r){console.error(`
22
- \u274C Task failed:`,r),process.exit(1)}}var oe={target:{alias:"t",desc:"Target repository path",demandOption:!0,normalize:!0},"install-cmd-prefix":{alias:"cmd",desc:"Pkg install command prefix",default:"pnpm add"},timeout:{desc:"Timeout checking new pkg version in sec",default:300}},ie=[{command:"wup",describe:"[W]ait for pkg publish, [U]pdate target repo, and [P]ush",builder:e=>e.options(oe).example('$0 wup -t "/tmp/..." -c "emo add"',"Install w/ eden-mono").example('$0 wup -t "/tmp/..." -c "rush add --make-consistent -p"',"Install w/ @microsoft/rush"),handler(e){let{target:n,installCmdPrefix:t=oe["install-cmd-prefix"].default,verbose:i}=e,o=Number(e.timeout),s=`Path ${n} is not a directory.`;try{if(!n||!Ee(n).isDirectory())throw new Error(s);Te({target:n,installCmdPrefix:t,timeout:o,verbose:i})}catch(r){throw new Error(s,{cause:r})}}}];var d=JSON.parse(await Le(je(import.meta.dirname,"../package.json"),"utf8"));Ue(`\u{1F44B} ${d.name} v${d.version}`);var He=[...N,...L,...ie,...P,...D,...ne];Je().scriptName("hi").version(d.version).option("verbose",{type:"boolean",description:"Run with verbose logging",global:!0}).strict().recommendCommands().command(He).help().parse(Ge(process.argv));export{d as PKG};
21
+ \u{1F6E0} Install cmd: ${o.join(" ")}`);let{execa:s}=await import("execa");try{let r=I();r.start("Pulling latest changes in target repo..."),await s({cwd:e.target,stdio:"inherit",env:{GIT_TRACE:"1"}})`git pull`,r.stop("Latest commit pulled"),r=I();let p=Date.now();for(let c=1;;c++){r.start(`Waiting for ${t}, attempt ${c}`);let{exitCode:a}=await s({reject:!1,stdio:"inherit"})`npm view ${t} version`;if(a===0){r.stop(`${t} is live! Found it \u2705`);try{r=I(),r.start(`Installing ${t} via ${o}`),await s({cwd:e.target,stdio:"inherit"})`${o}`,r.stop(`${t} installed! \u2705`);break}catch{r.stop(`${t} not installed`),te.error("Registry updated but failed to install")}}(Date.now()-p)/1e3>=e.timeout&&(r.stop(`Didn't find ${t} in ${e.timeout} sec(s)`),process.exit(1)),await Oe(i)}r=I(),r.start("Committing changes..."),await s({stdio:"inherit"})`git commit -am 'chore: upd ${t}`,r.stop("Committed \u2705"),r=I(),r.start("Pushing to remote..."),await s({stdio:"inherit"})`git push`,r.stop("Pushed \u2705"),te.success("\u{1F389} DONE!")}catch(r){console.error(`
22
+ \u274C Task failed:`,r),process.exit(1)}}var ne={target:{alias:"t",desc:"Target repository path",demandOption:!0,normalize:!0},"install-cmd-prefix":{alias:"cmd",desc:"Pkg install command prefix",default:"pnpm add"},timeout:{desc:"Timeout checking new pkg version in sec",default:300}},re=[{command:"wup",describe:"[W]ait for pkg publish, [U]pdate target repo, and [P]ush",builder:e=>e.options(ne).example('$0 wup -t "/tmp/..." -c "emo add"',"Install w/ eden-mono").example('$0 wup -t "/tmp/..." -c "rush add --make-consistent -p"',"Install w/ @microsoft/rush"),handler(e){let{target:n,installCmdPrefix:t=ne["install-cmd-prefix"].default,verbose:i}=e,o=Number(e.timeout),s=`Path ${n} is not a directory.`;try{if(!n||!De(n).isDirectory())throw new Error(s);Te({target:n,installCmdPrefix:t,timeout:o,verbose:i})}catch(r){throw new Error(s,{cause:r})}}}];var d=JSON.parse(await Le(je(import.meta.dirname,"../package.json"),"utf8"));Ue(`\u{1F44B} ${d.name} v${d.version}`);var He=[...N,...O,...re,...P,...E,...ee];Je().scriptName("hi").version(d.version).option("verbose",{type:"boolean",description:"Run with verbose logging",global:!0}).strict().recommendCommands().command(He).help().parse(Ge(process.argv));export{d as PKG};
23
23
  //# sourceMappingURL=index.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jerryc05/hi-tools",
3
- "version": "0.2.3",
3
+ "version": "0.2.4",
4
4
  "description": "A collection of my everyday SDE tools.",
5
5
  "scripts": {
6
6
  "pub": "npm run build && npm version patch && export NPM_CONFIG_REGISTRY=https://registry.npmjs.org &&{ npm whoami || npm login ;} && npm publish --access public && git push",