@chneau/x 0.0.218 → 0.0.219

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/package.json +1 -1
  2. package/x.js +1 -1
package/package.json CHANGED
@@ -1,5 +1,5 @@
1
1
  {
2
2
  "name": "@chneau/x",
3
- "version": "0.0.218",
3
+ "version": "0.0.219",
4
4
  "bin": "./x.js"
5
5
  }
package/x.js CHANGED
@@ -214,4 +214,4 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
214
214
  `).filter(Boolean),".deploy.json");let q=!1,w=[];for(let K of f){let T=await Bun.file(K).text().catch(()=>null);if(!T)continue;let j=Wy(T),r=JSON.parse(j),k=await my.parseAsync(r).catch(()=>null);if(!k)continue;let M=structuredClone(k);if(_.length)for(let J in k.services){if(_.includes(J))continue;delete k.services[J]}if(!Object.keys(k.services).length)continue;q=!0;for(let[J,D]of Object.entries(k.services))w.push(k3$({config:{...k,services:{[J]:D}},allServices:M.services,cwd:py.dirname(K)}))}if(!q&&!P)await r3$();if(P&&!q)console.log("\u274C No valid json files found");await Promise.all(w)},r3$=async()=>{console.log("\uD83D\uDD52 Creating .deploy.json template...");let $=my.parse({$schema:"https://raw.githubusercontent.com/chneau/x/refs/heads/master/deployment-schema.json",registries:{dockerhub:{hostname:"docker.io",username:"username",password:"password"}},images:{"my-image":{registry:"dockerhub",repository:"my-repo",imageName:"my-image"}},services:{"my-service":{image:"my-image",file:"kubeconfig",context:"my-context",namespace:"my-namespace",env:{ENV:"value"},endpoints:["my-endpoint.com"]}}}),f=JSON.stringify($,null,2),_=Bun.file(".deploy.json");if(await _.exists()){console.log("\u274C .deploy.json already exists");return}await _.write(f),console.log("\u2705 Created .deploy.json")},ey=($,f,_=[])=>{if(_.includes($.extends))throw Error(`Circular dependency detected: ${_.join(" -> ")} -> ${$.extends}`);let P=[..._,$.extends],q=f[$.extends];if(!q)throw Error(`Service ${$.extends} not found`);let w;if("extends"in q)w=ey(q,f,P);else w=structuredClone(q);return w.image=$.image??w.image,w.replicas=$.replicas??w.replicas,w.file=$.file??w.file,w.context=$.context??w.context,w.namespace=$.namespace??w.namespace,w.port=$.port??w.port,w.env={...w.env,...$.env},w.readOnlyRootFilesystem=$.readOnlyRootFilesystem??w.readOnlyRootFilesystem,w.endpoints=$.endpoints??w.endpoints,w},k3$=async({config:$,cwd:f,allServices:_})=>{for(let[P,q]of Object.entries($.services)){console.log(`\uD83D\uDD52 Deploying ${P}...`);let w="extends"in q?ey(q,_):q,K=$.images[w.image];if(!K){console.error(`\u274C Image ${w.image} not found`);continue}let O=K.registry?$.registries[K.registry]:null;if(!O){console.info(`\u2753 Registry ${K.registry} not found`);continue}if(O.username&&O.password){console.log(`\uD83D\uDD11 Logging in to ${O.hostname}...`),await Bun.$`echo ${O.password} | docker login --username ${O.username} --password-stdin ${O.hostname}`,console.log(`... \u2705 Logged in to ${O.hostname}`);let r=`${O.hostname}/${K.repository}/${K.imageName}:${K.tag}`;console.log(`\uD83D\uDD28 Building ${r}...`);let k={raw:Object.entries(K.args).map(([v,J])=>`--build-arg=${v}=${J}`).join(" ")},M={raw:K.target?`--target=${K.target}`:""};await Bun.$`docker build --pull --push --tag=${r} ${M} --file=${K.dockerfile} ${k} ${K.context}`,console.log(`... \u2705 Built ${r}`)}console.log(`\uD83D\uDD17 Creating deployment for ${P}...`);let T=await Xy({serviceAlias:P,registry:O,image:K,service:w});console.log(`... \u2705 Created deployment for ${P}`),console.log(`\uD83D\uDE80 Deploying ${P}...`);let j={...Bun.env,KUBECONFIG:py.join(f,w.file)};await Bun.$`echo ${T} | kubectl --context=${w.context} apply --filename=-`.env(j),console.log(`... \u2705 Deployed ${P}`)}};var{$:v$}=globalThis.Bun;var{$:B$}=globalThis.Bun;var Vy=i7.object({email:i7.email(),name:i7.string().min(1),updates:i7.boolean()}),yj=async($)=>{let f=await B$`git config --global user.name`.nothrow().text(),_=await B$`git config --global user.email`.nothrow().text();if(f.trim()==="")console.log("\u274C Git user.name is not set"),console.log("\uD83D\uDD52 Setting git user.name"),await B$`git config --global user.name ${$.name}`,console.log("\u2705 Git user.name set");else console.log(`\u2705 Git user.name is already set to "${f.trim()}"`);if(_.trim()==="")console.log("\u274C Git user.email is not set"),console.log("\uD83D\uDD52 Setting git user.email"),await B$`git config --global user.email ${$.email}`,console.log("\u2705 Git user.email set");else console.log(`\u2705 Git user.email is already set to "${_.trim()}"`);await B$`git config --global url."ssh://git@github.com/".insteadOf "https://github.com/"`,await B$`git config --global merge.ff false`,await B$`git config --global pull.ff true`,await B$`git config --global pull.rebase true`,await B$`git config --global core.whitespace "blank-at-eol,blank-at-eof,space-before-tab,cr-at-eol"`,await B$`git config --global fetch.prune true`,console.log("\u2705 Git config checked and updated.")},Cj=async()=>{let $=`${Bun.env.HOME||Bun.env.USERPROFILE}/.ssh/id_rsa`;if(await Bun.file($).exists())console.log("\u2705 SSH key is set");else throw console.log("\u274C SSH key is not set"),console.log(`\u26A1 Please execute this command:
215
215
 
216
216
  ssh-keygen -t rsa -b 4096 -f ~/.ssh/id_rsa -P ""`),Error("\u274C SSH key is not set")},ij=async()=>{if(await B$`ssh -T -o "StrictHostKeyChecking no" git@github.com 2>&1`.nothrow().text().then(($)=>$.includes("successfully authenticated")))console.log("\u2705 SSH key is set on GitHub");else if(console.log("\u274C SSH key is not set on GitHub"),console.log("\uD83D\uDD52 Adding SSH key to GitHub"),await Bun.file(`${Bun.env.HOME}/.ssh/id_rsa.pub`).exists()){let $=await Bun.file(`${Bun.env.HOME}/.ssh/id_rsa.pub`).text();console.log($),console.log("\u26A1 Go to https://github.com/settings/ssh/new and past the text above")}else console.log("\u274C ~/.ssh/id_rsa.pub not found. Please generate SSH key first.")};var{$:Zj}=globalThis.Bun;var k_=async($)=>{if(process.platform==="win32")return await Zj`powershell.exe -Command "Get-Command ${$}"`.quiet().then((f)=>f.exitCode===0).catch(()=>!1);return(await Zj`which ${$}`.text().catch(()=>"")).trim()!==""},oy=async()=>{return(await Zj`id -u`.text()).trim()==="0"},ty=async()=>{return(await Zj`sudo echo 0`.text().catch(()=>"")).trim()==="0"},aj=async()=>await Bun.file(`${import.meta.dir}/package.json`).json().then(($)=>$.version).catch(()=>"UNKNOWN");var{$:lP}=globalThis.Bun;var L_=($)=>({name:$,check:async()=>k_($),install:async()=>await lP`sudo apt install -y ${$}`}),M3$=[L_("git"),L_("gcc"),L_("make"),L_("curl"),L_("wget"),L_("unzip"),L_("zsh"),L_("bash"),L_("tree")],h$=($,f)=>({name:$,check:async()=>k_(f??$),install:async()=>await lP`brew install ${$}`}),v3$=[h$("aichat"),h$("bpytop"),h$("dive"),h$("dldash/core/docker-color-output","docker-color-output"),h$("docker-compose"),h$("go"),h$("graphviz","dot"),h$("helm"),h$("hyperfine"),h$("kubecolor"),h$("kubectx"),h$("kubernetes-cli","kubectl"),h$("lazygit"),h$("node"),h$("openjdk","javac"),h$("pipx"),h$("zsh")],M$=($,f)=>({name:$,check:async()=>k_(f??$),install:async()=>await lP`bun install --force --global ${$}`}),OY=[M$("@biomejs/biome","biome"),M$("@github/copilot","copilot"),M$("@google/gemini-cli","gemini"),M$("opencode-ai","opencode"),M$("concurrently"),M$("depcheck"),M$("fkill-cli","fkill"),M$("http-server"),M$("live-server"),M$("nodemon"),M$("npm-check-updates"),M$("npm-check"),M$("oxlint"),M$("prettier"),M$("ts-unused-exports"),M$("tsx"),M$("typesync"),M$("ungit")],yy=[...M3$,{name:"uv",check:async()=>k_("uv"),install:async()=>await lP`curl -LsSf https://astral.sh/uv/install.sh | sh`},{name:"brew",check:async()=>k_("brew"),install:async()=>await lP`HOME=/tmp CI=1 bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"`},{name:"deno",check:async()=>k_("deno"),install:async()=>await lP`curl -fsSL https://deno.land/install.sh | sh`},{name:"dotnet",check:async()=>k_("dotnet"),install:async()=>await lP`curl -sSL https://dot.net/v1/dotnet-install.sh | bash -s -- --channel 10.0`},...v3$,...OY];var{$:TY}=globalThis.Bun;var{$:z3$}=globalThis.Bun;var X_=($,f)=>({name:$,check:async()=>await k_(f??$),install:async()=>await z3$`powershell.exe -Command "winget install --id ${$} -e --source winget --accept-package-agreements --accept-source-agreements"`}),D3$=[X_("Git.Git","git"),X_("GoLang.Go","go"),X_("OpenJS.NodeJS","node"),X_("DenoLand.Deno","deno"),X_("JesseDuffield.Lazygit","lazygit"),X_("Microsoft.VisualStudioCode","code"),X_("Kubernetes.kubectl","kubectl"),X_("Helm.Helm","helm"),X_("JanDeDobbeleer.OhMyPosh","oh-my-posh")],Cy=[...D3$,...OY];var h3$=async()=>{console.log("\uD83D\uDD52 Updating system (winget upgrade --all)..."),await TY`winget upgrade --all --accept-package-agreements --accept-source-agreements`.nothrow(),console.log("\uD83D\uDD52 Updating Bun..."),await TY`bun upgrade`.nothrow(),await TY`bun update --latest --force --global`.nothrow(),console.log("\u2705 System updated")},Y3$=async()=>{let $=await Promise.all(Cy.map(async(f)=>({name:f.name,exists:await f.check(),install:f.install}))).then((f)=>f.filter((_)=>!_.exists));if(!$.length)console.log("\u2705 All packages are installed");else{console.log("\u274C Some packages are not installed"),console.table($);for(let f of $)console.log(`\uD83D\uDD52 Installing ${f.name}`),await f.install().then(()=>console.log(`\u2705 Installed ${f.name}`)).catch(()=>console.log(`\u274C Failed to install ${f.name}`))}},iy=async($)=>{console.log("\uD83D\uDD0D Running doctor (Windows)..."),console.log("\u2699\uFE0F email =",$.email,", name =",$.name,", updates =",$.updates),await Y3$(),await yj($);try{await Cj(),await ij()}catch(f){console.log(f)}if($.updates)await h3$();else console.log("\u26A0\uFE0F Skipping system updates");console.log("\u2139\uFE0F Restart your shell for installed packages to be available.")};if(process.platform!=="win32")Bun.env.PATH=[Bun.env.PATH??"","/home/linuxbrew/.linuxbrew/bin","/home/linuxbrew/.linuxbrew/sbin","$BUN_INSTALL/bin","$HOME/go/bin","$HOME/.arkade/bin","${KREW_ROOT:-$HOME/.krew}/bin","$HOME/.cargo/bin","$HOME/.dotnet","$HOME/.dotnet/tools","$HOME/.go/bin","$HOME/.local/bin","$HOME/bin","/snap/bin","/usr/local/sbin","/usr/sbin","/sbin"].join(":");var A3$=async()=>{if(!await oy())console.log("\u2705 You are not root");else throw Error("\u274C You are root")},J3$=async()=>{if(await ty())console.log("\u2705 You can sudo");else throw console.log("\u26A1 Please run this command to configure sudo:"),console.log("sudo sed -i 's/%sudo\\s\\+ALL=(ALL:ALL)\\s\\+ALL/%sudo ALL=(ALL:ALL) NOPASSWD: ALL/g' /etc/sudoers"),Error("\u274C You cannot sudo")},H3$=async()=>{console.log("\uD83D\uDD52 Updating system..."),await v$`sudo apt update -y`.nothrow(),await v$`sudo apt upgrade -y`.nothrow(),await v$`sudo apt autoremove -y`.nothrow(),await v$`sudo apt autoclean -y`.nothrow();let $=(await v$`which brew`.text().catch(()=>"")).trim()||"/home/linuxbrew/.linuxbrew/bin/brew";if(await Bun.file($).exists())await v$`${$} update`.nothrow(),await v$`${$} upgrade`.nothrow(),await v$`${$} cleanup`.nothrow();await v$`bun upgrade`.nothrow(),await v$`bun update --latest --force --global`.nothrow(),console.log("\u2705 System updated")},E3$=async()=>{let $=await Promise.all(yy.map(async(f)=>({name:f.name,exists:await f.check(),install:f.install}))).then((f)=>f.filter((_)=>!_.exists));if(!$.length)console.log("\u2705 All packages are installed");else{console.log("\u274C Some packages are not installed"),console.table($);for(let f of $)console.log(`\uD83D\uDD52 Installing ${f.name}`),await f.install().then(()=>console.log(`\u2705 Installed ${f.name}`)).catch(()=>console.log(`\u274C Failed to install ${f.name}`))}},n3$=async()=>{let f=await Promise.all([".bashrc",".zshrc",".aliases",".profile"].map(async(_)=>({name:_,content:await fetch(`https://raw.githubusercontent.com/chneau/dotfiles/HEAD/${_}`).then((P)=>P.text()),isPresent:await Bun.file(`${Bun.env.HOME}/${_}`).exists()})));if(f.every((_)=>_.isPresent))console.log("\u2705 Dotfiles are installed");else console.log("\u274C Dotfiles are not installed"),console.log("\uD83D\uDD52 Installing dotfiles"),await Promise.all(f.map(async(_)=>{console.log(`\uD83D\uDD52 Installing ${_.name}`),await Bun.write(`${Bun.env.HOME}/${_.name}`,_.content),console.log(`\u2705 Installed ${_.name}`)})),console.log("\u2705 Dotfiles are installed")},S3$=async()=>{if(!(await v$`which docker`.nothrow().text()).includes("not found"))console.log("\u2705 Docker is installed");else console.log("\u274C Docker is not installed"),console.log("\uD83D\uDD52 Installing Docker"),await v$`curl -sSL get.docker.com | sh`,console.log("\u2705 Docker is installed")},N3$=async()=>{if((await v$`groups`.text()).includes("docker"))console.log("\u2705 User is in docker groups");else console.log("\u274C User is not in docker groups"),console.log("\uD83D\uDD52 Adding user to docker groups"),await v$`sudo usermod -aG docker $USER`.catch(()=>{}),console.log("\u2705 User is in docker groups")},u3$=async()=>{let $=await Bun.file("/etc/shells").text().then((P)=>P.split(`
217
- `)),f=await v$`which zsh`.nothrow().text();if($.includes(f))console.log("\u2705 Zsh is set as a valid shell");else console.log("\u274C Zsh is not set as a valid shell"),console.log("\uD83D\uDD52 Adding Zsh to /etc/shells"),await v$`echo ${f} | sudo tee -a /etc/shells`,console.log("\u2705 Zsh is set as a valid shell");if((await v$`cat /etc/passwd | grep "^$USER:"`.text()).includes(f))console.log("\u2705 Zsh is set as your shell");else console.log("\u274C Zsh is not set as your shell"),console.log("\uD83D\uDD52 Setting Zsh as your shell"),await v$`sudo chsh -s ${f} $USER`,console.log("\u2705 Zsh is set as your shell")},L3$=async($)=>{if(console.log("\uD83D\uDD0D Running doctor (Linux)..."),console.log("\u2699\uFE0F email =",$.email,", name =",$.name,", updates =",$.updates),await Promise.all([A3$(),J3$()]),await Promise.all([n3$(),E3$().then(()=>Promise.all([yj($).then(Cj).then(ij),u3$(),S3$().then(N3$)]))]),$.updates)await H3$();else console.log("\u26A0\uFE0F Skipping system updates")},Zy=async($)=>{if($=Vy.parse($),process.platform==="win32")await iy($);else await L3$($)};var{$:jY}=globalThis.Bun;var ay=async()=>void await Promise.all([jY`deno fmt --use-tabs --quiet; oxlint --fix-dangerously --quiet; biome check --write --unsafe .`.nothrow(),jY`go fmt ./...`.nothrow(),jY`dotnet csharpier .`.nothrow()]);var{$:xj}=globalThis.Bun;var xy=async()=>{await xj`bun init -y .`,await xj`x`;let $=await Bun.file("package.json").json();delete $.module,delete $.type,delete $.private,$.devDependencies={...$.devDependencies,...$.peerDependencies},delete $.peerDependencies;let f=$.devDependencies;delete $.devDependencies,$.scripts={start:"bun index.ts",dev:"bun --watch index.ts",...$.scripts},$.dependencies={},$.devDependencies=f,await xj`bun run all`,await xj`echo node_modules > .gitignore`};var{$:X3$}=globalThis.Bun;var dy=async()=>await fetch("https://registry.npmjs.org/@chneau/x/latest").then(($)=>$.json().then((f)=>f.version)).catch(()=>"UNKNOWN");var Gy=async()=>{let $=await dy(),f=await aj();if($===f){console.log(`\u2705 You are already using the latest version ${f}`);return}console.log(`\uD83D\uDD52 You are using version ${f}`);while(!0){if(console.log(`\uD83D\uDD52 Updating to version ${$}`),await X3$`bun i -fg @chneau/x@${$}`.quiet().then(()=>!0).catch(()=>!1))break;await Bun.sleep(1000)}console.log(`\u2705 Updated to version ${$}`)};var W3$=await aj();a$.name("x").description("chneau's utility CLI").version(W3$);a$.option("-r, --recursive [number]","Recursion level",Number.parseFloat).argument("[dir]","Directory to manage",".").action(ZY);a$.command("fmt").description("Format all files").action(ay);a$.command("deploy").description("Deploy to kubernetes").allowExcessArguments().action(Ry);a$.command("upgrade").description("Uprade x to the latest version").action(Gy);a$.command("doctor").description("Check the system for issues").option("-e, --email <email>","Git email","charles63500@gmail.com").option("-n, --name <name>","Git name","chneau").option("--no-updates","Skip system updates").action(Zy);a$.command("new").description("Create new bun project").action(xy);a$.parse();
217
+ `)),f=await v$`which zsh`.nothrow().text();if($.includes(f))console.log("\u2705 Zsh is set as a valid shell");else console.log("\u274C Zsh is not set as a valid shell"),console.log("\uD83D\uDD52 Adding Zsh to /etc/shells"),await v$`echo ${f} | sudo tee -a /etc/shells`,console.log("\u2705 Zsh is set as a valid shell");if((await v$`cat /etc/passwd | grep "^$USER:"`.text()).includes(f))console.log("\u2705 Zsh is set as your shell");else console.log("\u274C Zsh is not set as your shell"),console.log("\uD83D\uDD52 Setting Zsh as your shell"),await v$`sudo chsh -s ${f} $USER`,console.log("\u2705 Zsh is set as your shell")},L3$=async($)=>{if(console.log("\uD83D\uDD0D Running doctor (Linux)..."),console.log("\u2699\uFE0F email =",$.email,", name =",$.name,", updates =",$.updates),await Promise.all([A3$(),J3$()]),await Promise.all([n3$(),E3$().then(()=>Promise.all([yj($).then(Cj).then(ij),u3$(),S3$().then(N3$)]))]),$.updates)await H3$();else console.log("\u26A0\uFE0F Skipping system updates")},Zy=async($)=>{if($=Vy.parse($),process.platform==="win32")await iy($);else await L3$($)};var{$:jY}=globalThis.Bun;var ay=async()=>void await Promise.all([jY`deno fmt --use-tabs --quiet; oxlint --fix-dangerously --quiet; biome check --write --unsafe .`.nothrow(),jY`go fmt ./...`.nothrow(),jY`dotnet csharpier .`.nothrow()]);var{$:xj}=globalThis.Bun;var xy=async()=>{await xj`bun init -y .`,await xj`x`;let $=await Bun.file("package.json").json();delete $.module,delete $.type,delete $.private,$.devDependencies={...$.devDependencies,...$.peerDependencies},delete $.peerDependencies;let f=$.devDependencies;delete $.devDependencies,$.scripts={start:"bun index.ts",dev:"bun --watch index.ts",...$.scripts},$.dependencies={},$.devDependencies=f,await Bun.write("package.json",JSON.stringify($,null,2)),await xj`bun run all`,await xj`echo node_modules > .gitignore`};var{$:X3$}=globalThis.Bun;var dy=async()=>await fetch("https://registry.npmjs.org/@chneau/x/latest").then(($)=>$.json().then((f)=>f.version)).catch(()=>"UNKNOWN");var Gy=async()=>{let $=await dy(),f=await aj();if($===f){console.log(`\u2705 You are already using the latest version ${f}`);return}console.log(`\uD83D\uDD52 You are using version ${f}`);while(!0){if(console.log(`\uD83D\uDD52 Updating to version ${$}`),await X3$`bun i -fg @chneau/x@${$}`.quiet().then(()=>!0).catch(()=>!1))break;await Bun.sleep(1000)}console.log(`\u2705 Updated to version ${$}`)};var W3$=await aj();a$.name("x").description("chneau's utility CLI").version(W3$);a$.option("-r, --recursive [number]","Recursion level",Number.parseFloat).argument("[dir]","Directory to manage",".").action(ZY);a$.command("fmt").description("Format all files").action(ay);a$.command("deploy").description("Deploy to kubernetes").allowExcessArguments().action(Ry);a$.command("upgrade").description("Uprade x to the latest version").action(Gy);a$.command("doctor").description("Check the system for issues").option("-e, --email <email>","Git email","charles63500@gmail.com").option("-n, --name <name>","Git name","chneau").option("--no-updates","Skip system updates").action(Zy);a$.command("new").description("Create new bun project").action(xy);a$.parse();