@stacksjs/launchpad
Version:
Like Homebrew, but faster.
9 lines (8 loc) • 13.5 kB
JavaScript
// @bun
import"./chunk-8pxdwzvm.js";var{semver:zf}=globalThis.Bun;import{readdirSync as Of,readFileSync as i,statSync as _}from"fs";import{homedir as Qf}from"os";import{join as j,resolve as Xf}from"path";import P from"process";function D(f){return Object.prototype.toString.call(f).slice(8,-1)}function b(f){return D(f)==="Array"}function M(f){if(D(f)!=="Object")return!1;let N=Object.getPrototypeOf(f);return!!N&&N.constructor===Object&&N===Object.prototype}function R(f){return D(f)==="String"}function d(f){return D(f)==="Number"&&!isNaN(f)}function Nf(f){return D(f)==="Null"}function Tf(f,N,Q,E,X){return($)=>f($)||N($)||!!Q&&Q($)||!!E&&E($)||!!X&&X($)}function Uf(f){return D(f)==="Undefined"}var Ff=Tf(Nf,Uf);class Y{range;constructor(f){this.range=f}toString(){return this.range}satisfies(f){return zf.satisfies(f,this.range)}}class x{string;constructor(f){this.string=Xf(f)}isDirectory(){try{return _(this.string).isDirectory()}catch{return!1}}async read(){return i(this.string,"utf8")}async readYAML(){let f=await this.read();return m(f)}async readYAMLAll(){return(await this.read()).split(/^---$/m).map((Q)=>m(Q.trim())).filter(Boolean)}async*ls(){try{let f=Of(this.string,{withFileTypes:!0});for(let N of f)yield[new x(j(this.string,N.name)),{name:N.name,isFile:N.isFile(),isSymlink:N.isSymbolicLink(),isDirectory:N.isDirectory()}]}catch{}}static home(){return new x(Qf())}}function m(f){try{if(f.trim().startsWith("{"))return JSON.parse(f);let N=f.split(`
`),Q={},E=[{obj:Q,key:null,indent:-1}];for(let X of N){let $=X.trim();if(!$||$.startsWith("#"))continue;let K=X.length-X.trimStart().length;while(E.length>1&&E[E.length-1].indent>=K)E.pop();let G=E[E.length-1];if($.startsWith("- ")){let A=$.substring(2).trim(),B=null,q=null;for(let w=E.length-1;w>=0;w--){let F=E[w];if(F.indent<K){let S=Object.keys(F.obj),u=S[S.length-1];if(u){B=u,q=F.obj;break}}}if(B&&q){if(!Array.isArray(q[B]))q[B]=[];q[B].push(A)}continue}let z=$.indexOf(":");if(z>0){let A=$.substring(0,z).trim(),B=$.substring(z+1).trim(),q=B.indexOf("#");if(q>=0)B=B.substring(0,q).trim();let w=B.replace(/^["']|["']$/g,"");if(w==="")G.obj[A]={},E.push({obj:G.obj[A],key:null,indent:K});else{let F=w;if(w==="true")F=!0;else if(w==="false")F=!1;else if(w==="null")F=null;else if(/^\d+$/.test(w))F=Number.parseInt(w,10);else if(/^\d+\.\d+$/.test(w))F=Number.parseFloat(w);G.obj[A]=F}}}return Q}catch{return{}}}function Zf(f){try{let N=f.replace(/\/\*[\s\S]*?\*\/|\/\/.*$/gm,"");return JSON.parse(N)}catch{return{}}}function y(f,N="explicit"){let Q=f.lastIndexOf("@");if(Q>0){let E=f.substring(0,Q),X=f.substring(Q+1);return{project:E,constraint:new Y(X),source:N}}return{project:f,constraint:new Y("*"),source:N}}function h(f,N,Q="explicit"){try{return{project:f,constraint:new Y(N),source:Q}}catch{return}}async function*$f(f){try{let Q=i(f,"utf8").split(`
`);for(let E of Q)yield E}catch{}}var c=new Map,g=new Map,Bf=5000;function Hf(){let f=Date.now();for(let[N,Q]of g)if(f-Q>Bf)c.delete(N),g.delete(N)}function Jf(f){Hf();let N=c.get(f);if(N!==void 0)return N;return}function wf(f,N){c.set(f,N),g.set(f,Date.now())}async function Gf(f){let N=f instanceof x?f:new x(f.string);if(!N.isDirectory())throw new Error(`not a directory: ${N.string}`);let Q=Jf(N.string);if(Q!==void 0)return Q?JSON.parse(Q):{pkgs:[],env:{},services:void 0};let E=new Y("*"),X=!1,$=!1,K=!1,G=!1,z=[],A={},B;for await(let[W,{name:T,isFile:U,isSymlink:O,isDirectory:Z}]of N.ls())if(U||O)switch(T){case"deno.json":case"deno.jsonc":await n(W);break;case".nvmrc":case".node-version":await o(W,"nodejs.org");break;case".ruby-version":await o(W,"ruby-lang.org");break;case".python-version":await s(W);break;case".terraform-version":await t(W);break;case"package.json":await a(W);break;case"action.yml":case"action.yaml":await ff(W);break;case"Cargo.toml":z.push({project:"rust-lang.org",constraint:E,source:"inferred"}),await I(W);break;case"skaffold.yaml":z.push({project:"skaffold.dev",constraint:E,source:"inferred"}),await e(W);break;case"go.mod":case"go.sum":z.push({project:"go.dev",constraint:E,source:"inferred"}),await I(W);break;case"requirements.txt":case"pipfile":case"pipfile.lock":case"setup.py":z.push({project:"pip.pypa.io",constraint:E,source:"inferred"}),await I(W);break;case"pyproject.toml":await Wf(W);break;case"Gemfile":z.push({project:"ruby-lang.org",constraint:E,source:"inferred"}),await I(W);break;case".yarnrc":z.push({project:"classic.yarnpkg.com",constraint:E,source:"inferred"}),await I(W);break;case"yarn.lock":z.push({project:"yarnpkg.com",constraint:E,source:"inferred"});break;case".yarnrc.yml":z.push({project:"yarnpkg.com",constraint:E,source:"inferred"}),await I(W);break;case"bun.lock":case"bun.lockb":$=!0,z.push({project:"bun.sh",constraint:new Y(">=1"),source:"inferred"});break;case"pnpm-lock.yaml":G=!0,z.push({project:"pnpm.io",constraint:E,source:"inferred"});break;case"pixi.toml":z.push({project:"prefix.dev",constraint:E,source:"inferred"}),await I(W);break;case"dependencies.yaml":case"dependencies.yml":case".dependencies.yml":case".dependencies.yaml":case"deps.yml":case"deps.yaml":case".deps.yml":case".deps.yaml":case"pkgx.yaml":case"pkgx.yml":case".pkgx.yml":case".pkgx.yaml":case"launchpad.yaml":case"launchpad.yml":case".launchpad.yml":case".launchpad.yaml":K=!0,await C(await W.readYAML());break;case"cdk.json":z.push({project:"aws.amazon.com/cdk",constraint:E,source:"inferred"});break;case"justfile":case"Justfile":z.push({project:"just.systems",constraint:E,source:"inferred"});break;case"Taskfile.yml":z.push({project:"taskfile.dev",constraint:E,source:"inferred"});break;case"uv.lock":z.push({project:"astral.sh/uv",constraint:E,source:"inferred"});break}else if(Z)switch(T){case".git":if(P.platform!=="darwin")z.push({project:"git-scm.org",constraint:E,source:"inferred"});break;case".hg":z.push({project:"mercurial-scm.org",constraint:E,source:"inferred"});break;case".svn":z.push({project:"apache.org/subversion",constraint:E,source:"inferred"});break}if(G&&!z.some((W)=>W.project==="pnpm.io"||W.project==="pnpm"))z.push({project:"pnpm.io",constraint:E,source:"inferred"});let q=z.some((W)=>{return W.project==="bun.sh"||W.project==="bun.com"||W.project==="bun"||W.project==="nodejs.org"||W.project==="node"||W.project==="deno.land"||W.project==="deno.com"||W.project==="deno"||W.project.includes("bun")||W.project.includes("nodejs")||W.project.includes("deno")});if(X&&!q&&!$&&!K){let W=new Y("^22");z.push({project:"nodejs.org",constraint:W,source:"inferred"})}let w=new Map,F=new Map;for(let W of z){let T=F.get(W.project)||[];T.push(W),F.set(W.project,T)}for(let[W,T]of F){let U=T.filter((J)=>J.source==="explicit"),O=T.filter((J)=>J.source==="inferred"),Z;if(U.length>0)Z=U.reduce((J,H)=>{let L=J.constraint.toString(),V=H.constraint.toString(),v=/^\d+\.\d+(?:\.\d+)?$/.test(L);if(/^\d+\.\d+(?:\.\d+)?$/.test(V)&&!v)return H;if(L==="*"&&V!=="*")return H;return J});else if(O.length>0)Z=O.reduce((J,H)=>{let L=J.constraint.toString(),V=H.constraint.toString(),v=/^\d+\.\d+(?:\.\d+)?$/.test(L);if(/^\d+\.\d+(?:\.\d+)?$/.test(V)&&!v)return H;if(L==="*"&&V!=="*")return H;return J});else Z=T[0];w.set(W,Z)}let S=Array.from(w.values());if(!B?.enabled&&l()){let W=await p(N.string);if(W.autoStart.length>0)B={enabled:!0,autoStart:W.autoStart}}let u={pkgs:S,env:A,services:B};return wf(N.string,JSON.stringify(u)),u;async function n(W){z.push({project:"deno.land",constraint:E,source:"inferred"});let T=Zf(await W.read());if(M(T)&&T.pkgx){let U=T.pkgx;if(R(U)||b(U))U={dependencies:U};await C(U)}}async function o(W,T){let U=(await W.read()).trim();if(U.startsWith("v"))U=U.slice(1);if(U.match(/^\d/))U=`@${U}`;U=`${T}${U}`,z.push(y(U,"inferred"))}async function s(W){let U=(await W.read()).trim().split(`
`);for(let O of U){if(O=O.trim(),!O)continue;if(O.startsWith("#"))continue;O=`python.org@${O}`;try{z.push(y(O,"inferred"));break}catch{}}}async function t(W){let U=`terraform.io@${(await W.read()).trim()}`;z.push(y(U,"inferred"))}async function a(W){let T=JSON.parse(await W.read()),U={};if(T?.engines){if(T.engines.node)U["nodejs.org"]=T.engines.node;if(T.engines.npm)U["npmjs.com"]=T.engines.npm;if(T.engines.yarn)U["yarnpkg.com"]=T.engines.yarn;if(T.engines.pnpm)U["pnpm.io"]=T.engines.pnpm,G=!0}if(T?.packageManager){let Z=T.packageManager.match(/^(?<pkg>[^@]+)@(?<version>[^+]+)/);if(Z){let{pkg:J,version:H}=Z.groups;switch(J){case"npm":U["npmjs.com"]=H;break;case"yarn":U["yarnpkg.com"]=H;break;case"pnpm":G=!0,U["pnpm.io"]=H;break}}}if(T?.volta){if(T.volta.node)U["nodejs.org"]=T.volta.node;if(T.volta.npm)U["npmjs.com"]=T.volta.npm;if(T.volta.yarn)U["yarnpkg.com"]=T.volta.yarn;if(T.volta.pnpm)U["pnpm.io"]=T.volta.pnpm,G=!0}let O=T?.pkgx;if(R(O)||b(O))O={dependencies:O};if(O?.dependencies){if(M(O.dependencies))Object.assign(U,O.dependencies)}if(Object.keys(U).length>0)for(let[Z,J]of Object.entries(U))try{let H=J;if(H.endsWith("@latest"))H=H.slice(0,-6);if(/^@?latest$/.test(H))H="*";let L=h(Z,H,"inferred");if(L)z.push(L)}catch{}if(O&&(O.dependencies||O.env))await C(O);X=!0}async function e(W){let T=await W.readYAMLAll(),U=[];for(let Z of T){if(!M(Z))continue;if(Z.build?.local?.useDockerCLI?.toString()==="true"||Z.deploy?.docker)U.push({project:"docker.com/cli",constraint:new Y("*"),source:"inferred"});if(Z.deploy?.kubectl)U.push({project:"kubernetes.io/kubectl",constraint:new Y("*"),source:"inferred"});if(Z.deploy?.kubeContext?.match("minikube"))U.push({project:"kubernetes.io/minikube",constraint:new Y("*"),source:"inferred"});if(Z.deploy?.helm||Z.manifests?.helm)U.push({project:"helm.sh",constraint:new Y("*"),source:"inferred"});if(Z.deploy?.kpt||Z.manifests?.kpt)U.push({project:"kpt.dev",constraint:new Y("*"),source:"inferred"});if(Z.manifests?.kustomize)U.push({project:"kubernetes.io/kustomize",constraint:new Y("*"),source:"inferred"})}let O=Array.from(new Map(U.map((Z)=>[Z.project,Z])).values());z.push(...O)}async function ff(W){let T=await W.readYAML();if(!M(T))return;let U=T.runs?.using?.match(/node(\d+)/);if(U?.[1])z.push({project:"nodejs.org",constraint:new Y(`^${U?.[1]}`),source:"inferred"});await C(T.pkgx)}async function Wf(W){let T=await W.read();if(z.push({project:"python.org",constraint:E,source:"inferred"}),T.includes("poetry.core.masonry.api"))z.push({project:"python-poetry.org",constraint:E,source:"inferred"});else z.push({project:"pip.pypa.io",constraint:E,source:"inferred"});await I(W)}async function I(W){let T;for await(let U of $f(W.string))if(T!==void 0){if(/^(?:(?:#|\/\/)\s*)?---(?:\s*\*\/)?$/.test(U.trim())){let O=m(T);if(M(O)&&O.pkgx)O=R(O.pkgx)||b(O.pkgx)?{dependencies:O.pkgx}:O.pkgx;return await C(O)}T+=U?.replace(/^(#|\/\/)/,""),T+=`
`}else if(/^(?:(?:\/\*|#|\/\/)\s*)?---/.test(U.trim()))T=""}async function C(W){if(!M(W))return;let T=await Kf(W);for(let[Z,J]of Object.entries(T.env)){if(d(J))J=J.toString();if(R(J))A[Z]=O(J)}if(z.push(...T.deps),T.services)B=T.services;if((W.services?.infer===!0||W.inferServices===!0||W.framework===!0)&&l()){if(!B||!B.enabled){let Z=await p(N.string);if(Z.autoStart.length>0)B={enabled:!0,autoStart:Z.autoStart}}}function O(Z){let J=[{from:"{{home}}",to:x.home().string},{from:"{{srcroot}}",to:N.string}],H=Z;for(let{from:L,to:V}of J)H=H.replace(new RegExp(L,"g"),V);return r(H),H}}}function l(){let f=P.env.LAUNCHPAD_FRAMEWORKS_ENABLED!=="false",N=P.env.LAUNCHPAD_SERVICES_INFER!=="false",Q=P.env.LAUNCHPAD_LARAVEL_ENABLED!=="false",E=P.env.LAUNCHPAD_STACKS_ENABLED!=="false";return f&&N&&(Q||E)}async function p(f){let N=[];try{let Q=j(f,"artisan"),E=j(f,"buddy"),X=j(f,".env"),$=(()=>{try{return _(Q).isFile()}catch{return!1}})(),K=(()=>{try{return _(E).isFile()}catch{return!1}})(),G=_(X).isFile();if(!($||K)||!G)return{autoStart:N};let z=i(X,"utf8"),A=k(z,"DB_CONNECTION"),B=k(z,"CACHE_STORE")||k(z,"CACHE_DRIVER");if(A==="pgsql"||A==="postgres"||A==="postgresql")N.push("postgres");else if(A==="mysql"||A==="mariadb")N.push("mysql");if(B==="redis")N.push("redis");else if(B==="memcached")N.push("memcached")}catch{}return{autoStart:Array.from(new Set(N))}}function k(f,N){let Q=f.split(`
`);for(let E of Q){let X=E.trim();if(!X||X.startsWith("#"))continue;let $=X.indexOf("=");if($===-1)continue;if(X.substring(0,$).trim()!==N)continue;let G=X.substring($+1).trim();return G=G.replace(/^['"]|['"]$/g,""),G}return}function r(f){let N=0;while(!0){let Q=f.indexOf("$",N);if(Q===-1)break;N=Q;let E=f.substring(N),X=/^\$\{[A-Z_]\w*\}/i.test(E),$=/^\$[A-Z_]\w*/i.test(E);if(!X&&!$)throw new Error("Invalid dollar sign usage detected.");N++}}function Kf(f){let N=f.global===!0||f.global==="true",Q=Af(f.dependencies,N),E=M(f.env)?f.env:{},X;if(M(f.services))X={enabled:f.services.enabled===!0,autoStart:Array.isArray(f.services.autoStart)?f.services.autoStart:void 0};return{deps:Q,env:E,services:X}}function Af(f,N=!1){if(R(f))f=f.split(/\s+/).filter((E)=>E);function Q(E){if(E.endsWith("@latest"))E=E.slice(0,-6);return y(E,"explicit")}if(b(f))f=f.map((E)=>Q(E)).reduce((E,X)=>{return E[X.project]=X.constraint.toString(),E},{});if(!M(f))return[];return Object.entries(f).map(([E,X])=>{if(M(X)){let K=X,G=K.version||"*",A=K.global===!0||K.global==="true"||K.global===!1||K.global==="false"?K.global===!0||K.global==="true":N;if(/^@?latest$/.test(G)){let w=h(E,"*","explicit");return w?{...w,global:A}:null}let B=h(E,G,"explicit");return B?{...B,global:A}:null}if(/^@?latest$/.test(X))X="*";let $=h(E,X,"explicit");return $&&N?{...$,global:N}:$}).filter(Boolean)}var Rf={validateDollarSignUsage:r};export{Gf as default,Rf as _internals,Y as SemverRange};
export{Gf as u};