canopy-engine 0.1.8 → 0.1.9
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/LICENSE +4 -3
- package/PRIVACY.md +6 -6
- package/README.md +242 -241
- package/dist/canopy.js +66 -65
- package/dist/chunk-4RMLGRCG.js +12 -0
- package/dist/{chunk-ZE3NJMCS.js → chunk-HDMHITMG.js} +1 -1
- package/dist/chunk-K7XFTTX2.js +5 -0
- package/dist/chunk-T3YCNXUR.js +28 -0
- package/dist/{chunk-4XUKEJ3C.js → chunk-U6RT2XM5.js} +1 -1
- package/dist/chunk-YC3GSAN3.js +5 -0
- package/package.json +6 -4
- package/ui-react/dist/bundle.js +45 -45
- package/dist/chunk-AGOP4Q7U.js +0 -12
- package/dist/chunk-B5D2E2HN.js +0 -5
- package/dist/chunk-DT3LR6DW.js +0 -25
- package/dist/chunk-F535OXGZ.js +0 -5
package/dist/canopy.js
CHANGED
|
@@ -3,99 +3,99 @@ import{fileURLToPath as __cf,pathToFileURL as __cu}from"node:url";import{dirname
|
|
|
3
3
|
const require=__cr(import.meta.url);
|
|
4
4
|
globalThis.__canopyBundle??=__cj(__cd(__cf(import.meta.url)),"canopy.js");
|
|
5
5
|
globalThis.__canopyUrl??=(r)=>__cu(__cj(__cd(__cd(globalThis.__canopyBundle)),r)).href;
|
|
6
|
-
import{a as go,b as yo,d as vo,e as wo,g as xo}from"./chunk-Y3GNG3XL.js";import{
|
|
7
|
-
`,o),c=(i<0?s.length:i)-o;if(c>r&&(r=c),i<0)break;o=i+1}if(r>Fn)return{kind:"minified",reason:`line of ${r.toLocaleString("en-US")} characters (limit ${Fn.toLocaleString("en-US")}; minified/bundled)`}}return null}function jt(e,t=["javascript","typescript"]){let n=t.flatMap(y=>(y==="typescript"?
|
|
8
|
-
`)}function
|
|
9
|
-
`))}import Wn from"node:path";function Zt(e){let t=Wn.resolve(e),n=t.split(Wn.sep).join("/"),s=[[t.toLowerCase(),t.length,Wn.sep],[n.toLowerCase(),n.length,"/"]],o=Math.max(s[0][1],s[1][1])+1,r=i=>{if(typeof i!="string")return i;let c=i.length>o?i.slice(0,o).toLowerCase():i.toLowerCase();if(c===s[0][0]||c===s[1][0])return".";for(let[a,l,f]of s)if(c.startsWith(a+f)){let y=i.slice(l+1),u=y.indexOf("::");return(u<0?y:y.slice(0,u)).split("\\").join("/")+(u<0?"":y.slice(u))}return i};return{rel:r,repoRoot:n,replacer:(i,c)=>typeof c=="string"?r(c):c,json:(i,c)=>JSON.stringify(i,(a,l)=>typeof l=="string"?r(l):l,c),walk:i=>Xt(i,r),clone:i=>{try{return JSON.parse(JSON.stringify(i,(c,a)=>typeof a=="string"?r(a):a))}catch(c){if(!(c instanceof RangeError))throw c;return Xt(i,r)}}}}function Xt(e,t){if(typeof e=="string")return t(e);if(Array.isArray(e))return e.map(n=>Xt(n===void 0||typeof n=="function"?null:n,t));if(e&&typeof e=="object"){let n={};for(let s of Object.keys(e)){let o=e[s];o!==void 0&&typeof o!="function"&&(n[s]=Xt(o,t))}return n}return e}function Ss(e){let t=e.map((s,o)=>({e:s,i:o})).sort((s,o)=>String(s.e.fromNodeId).localeCompare(String(o.e.fromNodeId))||(s.e.line??0)-(o.e.line??0)||(s.e.column??0)-(o.e.column??0)||s.i-o.i),n=new Map;for(let{e:s}of t){let o=s.calleeNameRaw??s.eventName??s.url??"",r=`${s.fromNodeId??"\u2205"} | ${s.callKind??s.type} | ${o}`,i=(n.get(r)??0)+1;n.set(r,i),s.id=`${r} | #${i}`}return e}function bs(e){let t=new Map;for(let n of e)t.has(n.id)||t.set(n.id,[]),t.get(n.id).push(n);for(let[n,s]of t)s.length<2||(s.sort((o,r)=>o.startLine-r.startLine||o.endLine-r.endLine),s.forEach((o,r)=>{r>0&&(o.id=`${n}#${r+1}`)}));return e}function ce(e,t){let n=null;for(let s of t)s.type!=="moduleRoot"&&e>=s.startLine&&e<=s.endLine&&(!n||s.endLine-s.startLine<n.endLine-n.startLine)&&(n=s);return n||t.find(s=>s.type==="moduleRoot")}function $s(e,t){let n=[];for(let[o,r]of e){let i=t.filter(c=>c.filePath===o);for(let c of r.calls){let a=ce(c.startLine,i);n.push({fromFileId:o,fromNodeId:a?.id??null,calleeNameRaw:c.calleeName,line:c.startLine,column:c.startColumn,branchPath:c.branchPath??[],firstArgText:c.firstArgText??null,deferred:c.deferred??!1,type:"call",callKind:c.callKind??"call",resolved:!1})}for(let c of r.methodCalls){let a=ce(c.startLine,i);n.push({fromFileId:o,fromNodeId:a?.id??null,calleeNameRaw:c.methodName,objectNameRaw:c.objectName,line:c.startLine,column:c.startColumn,branchPath:c.branchPath??[],firstArgText:c.firstArgText??null,deferred:c.deferred??!1,type:"methodCall",callKind:c.callKind??"methodCall",resolved:!1})}for(let c of r.returnEntries??[]){let a=ce(c.startLine,i);n.push({fromFileId:o,fromNodeId:a?.id??null,calleeNameRaw:c.label,line:c.startLine,column:c.startColumn,branchPath:c.branchPath??[],deferred:c.deferred??!1,type:"returnValue",resolved:!1})}for(let c of r.jsxElements){let a=ce(c.startLine,i);n.push({fromFileId:o,fromNodeId:a?.id??null,calleeNameRaw:c.calleeName,line:c.startLine,type:"call",callKind:"jsx",resolved:!1})}for(let c of r.callSites??[]){let a=ce(c.startLine,i);n.push({fromFileId:o,fromNodeId:a?.id??null,calleeNameRaw:c.calleeName,line:c.startLine,column:c.startColumn,branchPath:c.branchPath??[],firstArgText:c.firstArgText??null,deferred:c.deferred??!1,type:"callSite",callKind:c.callKind,chainHead:c.chainHead??null,chainHeadCalled:c.chainHeadCalled??!1,ctorName:c.ctorName??null,...c.thisProp?{thisProp:c.thisProp,thisMethod:c.thisMethod}:{},resolved:!1})}for(let c of r.socketEmits){let a=ce(c.startLine,i);n.push({fromFileId:o,fromNodeId:a?.id??null,eventName:c.eventName,line:c.startLine,type:"socketEmit",resolved:!1})}for(let c of r.rawSocketSends??[]){let a=ce(c.startLine,i);n.push({fromFileId:o,fromNodeId:a?.id??null,eventName:c.eventName,line:c.startLine,type:"rawSocketSend",resolved:!1})}for(let c of r.apiCalls){let a=ce(c.startLine,i);n.push({fromFileId:o,fromNodeId:a?.id??null,url:c.url,httpMethod:c.method,scope:c.scope,line:c.startLine,type:"apiCall",resolved:!1})}}let s=n.filter(o=>o.type==="apiCall").length;return n}function fe(e,t){let n=new Map;for(let s of t)s.filePath===e&&n.set(s.name,s.id);return n}function Et(e,t,n,s,o=null){if(n.has(e.calleeNameRaw))return{...e,targetNodeId:n.get(e.calleeNameRaw),confidence:.95,matchType:"local",resolved:!0};let r=[...s],i=s.legacySize??r.length,c=([,l])=>{let f=o?o.scopeOf(l):fe(l,t);return f.has(e.calleeNameRaw)?{...e,targetNodeId:f.get(e.calleeNameRaw),confidence:.85,matchType:"import",resolved:!0}:null};for(let l=0;l<i;l++){let f=c(r[l]);if(f)return f}let a=o?.bind?.resolveName(e.fromFileId,e.calleeNameRaw);if(a)return{...e,targetNodeId:a.id,confidence:.85,matchType:"import",resolved:!0};for(let l=i;l<r.length;l++){let f=c(r[l]);if(f)return f}return{...e,targetNodeId:null,confidence:0,matchType:"unresolved",resolved:!1}}function Ns(e,t,n=null){let s=n?n.method(e.objectNameRaw,e.calleeNameRaw):t.find(r=>r.type==="classMethod"&&r.className===e.objectNameRaw&&r.name===e.calleeNameRaw);if(s)return{...e,targetNodeId:s.id,confidence:.6,matchType:"methodHeuristic",resolved:!0};let o=n?.bind?.resolveMember(e.fromFileId,e.objectNameRaw,e.calleeNameRaw);return o?{...e,targetNodeId:o.id,confidence:.85,matchType:"import",resolved:!0}:{...e,targetNodeId:null,confidence:0,matchType:"unresolved",resolved:!1}}function Is(e){return{...e,targetNodeId:null,confidence:0,matchType:"unresolvedExternal",resolved:!1}}function js(e,t,n,s,o=null){if(e.callKind==="new"&&e.ctorName){let r=Et({...e,calleeNameRaw:e.ctorName},t,n,s,o);if(r.resolved)return{...r,calleeNameRaw:e.calleeNameRaw,matchType:r.matchType+"New"};let i=new Set([e.fromFileId,...s.values()]),c=o?o.ctorsOf(e.ctorName).find(a=>i.has(a.filePath)):t.find(a=>a.type==="classMethod"&&a.className===e.ctorName&&a.name==="constructor"&&i.has(a.filePath));return c?{...e,targetNodeId:c.id,confidence:c.filePath===e.fromFileId?.9:.8,matchType:(c.filePath===e.fromFileId?"local":"import")+"New",resolved:!0}:Is(e)}if(e.callKind==="chainedCall"&&e.chainHead&&e.chainHeadCalled){let r=Et({...e,calleeNameRaw:e.chainHead},t,n,s,o);if(r.resolved)return{...e,targetNodeId:r.targetNodeId,confidence:r.confidence*.8,matchType:"chainHead",resolved:!0}}return Is(e)}import qn from"node:path";import qe from"node:fs";import Y from"node:path";var _s=[".ts",".tsx",".mts",".cts",".js",".jsx",".mjs",".cjs"],Cc=["index.ts","index.tsx","index.mts","index.cts","index.js","index.jsx","index.mjs","index.cjs"],Rc={".js":[".ts",".tsx"],".jsx":[".tsx"],".mjs":[".mts"],".cjs":[".cts"]};var Ls=null,Ps=e=>{Ls=e},Ms=()=>Ls,Es=e=>Y.resolve(e);function Ct(e,t){e=Y.resolve(e);let n=()=>{try{let i=Y.join(e,"package.json");if(!qe.existsSync(i))return null;let c=JSON.parse(qe.readFileSync(i,"utf8")).main;if(typeof c!="string")return null;let a=Y.resolve(e,c);return t.has(a)?a:_c(a,t)}catch{return null}},s=Y.extname(e);if(s&&t.has(e))return e;let o=Rc[s];if(o)for(let i of o){let c=e.slice(0,-s.length)+i;if(t.has(c))return c}for(let i of _s)if(t.has(e+i))return e+i;let r=n();if(r)return r;for(let i of Cc){let c=Y.join(e,i);if(t.has(c))return c}return null}function _c(e,t){if(Y.extname(e)&&t.has(e))return e;for(let s of _s)if(t.has(e+s))return e+s;return null}var Un=e=>{try{let n=qe.readFileSync(e,"utf8").replace(/^/,"").replace(/("(?:[^"\\]|\\.)*")|\/\/[^\n]*|\/\*[\s\S]*?\*\//g,(s,o)=>o??"");return JSON.parse(n.replace(/,(\s*[}\]])/g,"$1"))}catch{return null}};function Os(e,t=new Set){if(t.has(e))return{baseUrl:null,paths:null};t.add(e);let n=Un(e);if(!n)return{baseUrl:null,paths:null};let s=null,o=null,r=n.extends?Array.isArray(n.extends)?n.extends:[n.extends]:[];for(let c of r){if(typeof c!="string"||!c.startsWith("."))continue;let a=Y.resolve(Y.dirname(e),c);(!qe.existsSync(a)||qe.statSync(a).isDirectory())&&(a=qe.existsSync(a+".json")?a+".json":Y.join(a,"tsconfig.json"));let l=Os(a,t);l.baseUrl&&(s=l.baseUrl),l.paths&&(o=l.paths)}let i=n.compilerOptions??{};if(typeof i.baseUrl=="string"&&(s=Y.resolve(Y.dirname(e),i.baseUrl)),i.paths&&typeof i.paths=="object"){let c=s??Y.dirname(e);o=Object.entries(i.paths).map(([a,l])=>{let f=a.indexOf("*");return{prefix:f<0?a:a.slice(0,f),suffix:f<0?"":a.slice(f+1),wildcard:f>=0,targets:(Array.isArray(l)?l:[]).filter(y=>typeof y=="string").map(y=>Y.resolve(c,y))}}).sort((a,l)=>l.prefix.length-a.prefix.length)}return{baseUrl:s,paths:o}}function Lc(e,t){if(t=t.replace(/^\.\//,"").replace(/\/+$/,""),t.startsWith("!"))return[];let n=[],s=o=>{try{return qe.readdirSync(o,{withFileTypes:!0}).filter(r=>r.isDirectory()&&r.name!=="node_modules"&&!r.name.startsWith(".")).map(r=>Y.join(o,r.name))}catch{return[]}};if(t.endsWith("/**")){let o=Y.join(e,t.slice(0,-3)),r=i=>{for(let c of s(i))n.push(c),r(c)};r(o)}else t.endsWith("/*")?n.push(...s(Y.join(e,t.slice(0,-2)))):t.includes("*")||n.push(Y.join(e,t));return n}function Pc(e){let t=[],s=Un(Y.join(e,"package.json"))?.workspaces;Array.isArray(s)?t.push(...s):Array.isArray(s?.packages)&&t.push(...s.packages);try{let o=qe.readFileSync(Y.join(e,"pnpm-workspace.yaml"),"utf8"),r=!1;for(let i of o.split(/\r?\n/)){if(/^packages\s*:/.test(i)){r=!0;continue}if(r){let c=/^\s*-\s*['"]?([^'"#\s]+)['"]?/.exec(i);c?t.push(c[1]):/^\S/.test(i)&&(r=!1)}}}catch{}return t}function Cs(e,t){if(e==null)return null;let n=o=>{if(typeof o=="string")return o;if(Array.isArray(o)){for(let r of o){let i=n(r);if(i)return i}return null}if(o&&typeof o=="object"){for(let r of["source","import","module","default","require","node"])if(r in o){let i=n(o[r]);if(i)return i}}return null};if(typeof e=="string"||Array.isArray(e))return t==="."?n(e):null;let s=Object.keys(e);if(!s.some(o=>o.startsWith(".")))return t==="."?n(e):null;if(e[t]!=null)return n(e[t]);for(let o of s){let r=o.indexOf("*");if(r>0&&t.startsWith(o.slice(0,r))&&t.endsWith(o.slice(r+1))){let i=n(e[o]);if(i)return i.replace("*",t.slice(r,t.length-(o.length-r-1)))}}return null}function Ts(e,t,n={}){let s=Es(e),o=new Set(t),r=new Map,i=u=>{if(r.has(u))return r.get(u);let v=null,p=Y.join(u,"tsconfig.json");return qe.existsSync(p)?v=Os(p):u!==s&&Y.dirname(u)!==u&&u.startsWith(s)&&(v=i(Y.dirname(u))),r.set(u,v),v},c=new Map;for(let u of Pc(s))for(let v of Lc(s,u)){let p=Un(Y.join(v,"package.json"));p?.name&&!c.has(p.name)&&c.set(p.name,{dir:Es(v),pkg:p})}let a=[...c.keys()].sort((u,v)=>v.length-u.length),l=(u,v,p)=>{let{dir:w,pkg:I}=c.get(u),g=[],b=$=>{if(!$)return;let S=Y.resolve(w,$);g.push(S);let m=Y.relative(w,S).split(Y.sep);["dist","build","lib","out","esm","cjs"].includes(m[0])&&g.push(Y.join(w,"src",...m.slice(1)))};if(v==="."){b(Cs(I.exports,"."));for(let $ of["source","module","main"])typeof I[$]=="string"&&b(I[$]);g.push(Y.join(w,"src","index"),Y.join(w,"index"))}else b(Cs(I.exports,v)),g.push(Y.join(w,v),Y.join(w,"src",v));for(let $ of g){let S=Ct($,p);if(S)return S}return null},f=u=>a.find(v=>u===v||u.startsWith(v+"/"))??null,y=(u,v)=>v?.paths?.some(p=>p.wildcard?u.startsWith(p.prefix)&&u.endsWith(p.suffix)&&u.length>=p.prefix.length+p.suffix.length:u===p.prefix)??!1;return{root:s,files:o,packages:c,isInternal(u,v){if(u.startsWith(".")||f(u))return!0;let p=i(Y.dirname(v));return!!(y(u,p)||p?.baseUrl&&!u.startsWith("@")&&Ct(Y.join(p.baseUrl,u),o))},resolve(u,v,p){if(u.startsWith("."))return Ct(Y.resolve(Y.dirname(v),u),p);let w=i(Y.dirname(v));if(w?.paths&&n.paths!==!1)for(let g of w.paths){let b=null;if(g.wildcard?u.startsWith(g.prefix)&&u.endsWith(g.suffix)&&u.length>=g.prefix.length+g.suffix.length&&(b=u.slice(g.prefix.length,u.length-g.suffix.length)):u===g.prefix&&(b=""),b!=null){for(let $ of g.targets){let S=Ct($.replace("*",b),p);if(S)return S}break}}let I=n.workspaces===!1?null:f(u);if(I){let g=l(I,u===I?".":"./"+u.slice(I.length+1),p);if(g)return g}if(w?.baseUrl&&n.paths!==!1){let g=Ct(Y.join(w.baseUrl,u),p);if(g)return g}return null}}}var Rs=new WeakMap;function As(e){if(e instanceof Set)return e;let t=Rs.get(e);return t||Rs.set(e,t=new Set(e)),t}var Fs=new WeakMap;function Mc(e){let t=Fs.get(e);return(!t||t.n!==e.length)&&(t={n:e.length,set:new Set(e)},Fs.set(e,t)),t.set}function Gn(e,t,n){if(!e.startsWith("."))return null;let s=qn.dirname(t),o=qn.resolve(s,e),r=[o,...cs().map(i=>`${o}${i}`),...as().map(i=>qn.join(o,i))];for(let i of r)if(Mc(n).has(i))return i;return null}function ve(e,t,n){let s=Gn(e,t,n);if(s)return s;let o=Ms();return o?o.resolve(e,t,As(n)):null}function wt(e,t,n){let s=new Map;for(let o of t){let r=Gn(o.source,e,n);r&&s.set(o.source,r)}s.legacySize=s.size;for(let o of t){if(s.has(o.source))continue;let r=ve(o.source,e,n);r&&s.set(o.source,r)}return s}function Bs(e){let t=new Map,n=new Map,s=new Map;for(let o of e){if(o.type!=="classMethod")continue;let r=o.className+"\0"+o.name;n.has(r)||n.set(r,o),o.name==="constructor"&&(s.has(o.className)||s.set(o.className,[]),s.get(o.className).push(o))}return{scopeOf:o=>{let r=t.get(o);return r||(r=fe(o,e),t.set(o,r)),r},method:(o,r)=>n.get(o+"\0"+r),ctorsOf:o=>s.get(o)??[]}}function xt(e){return e?e.split("?")[0].split("/").map(t=>t.startsWith(":")||/^\d+$/.test(t)?"*":t).join("/"):""}var Oc=new Set(["function","arrowFunction"]);function Hs(e,t,n,s){let o=new Map;for(let l of t){let f=o.get(l.filePath);f||o.set(l.filePath,f=[]),f.push(l)}let r=new Set;for(let l of s)l.resolved&&l.fromNodeId&&l.targetNodeId&&r.add(l.fromNodeId+"\0"+l.targetNodeId);let i=(l,f)=>(o.get(l)??[]).find(y=>Oc.has(y.type)&&f(y))??null,c=[];c.argBindings=[];let a=(l,f,y,u,v,p,w)=>{!f||!y||f.id===y.id||r.has(f.id+"\0"+y.id)||c.push({fromFileId:l,fromNodeId:f.id,calleeNameRaw:u,line:v,column:p,branchPath:[],firstArgText:null,deferred:!1,type:"reference",callKind:"reference",targetNodeId:y.id,confidence:w==="local"?.95:.85,matchType:w,resolved:!0})};for(let[l,f]of e){let y=o.get(l);if(y){for(let u of f.refArgs??[]){let v=null,p="local";if(u.b==="fn"?v=i(l,I=>I.name===u.name&&I.startLine===u.declLine):u.b==="import"&&(p="import",(u.ik==="default"||u.ik==="named"||u.ik==="cjs")&&(v=n.nodeForImport(l,u.src,u.ik,u.imp))),!v)continue;let w=ce(u.line,y);a(l,w,v,u.name,u.line,u.column,p),u.callLine!=null&&w&&w.id!==v.id&&c.argBindings.push({file:l,line:u.callLine,column:u.callColumn,targetNodeId:v.id,matchType:p,direct:u.via==="arg"})}for(let u of y){if(u.type!=="inlineHandler")continue;let v=null;for(let p of y)p===u||p.type==="moduleRoot"||p.startLine<=u.startLine&&p.endLine>=u.endLine&&!(p.startLine===u.startLine&&p.endLine===u.endLine)&&(!v||p.endLine-p.startLine<v.endLine-v.startLine)&&(v=p);v??=y.find(p=>p.type==="moduleRoot"),a(l,v,u,u.name,u.startLine,0,"local")}}}return c}function Ds(e,t,n,s){let o=new Map,r=new Map;for(let c of e){if(r.set(c.id,c),c.type!=="classMethod")continue;let a=c.filePath+"\0"+c.className+"\0"+c.name,l=o.get(a);l?l.push(c):o.set(a,[c])}let i=(c,a)=>{for(let l of o.keys())if(l.startsWith(c+"\0"+a+"\0"))return!0;return!1};return function(a){let l=r.get(a.fromNodeId);if(!l||l.type!=="classMethod")return null;let f=t.get(a.fromFileId),y=(f?.classProps??[]).find(I=>I.className===l.className&&I.prop===a.thisProp);if(!y)return null;let u=null,v=null,p=(f.importBindings??[]).find(I=>I.local===y.type);if(p){let I=p.kind==="default"||p.kind==="named"?s.resolveImport(a.fromFileId,p.source,p.kind,p.imported):null;I?.local&&I.local!=="default"&&(u=I.file,v=I.local)}else i(a.fromFileId,y.type)&&(u=a.fromFileId,v=y.type);if(!u)return null;let w=o.get(u+"\0"+v+"\0"+a.thisMethod);return!w||w.length!==1?null:{...a,targetNodeId:w[0].id,confidence:.9,matchType:"typedProperty",resolved:!0}}}var Tc=new Set(["function","arrowFunction"]);function Qt(e,t,n){let s=new Map;for(let f of e){if(!Tc.has(f.type))continue;let y=f.filePath+"\0"+f.name;s.has(y)||s.set(y,f)}let o=new Map,r=(f,y)=>{let u=o.get(f);if(!u){u=new Map;for(let v of t.get(f)?.importBindings??[])u.has(v.local)||u.set(v.local,v);o.set(f,u)}return u.get(y)??null},i=(f,y)=>n(f).get(y)??null;function c(f,y,u=new Set){let v=f+"\0"+y;if(u.has(v))return null;u.add(v);let p=t.get(f)?.exportBindings;if(!p)return null;if(y==="default"){if(p.default)return{file:f,local:p.default==="<anon>"?"default":p.default}}else if(p.named?.[y])return{file:f,local:p.named[y]};for(let w of p.reexports??[]){if(w.exported!==y)continue;let I=i(f,w.source);if(I)return c(I,w.imported,u)}for(let w of p.nsReexports??[]){if(w.exported!==y)continue;let I=i(f,w.source);if(I)return{moduleFile:I}}if(y!=="default")for(let w of p.stars??[]){let I=i(f,w),g=I?c(I,y,u):null;if(g)return g}return null}let a=f=>f?.local?s.get(f.file+"\0"+f.local)??null:null;function l(f,y,u,v){let p=i(f,y);return p?u==="default"?c(p,"default"):u==="named"?c(p,v):{moduleFile:p,cjs:u==="cjs"}:null}return{lookupExport:c,resolveImport:l,nodeForImport(f,y,u,v){let p=l(f,y,u,v);return p?.moduleFile&&p.cjs?a(c(p.moduleFile,"default")):a(p)},resolveName(f,y){let u=r(f,y);return u?this.nodeForImport(f,u.source,u.kind,u.imported):null},resolveMember(f,y,u){let v=r(f,y);if(!v)return null;let p=l(f,v.source,v.kind,v.imported);return p?.moduleFile?a(c(p.moduleFile,u)):null},classForImport(f,y){let u=r(f,y);if(!u)return null;let v=l(f,u.source,u.kind,u.imported);return v?.local?{file:v.file,className:v.local==="default"?null:v.local}:null},bindingFor:r}}function zs(e,t,n,s){let o=new Map,r=new Map;for(let u of t){if(u.type!=="classMethod")continue;r.set(u.id,u);let v=u.filePath+"\0"+u.className+"\0"+u.name,p=o.get(v);p?p.push(u):o.set(v,[u])}let i=(u,v)=>{let p=(n.get(u)?.classHeritage??[]).filter(w=>w.className===v);return p.length===1?p[0]:null},c=(u,v)=>(n.get(u)?.classHeritage??[]).filter(p=>p.className===v).length,a=new Map;for(let[u,v]of n)for(let p of v.classHeritage??[]){if(!p.superName)continue;let w=a.get(p.superName);w?w.push({file:u,className:p.className}):a.set(p.superName,[{file:u,className:p.className}])}let l=(u,v)=>{let p=new Set([u]),w=[u];for(;w.length;)for(let I of a.get(w.pop())??[]){if(o.has(I.file+"\0"+I.className+"\0"+v))return!0;p.has(I.className)||(p.add(I.className),w.push(I.className))}return!1},f=(u,v)=>{let w=(n.get(u)?.importBindings??[]).find(I=>I.local===v);if(w){let I=w.kind==="default"||w.kind==="named"?s.resolveImport(u,w.source,w.kind,w.imported):null;return I?.local&&I.local!=="default"&&I.file?{file:I.file,cls:I.local}:null}return c(u,v)===1?{file:u,cls:v}:null},y=0;for(let u of e){if(u.resolved||u.type!=="callSite"||u.callKind!=="thisCall"||u.thisBound===!1)continue;let v=/^this\s*\.\s*(#?[A-Za-z_$][\w$]*)$/.exec(u.calleeNameRaw??""),p=r.get(u.fromNodeId);if(!v||!p)continue;let w=v[1];if(c(p.filePath,p.className)!==1||l(p.className,w))continue;let I=p.filePath,g=p.className,b=null,$="thisMethod";for(let S=0;S<12;S++){let m=o.get(I+"\0"+g+"\0"+w);if(m){b=m.length===1?m[0]:null;break}let d=i(I,g);if(!d||!d.superName||d.unknownSuper)break;let k=f(I,d.superName);if(!k)break;({file:I,cls:g}=k),$="thisMethodInherited"}b&&(Object.assign(u,{targetNodeId:b.id,confidence:$==="thisMethod"?.9:.85,matchType:"thisMethod",thisInherited:$==="thisMethodInherited",resolved:!0}),y++)}return y}function Ws(e,t,n,s,o,r,i){let c=[],a=Bs(t),l=new Map,f=g=>l.get(g)??wt(g,n.get(g)?.imports??[],s);a.bind=Qt(t,n,f);let y=Ds(t,n,f,a.bind),u=new Map;for(let g of e)u.has(g.fromFileId)||u.set(g.fromFileId,[]),u.get(g.fromFileId).push(g);for(let[g,b]of u){let $=n.get(g),S=fe(g,t),m=wt(g,$.imports,s);l.set(g,m);for(let d of b)if(d.type==="call")c.push(Et(d,t,S,m,a));else if(d.type==="methodCall")c.push(Ns(d,t,a));else if(d.type==="callSite")c.push((d.thisProp?y(d):null)??js(d,t,S,m,a));else if(d.type==="returnValue")c.push({...d,targetNodeId:null,confidence:0,matchType:"returnValue",resolved:!1});else if(d.type==="apiCall")if(d.scope==="external")c.push({...d,targetNodeId:null,confidence:null,matchType:"externalService",resolved:!1});else{let k=xt(d.url),h=o.get(k);h?c.push({...d,targetNodeId:h,confidence:.5,matchType:"crossLayer",resolved:!0}):c.push({...d,targetNodeId:null,confidence:0,matchType:"unresolved",resolved:!1})}else if(d.type==="socketEmit"){let k=r.get(d.eventName);k?c.push({...d,targetNodeId:k,confidence:.5,matchType:"crossLayer",resolved:!0}):c.push({...d,targetNodeId:null,confidence:0,matchType:"unresolved",resolved:!1})}else if(d.type==="rawSocketSend"){let k=i?.get(d.eventName);k?c.push({...d,targetNodeId:k,confidence:.5,matchType:"crossLayer",resolved:!0}):c.push({...d,targetNodeId:null,confidence:0,matchType:"unresolved",resolved:!1})}}let v=Hs(n,t,a.bind,c);for(let g of v)c.push(g);let p=new Map;for(let g of c){if(g.resolved||g.line==null||g.type!=="call"&&g.type!=="methodCall"&&g.type!=="callSite")continue;let b=g.fromFileId+" "+g.line+" "+g.column;(p.get(b)??p.set(b,[]).get(b)).push(g)}let w=[...v.argBindings].sort((g,b)=>b.direct-g.direct),I=new Set;for(let g of w){let b=g.file+" "+g.line+" "+g.column;if(I.has(b))continue;let $=(p.get(b)??[]).find(S=>S.fromNodeId!==g.targetNodeId);$&&(I.add(b),Object.assign($,{targetNodeId:g.targetNodeId,confidence:g.matchType==="local"?.95:.85,matchType:"argument",resolved:!0,viaArgument:!0}))}return zs(c,t,n,a.bind),c}import Ac from"node:crypto";var Fc=200,Us=(e,t)=>t.length<=Fc?e+t:e+"#"+t.length+":"+Ac.createHash("sha256").update(t).digest("base64"),Bc=20,Hc=40;function qs(e){let t=new Map,n=new WeakMap,s=a=>{if(typeof a=="string")return a.length>=Bc?Us("s",a):null;if(a&&typeof a=="object"){let l=n.get(a);if(l===void 0){let f=JSON.stringify(a);l=f.length>=Hc?Us("j",f):"",n.set(a,l)}return l||null}return null};(function a(l){let f=s(l);if(f){let y=t.get(f)??0;if(t.set(f,y+1),y>0)return}if(Array.isArray(l))for(let y of l)a(y);else if(l&&typeof l=="object")for(let y of Object.values(l))a(y)})(e);let o=[],r=new Map,i=a=>{let l=s(a),f=l&&t.get(l)>1;if(f&&r.has(l))return r.get(l);let y;if(typeof a=="string"?y=JSON.stringify(a):Array.isArray(a)?y="["+a.map(i).join(",")+"]":a&&typeof a=="object"?y="{"+Object.entries(a).map(([v,p])=>JSON.stringify(v)+":"+i(p)).join(",")+"}":y=JSON.stringify(a),!f)return y;let u="$"+o.length.toString(36);return o.push(`const ${u}=${y};`),r.set(l,u),u},c=i(e);return`(() => {${o.join(`
|
|
6
|
+
import{a as go,b as yo,d as vo,e as wo,g as xo}from"./chunk-Y3GNG3XL.js";import{b as Jo}from"./chunk-YC3GSAN3.js";import{a as Mo,b as Oo,c as To,d as Ao,f as Fo,g as Bo,h as Ho,i as Do,j as zo,k as Wo,l as Uo,m as qo,o as Go,p as Yo}from"./chunk-DRLW6UU3.js";import{s as Lo,t as Po}from"./chunk-W57Z6UQP.js";import{a as ko,b as Bt,c as Ht,d as ye,e as Re,f as Dt,g as ot,h as Cn,i as So,j as bo,k as $o,l as No,m as Io,n as jo,o as Eo,p as Co,q as Ro,r as _o}from"./chunk-LAKMPJML.js";import{a as ze,c as Rn,d as Vo,e as Ko,f as Xo,g as Zo,i as Qo}from"./chunk-K7XFTTX2.js";import{a as Te,b as Ft}from"./chunk-ZF5SEDQB.js";import{a as Ti,b as Ai}from"./chunk-ZQ6F3H6X.js";var ls=Ti((Wl,Ut)=>{function os(e){return Array.isArray(e)?e:[e]}var Bi=void 0,Ln="",ts=" ",_n="\\",Hi=/^\s+$/,Di=/(?:[^\\]|^)\\$/,zi=/^\\!/,Wi=/^\\#/,Ui=/\r?\n/g,qi=/^\.{0,2}\/|^\.{1,2}$/,Gi=/\/$/,ht="/",ss="node-ignore";typeof Symbol<"u"&&(ss=Symbol.for("node-ignore"));var rs=ss,gt=(e,t,n)=>(Object.defineProperty(e,t,{value:n}),n),Yi=/([0-z])-([0-z])/g,is=()=>!1,Ji=e=>e.replace(Yi,(t,n,s)=>n.charCodeAt(0)<=s.charCodeAt(0)?t:Ln),Vi=e=>e.startsWith("!")||e.startsWith("\\^")?`^${e.slice(e[0]==="!"?1:2)}`:e,Ki=e=>{let{length:t}=e;return e.slice(0,t-t%2)},Xi=[[/^\uFEFF/,()=>Ln],[/((?:\\\\)*?)(\\?\s+)$/,(e,t,n)=>t+(n.indexOf("\\")===0?ts:Ln)],[/(\\+?)\s/g,(e,t)=>{let{length:n}=t;return t.slice(0,n-n%2)+ts}],[/[\\$.|*+(){^]/g,e=>`\\${e}`],[/(?!\\)\?/g,()=>"[^/]"],[/^\//,()=>"^"],[/\//g,()=>"\\/"],[/^\^*(?:\\\*\\\*\\\/)+/,()=>"^(?:.*\\/)?"],[/^(?=[^^])/,function(){return/\/(?!$)/.test(this)?"^":"(?:^|\\/)"}],[/\\\/\\\*\\\*(?=\\\/|$)/g,(e,t,n)=>t+6<n.length?"(?:\\/[^\\/]+)*":"\\/.+"],[/(^|[^\\]+)(\\\*)+(?=.+)/g,(e,t,n)=>{let s=n.replace(/\\\*/g,"[^\\/]*");return t+s}],[/\\\\\\(?=[$.|*+(){^])/g,()=>_n],[/\\\\/g,()=>_n],[/(\\)?\[([^\]/]*?)(\\*)($|\])/g,(e,t,n,s,o)=>t===_n?`\\[${n}${Ki(s)}${o}`:o==="]"&&s.length%2===0?`[${Vi(Ji(n))}${s}]`:"[]"],[/(?:[^*])$/,e=>/\/$/.test(e)?`${e}$`:`${e}(?=$|\\/$)`]],Zi=/(^|\\\/)?\\\*$/,It="regex",zt="checkRegex",ns="_",Qi={[It](e,t){return`${t?`${t}[^/]+`:"[^/]*"}(?=$|\\/$)`},[zt](e,t){return`${t?`${t}[^/]*`:"[^/]*"}(?=$|\\/$)`}},ec=e=>Xi.reduce((t,[n,s])=>t.replace(n,s.bind(e)),e),Wt=e=>typeof e=="string",tc=e=>e&&Wt(e)&&!Hi.test(e)&&!Di.test(e)&&e.indexOf("#")!==0,nc=e=>e.split(Ui).filter(Boolean),Pn=class{constructor(t,n,s,o,r,i){this.pattern=t,this.mark=n,this.negative=r,gt(this,"body",s),gt(this,"ignoreCase",o),gt(this,"regexPrefix",i)}get regex(){let t=ns+It;return this[t]?this[t]:this._make(It,t)}get checkRegex(){let t=ns+zt;return this[t]?this[t]:this._make(zt,t)}_make(t,n){let s=this.regexPrefix.replace(Zi,Qi[t]),o=this.ignoreCase?new RegExp(s,"i"):new RegExp(s);return gt(this,n,o)}},oc=({pattern:e,mark:t},n)=>{let s=!1,o=e;o.indexOf("!")===0&&(s=!0,o=o.substr(1)),o=o.replace(zi,"!").replace(Wi,"#");let r=ec(o);return new Pn(e,t,o,n,s,r)},Mn=class{constructor(t){this._ignoreCase=t,this._rules=[]}_add(t){if(t&&t[rs]){this._rules=this._rules.concat(t._rules._rules),this._added=!0;return}if(Wt(t)&&(t={pattern:t}),tc(t.pattern)){let n=oc(t,this._ignoreCase);this._added=!0,this._rules.push(n)}}add(t){return this._added=!1,os(Wt(t)?nc(t):t).forEach(this._add,this),this._added}test(t,n,s){let o=!1,r=!1,i;this._rules.forEach(a=>{let{negative:l}=a;r===l&&o!==r||l&&!o&&!r&&!n||!a[s].test(t)||(o=!l,r=l,i=l?Bi:a)});let c={ignored:o,unignored:r};return i&&(c.rule=i),c}},sc=(e,t)=>{throw new t(e)},We=(e,t,n)=>Wt(e)?e?We.isNotRelative(e)?n(`path should be a \`path.relative()\`d string, but got "${t}"`,RangeError):!0:n("path must not be empty",TypeError):n(`path must be a string, but got \`${t}\``,TypeError),cs=e=>qi.test(e);We.isNotRelative=cs;We.convert=e=>e;var On=class{constructor({ignorecase:t=!0,ignoreCase:n=t,allowRelativePaths:s=!1}={}){gt(this,rs,!0),this._rules=new Mn(n),this._strictPathCheck=!s,this._initCache()}_initCache(){this._ignoreCache=Object.create(null),this._testCache=Object.create(null)}add(t){return this._rules.add(t)&&this._initCache(),this}addPattern(t){return this.add(t)}_test(t,n,s,o){let r=t&&We.convert(t);return We(r,t,this._strictPathCheck?sc:is),this._t(r,n,s,o)}checkIgnore(t){if(!Gi.test(t))return this.test(t);let n=t.split(ht).filter(Boolean);if(n.pop(),n.length){let s=this._t(n.join(ht)+ht,this._testCache,!0,n);if(s.ignored)return s}return this._rules.test(t,!1,zt)}_t(t,n,s,o){if(t in n)return n[t];if(o||(o=t.split(ht).filter(Boolean)),o.pop(),!o.length)return n[t]=this._rules.test(t,s,It);let r=this._t(o.join(ht)+ht,n,s,o);return n[t]=r.ignored?r:this._rules.test(t,s,It)}ignores(t){return this._test(t,this._ignoreCache,!1).ignored}createFilter(){return t=>!this.ignores(t)}filter(t){return os(t).filter(this.createFilter())}test(t){return this._test(t,this._testCache,!0)}},Tn=e=>new On(e),rc=e=>We(e&&We.convert(e),e,is),as=()=>{let e=n=>/^\\\\\?\\/.test(n)||/["<>|\u0000-\u001F]+/u.test(n)?n:n.replace(/\\/g,"/");We.convert=e;let t=/^[a-z]:\//i;We.isNotRelative=n=>t.test(n)||cs(n)};typeof process<"u"&&process.platform==="win32"&&as();Ut.exports=Tn;Tn.default=Tn;Ut.exports.isPathValid=rc;gt(Ut.exports,Symbol.for("setupWindows"),as)});import{isMainThread as es,workerData as Fi}from"node:worker_threads";es&&!process.env.UV_THREADPOOL_SIZE&&(process.env.UV_THREADPOOL_SIZE="16");if(!es&&Fi?.canopyParseWorker===!0){let{runParseWorker:e}=await import("./chunk-HSFPQRFR.js");await e(),await new Promise(()=>{})}import jn from"node:fs";import St from"node:path";import Ve from"node:fs";import Ja from"node:os";import ue from"node:path";import{fileURLToPath as ii}from"node:url";import Q from"node:path";import we from"node:fs";import{fileURLToPath as Ua,pathToFileURL as qa}from"node:url";var Bn=Ai(ls(),1);import yt from"node:fs";import $e from"node:path";var An={javascript:[".js",".jsx",".mjs",".cjs"],typescript:[".ts",".tsx"]},fs=[".ts",".tsx",".mts",".cts"],ic={javascript:["index.js","index.jsx"],typescript:["index.ts","index.tsx"]};function us(){return Object.values(An).flat()}function ds(){return Object.values(ic).flat()}var ps=["log","logger","console","debug","trace"];var hs=[".yarn",".pnp","vendor","dist","build","out","coverage",".next",".nuxt",".turbo",".cache","bower_components"],Hn=["node_modules",".git",".canopy",".canopy-cache"],ms=[".vue",".svelte"],cc=1024*1024,Fn=1e4;function ac(e,t=null){let n=[];function s(o,r){let i=$e.join(o,".gitignore"),c=(0,Bn.default)().add(r);yt.existsSync(i)&&c.add(yt.readFileSync(i,"utf-8"));let a=yt.readdirSync(o,{withFileTypes:!0});for(let l of a){let f=$e.join(o,l.name),y=$e.relative(e,f).split($e.sep).join("/");if(!c.ignores(y)&&!(l.isDirectory()&&Hn.includes(l.name))){if(l.isDirectory()&&hs.includes(l.name)){t&&t.excludedDirs.push(f);continue}l.isDirectory()?s(f,c):l.isFile()&&n.push(f)}}}return s(e,(0,Bn.default)()),n}function lc(e,t,n=null){return e.filter(s=>!(n?$e.relative(n,s):s).split($e.sep).some(r=>t.includes(r)))}function gs(e,t){let n=0,s;try{s=yt.readdirSync(e,{withFileTypes:!0})}catch{return 0}for(let o of s)o.isDirectory()?Hn.includes(o.name)||(n+=gs($e.join(e,o.name),t)):o.isFile()&&t.has($e.extname(o.name))&&n++;return n}var fc=e=>/\.d\.(ts|mts|cts)$/.test(e);function uc(e){let t=$e.basename(e);if(/\.min\.js$/.test(t))return{kind:"minified",reason:"minified (*.min.js)"};if(/\.bundle\.js$/.test(t))return{kind:"bundled",reason:"bundled (*.bundle.js)"};let n;try{n=yt.statSync(e).size}catch{return null}if(n>cc)return{kind:"oversized",reason:`oversized (${(n/1048576).toFixed(1)} MB, limit 1 MB)`};if(n>Fn){let s=yt.readFileSync(e,"utf8"),o=0,r=0;for(;;){let i=s.indexOf(`
|
|
7
|
+
`,o),c=(i<0?s.length:i)-o;if(c>r&&(r=c),i<0)break;o=i+1}if(r>Fn)return{kind:"minified",reason:`line of ${r.toLocaleString("en-US")} characters (limit ${Fn.toLocaleString("en-US")}; minified/bundled)`}}return null}function jt(e,t=["javascript","typescript"]){let n=t.flatMap(y=>(y==="typescript"?fs:An[y])||[]),s={excludedDirs:[]},o=lc(ac(e,s),[...hs,...Hn],e),r=y=>$e.relative(e,y).split($e.sep).join("/"),i=[],c=[],a={};for(let y of o){let u=$e.extname(y);if(n.includes(u)){if(fc(y)){c.push({file:r(y),kind:"declaration",reason:"declaration file"});continue}let v=uc(y);v?c.push({file:r(y),kind:v.kind,reason:v.reason}):i.push(y)}else ms.includes(u)&&(a[u]=(a[u]??0)+1)}let l=new Set([...n,...ms]),f={};for(let y of s.excludedDirs){let u=$e.basename(y),v=f[u]??={dirs:0,files:0};v.dirs++,v.files+=gs(y,l)}return{files:i,skipped:c,unsupported:a,excludedDirs:f}}function Dn(e,t=["javascript","typescript"]){return jt(e,t).files}import dc from"node:path";var st=e=>e.toLocaleString("en-US"),qt=(e,t,n=t+"s")=>`${st(e)} ${e===1?t:n}`,pc={".vue":"Vue",".svelte":"Svelte"},mc=[".vue",".svelte"],hc=new Set([".ts",".tsx",".mts",".cts"]);function ys({discovered:e,parseResults:t,scopeFiles:n,rel:s,rootService:o=null}){let r=(t.budgetSkips??[]).map(p=>({path:s(p.filePath),kind:"timeout",reason:p.reason})),i=new Set((t.budgetSkips??[]).map(p=>p.filePath)),c=[...e.skipped.map(p=>({path:p.file,kind:p.kind,reason:p.reason})),...r].sort((p,w)=>p.path<w.path?-1:p.path>w.path?1:0),a=e.files.filter(p=>!i.has(p)),l=a.filter(p=>t.get(p)?.hadErrors).map(s).sort(),f=a.flatMap(p=>(t.get(p)?.warnings??[]).map(w=>({path:s(p),extractor:w.extractor,message:w.message}))).sort((p,w)=>p.path<w.path?-1:p.path>w.path?1:0),y=a.filter(p=>hc.has(dc.extname(p))).length,u={};for(let p of mc)e.unsupported[p]&&(u[p]=e.unsupported[p]);let v={};for(let p of c)v[p.kind]=(v[p.kind]??0)+1;return{analyzed:a.length,analyzedJs:a.length-y,analyzedTs:y,inService:a.filter(p=>n.has(p)).length,notAnalyzed:u,notAnalyzedTotal:Object.values(u).reduce((p,w)=>p+w,0),skipped:c,skippedByKind:v,parseErrors:l.length,parseErrorFiles:l.slice(0,50),parseWarnings:f.length,parseWarningList:f.slice(0,50),excludedDirs:e.excludedDirs,rootService:o}}function Gt(e){let t=["Coverage"],n=[],s=new Map;for(let[c,a]of Object.entries(e.notAnalyzed)){let l=pc[c];s.has(l)||s.set(l,[]),s.get(l).push(`${st(a)} ${c}`)}for(let[c,a]of s)n.push(`${a.join(", ")} files (${c} not supported yet)`);if(e.skipped.length){let c=Object.entries(e.skippedByKind).map(([a,l])=>`${a}: ${l}`).join(", ");n.push(`${st(e.skipped.length)} skipped (${c})`)}e.parseErrors&&n.push(`${st(e.parseErrors)} with parse errors`),e.parseWarnings&&n.push(`${st(e.parseWarnings)} extractor warnings (a construct skipped; the rest of its file was analyzed)`);let o=e.analyzedTs?`${qt(e.analyzedJs,"JS file")} and ${qt(e.analyzedTs,"TS file")}`:qt(e.analyzed,"JS file");t.push(` Analyzed ${o}, ${st(e.inService)} of them inside a service${e.analyzed?` (${Math.round(100*e.inService/e.analyzed)}%)`:""}.`),t.push(` Not analyzed: ${n.length?n.join(", "):"nothing"}.`);let r=e.skipped.filter(c=>c.kind!=="declaration");for(let c of r.slice(0,5))t.push(` skipped ${c.path}: ${c.reason}`);r.length>5&&t.push(` ... and ${st(r.length-5)} more (full list: meta.coverage.skipped)`);let i=Object.entries(e.excludedDirs);return i.length&&t.push(` Excluded directories: ${i.map(([c,a])=>`${c}/ x${a.dirs} (${qt(a.files,"source file")})`).join(", ")}.`),e.rootService&&t.push(` Root service: ${e.rootService.reason}.`),t.join(`
|
|
8
|
+
`)}function Yt(e,t){return`${e}::${t}`}var vs=[{category:"frontend",patterns:["frontend","client","src/components","ui","src/pages","public"]},{category:"backend",patterns:["backend","server","api","realtime-backend"]},{category:"transport",patterns:["websocket","socket","realtime"]},{category:"data",patterns:["redis","database","models","db"]}];function Jt(e){let t=e.toLowerCase().replace(/\\/g,"/");for(let{category:n,patterns:s}of vs)for(let o of s)if(t.includes(o))return n;return"unknown"}import zn from"node:fs";import xe from"node:path";import Vt from"node:fs";import Ue from"node:path";var gc=["index.html","public/index.html","src/index.html"],yc=/^(build|esbuild|vite\.config|webpack\.config|rollup\.config|bundle)[\w.-]*\.(mjs|cjs|js|ts)$/i;function vc(e){let t=e.replace(/<!--[\s\S]*?-->/g,""),n=[];for(let s of t.matchAll(/<script\b[^>]*?\bsrc\s*=\s*(?:"([^"]*)"|'([^']*)')/gi))n.push(s[1]??s[2]);return n}function wc(e){let t=[],n=[];try{n=Vt.readdirSync(e).filter(s=>yc.test(s)).sort()}catch{return t}for(let s of n){let o;try{o=Vt.readFileSync(Ue.join(e,s),"utf8")}catch{continue}let r=/\boutfile\s*:\s*["'`]([^"'`]+)["'`]/.exec(o)?.[1]??null,i=/\b(?:entryPoints|entry|input)\s*:\s*\[?\s*["'`]([^"'`]+)["'`]/.exec(o)?.[1]??null;i&&t.push({config:s,outfile:r,entry:i})}return t}function Kt(e,t,n=new Set(t.map(s=>Ue.resolve(s)))){for(let s of gc){let o=Ue.join(e,s);if(!Vt.existsSync(o))continue;let r;try{r=Vt.readFileSync(o,"utf8")}catch{continue}let i=Ue.dirname(o),c=f=>{let y=f.split(/[?#]/)[0];return!y||/^([a-z]+:)?\/\//i.test(y)?null:Ue.resolve(y.startsWith("/")?Ue.join(e,y):Ue.join(i,y))},a=vc(r).map(f=>({s:f,p:c(f)})).filter(f=>f.p);for(let{s:f,p:y}of a)if(n.has(y))return{indexHtml:o,script:f,entry:y,via:"script"};let l=wc(e);for(let{s:f,p:y}of a)for(let u of l){if(!u.outfile||Ue.resolve(e,u.outfile)!==y)continue;let v=Ue.resolve(e,u.entry);if(n.has(v))return{indexHtml:o,script:f,entry:v,via:`${u.config} (outfile ${u.outfile})`}}}return null}var xc=new Set(["test","tests","__tests__","fixtures","__fixtures__","__mocks__","e2e","cypress"]);function vt(e){let t=String(e).replace(/\\/g,"/").split("/").filter(Boolean);if(!t.length)return!1;for(let n of t.slice(0,-1))if(xc.has(n.toLowerCase()))return!0;return/\.(test|spec)\.[^./]+$/i.test(t[t.length-1])}function kc(e){let t=xe.join(e,"package.json");if(!zn.existsSync(t))return null;try{return JSON.parse(zn.readFileSync(t,"utf-8"))}catch{return null}}function Sc(e){return[...Object.keys(e.dependencies??{}),...Object.keys(e.devDependencies??{})]}function bc(e){let t=!!e.workspaces,n=Object.keys(e.dependencies??{}).length>0,s=!!(e.scripts&&e.scripts.start);return t&&!n&&!s}var $c=["react","vue","svelte","next","vite","webpack","parcel"],Nc=["express","fastify","koa","hapi","socket.io","ws"],Ic=[{deps:["mongodb","mongoose"],label:"MongoDB"},{deps:["redis","ioredis"],label:"Redis"},{deps:["pg","postgres"],label:"PostgreSQL"},{deps:["mysql","mysql2"],label:"MySQL"},{deps:["sqlite3","better-sqlite3"],label:"SQLite"},{deps:["@prisma/client"],label:"Prisma"},{deps:["drizzle-orm"],label:"Drizzle"}];function jc(e){let t=e.some(s=>$c.includes(s)),n=e.some(s=>Nc.includes(s));return t&&!n?"client":n&&!t||n&&t?"server":"unknown"}function Ec(e){let t=[];for(let{deps:n,label:s}of Ic)n.some(o=>e.includes(o))&&!t.includes(s)&&t.push(s);return t}function ws(e){let t=new Set(["node_modules",".git","dist","build",".next","coverage"]);try{return zn.readdirSync(e,{withFileTypes:!0}).filter(n=>n.isDirectory()&&!t.has(n.name)&&!n.name.startsWith(".")).map(n=>xe.join(e,n.name))}catch{return[]}}function xs(e,t=null){let n=[e];for(let o of ws(e)){n.push(o);for(let r of ws(o))n.push(r)}let s=[];for(let o of n){let r=kc(o);if(!r||bc(r))continue;let i=Sc(r);s.push({name:r.name||xe.basename(o),rootPath:o,isRepoRoot:xe.resolve(o)===xe.resolve(e),kind:jc(i),datastores:Ec(i)})}if(t){let o=new Set(t.map(i=>xe.resolve(i))),r=new Set(s.map(i=>xe.resolve(i.rootPath)));for(let i of n)xe.resolve(i)===xe.resolve(e)||r.has(xe.resolve(i))||vt(xe.relative(e,i)+"/x")||Kt(i,t,o)&&s.push({name:xe.basename(i),rootPath:i,isRepoRoot:!1,kind:"client",datastores:[],webRoot:!0})}return s}function rt(e,t){let n=null,s=-1;for(let o of t)o.isRepoRoot&&t.length>1&&!o.ownsLeftovers||(e===o.rootPath||e.startsWith(o.rootPath+xe.sep))&&o.rootPath.length>s&&(n=o.name,s=o.rootPath.length);return n}var Cc=5,Rc=.1;function ks(e,t,n){let s=xe.basename(xe.resolve(n)),o=a=>({name:a,rootPath:n,isRepoRoot:!0,ownsLeftovers:!0,kind:"unknown",datastores:[]});if(!t.length)return{services:e,added:null};if(!e.length)return{services:[o(s)],added:{name:s,reason:"no package.json found: the repo root is the one service",leftover:t.length}};let r=t.filter(a=>!rt(a,e)).length;if(r<Cc||r<Rc*t.length)return{services:e,added:null,leftover:r};let i=e.find(a=>a.isRepoRoot);if(i)return i.ownsLeftovers=!0,{services:e,added:{name:i.name,reason:`${r} of ${t.length} files sit outside every nested package: owned by the root package ${i.name}`,leftover:r}};let c=s;return e.some(a=>a.name.toLowerCase()===c.toLowerCase())&&(c=`${s} (root)`),{services:[...e,o(c)],added:{name:c,reason:`${r} of ${t.length} files sit outside every nested package: owned by a service named after the repo folder`,leftover:r}}}function Ss(e,t=[]){let n=[];for(let[s,o]of e){let r=Jt(s),i=rt(s,t);n.push({id:`${s}::__module_root__`,name:"module root",filePath:s,startLine:0,endLine:Number.MAX_SAFE_INTEGER,category:r,serviceName:i,type:"moduleRoot",bodyHash:o.moduleBodyHash??null});for(let c of o.functions)n.push({id:Yt(s,c.name),name:c.name,filePath:s,startLine:c.startLine,endLine:c.endLine,params:c.params,returns:c.returns,category:r,serviceName:i,bodyHash:c.bodyHash??null,type:"function"});for(let c of o.arrowFunctions)n.push({id:Yt(s,c.name),name:c.name,filePath:s,startLine:c.startLine,endLine:c.endLine,params:c.params,returns:c.returns,category:r,serviceName:i,bodyHash:c.bodyHash??null,type:"arrowFunction"});for(let c of o.classMethods)n.push({id:Yt(s,`${c.className}.${c.methodName}`),name:c.methodName,className:c.className,filePath:s,startLine:c.startLine,endLine:c.endLine,params:c.params,returns:c.returns,category:r,serviceName:i,bodyHash:c.bodyHash??null,type:"classMethod"})}return n}function Ae(e,t){let n=[];for(let r of t.routes??[])r.isInlineHandler&&n.push({item:r,line:r.startLine,key:`route:${String(r.method).toUpperCase()} ${r.path}`});for(let r of t.listeners??[])r.isInlineHandler&&n.push({item:r,line:r.startLine,key:`listener:${r.targetName??"unknown"}.${r.eventName}`});for(let r of t.socketListeners??[])r.isInlineHandler&&n.push({item:r,line:r.startLine,key:`socket:${r.eventName}`});n.sort((r,i)=>r.line-i.line);let s=new Map,o=new Map;for(let{item:r,key:i}of n){let c=(s.get(i)??0)+1;s.set(i,c),o.set(r,`${e}::${i}${c>1?`#${c}`:""}`)}return o}function bs(e,t=[]){let n=[];for(let[s,o]of e){let r=Jt(s),i=rt(s,t),c=t.find(l=>l.name===i),a=Ae(s,o);for(let l of o.routes??[]){if(!l.isInlineHandler)continue;let f=`${l.method.toUpperCase()} ${l.path}`;n.push({id:a.get(l),name:`${f} (inline handler)`,filePath:s,startLine:l.handlerStartLine??l.startLine,endLine:l.handlerEndLine??l.startLine,category:r,serviceName:i,type:"inlineHandler",isEntryPoint:!0,bodyHash:l.handlerBodyHash??null,trigger:{type:"route",label:f,resolvedVia:"inline"}})}for(let l of o.listeners??[])l.isInlineHandler&&n.push({id:a.get(l),name:`${l.eventName} (inline handler)`,filePath:s,startLine:l.handlerStartLine??l.startLine,endLine:l.handlerEndLine??l.startLine,category:r,serviceName:i,type:"inlineHandler",isEntryPoint:!0,bodyHash:l.handlerBodyHash??null,trigger:{type:"listener",label:l.eventName,resolvedVia:"inline"}});if(c?.kind==="server")for(let l of o.socketListeners??[])l.isInlineHandler&&n.push({id:a.get(l),name:`${l.eventName} (inline handler)`,filePath:s,startLine:l.handlerStartLine??l.startLine,endLine:l.handlerEndLine??l.startLine,category:r,serviceName:i,type:"inlineHandler",isEntryPoint:!0,bodyHash:l.handlerBodyHash??null,trigger:{type:"socketListener",label:l.eventName,resolvedVia:"inline"}})}return n}import _c from"node:fs";import Lc from"node:crypto";var $s=e=>Lc.createHash("sha256").update(e).digest("hex");function Ns(e,t){return e.map(n=>[t(n),$s(_c.readFileSync(n))]).sort((n,s)=>n[0]<s[0]?-1:n[0]>s[0]?1:0)}function Xt(e){return $s(e.map(([t,n])=>`${t}\0${n}`).join(`
|
|
9
|
+
`))}import Wn from"node:path";function Qt(e){let t=Wn.resolve(e),n=t.split(Wn.sep).join("/"),s=[[t.toLowerCase(),t.length,Wn.sep],[n.toLowerCase(),n.length,"/"]],o=Math.max(s[0][1],s[1][1])+1,r=i=>{if(typeof i!="string")return i;let c=i.length>o?i.slice(0,o).toLowerCase():i.toLowerCase();if(c===s[0][0]||c===s[1][0])return".";for(let[a,l,f]of s)if(c.startsWith(a+f)){let y=i.slice(l+1),u=y.indexOf("::");return(u<0?y:y.slice(0,u)).split("\\").join("/")+(u<0?"":y.slice(u))}return i};return{rel:r,repoRoot:n,replacer:(i,c)=>typeof c=="string"?r(c):c,json:(i,c)=>JSON.stringify(i,(a,l)=>typeof l=="string"?r(l):l,c),walk:i=>Zt(i,r),clone:i=>{try{return JSON.parse(JSON.stringify(i,(c,a)=>typeof a=="string"?r(a):a))}catch(c){if(!(c instanceof RangeError))throw c;return Zt(i,r)}}}}function Zt(e,t){if(typeof e=="string")return t(e);if(Array.isArray(e))return e.map(n=>Zt(n===void 0||typeof n=="function"?null:n,t));if(e&&typeof e=="object"){let n={};for(let s of Object.keys(e)){let o=e[s];o!==void 0&&typeof o!="function"&&(n[s]=Zt(o,t))}return n}return e}function Is(e){let t=e.map((s,o)=>({e:s,i:o})).sort((s,o)=>String(s.e.fromNodeId).localeCompare(String(o.e.fromNodeId))||(s.e.line??0)-(o.e.line??0)||(s.e.column??0)-(o.e.column??0)||s.i-o.i),n=new Map;for(let{e:s}of t){let o=s.calleeNameRaw??s.eventName??s.url??"",r=`${s.fromNodeId??"\u2205"} | ${s.callKind??s.type} | ${o}`,i=(n.get(r)??0)+1;n.set(r,i),s.id=`${r} | #${i}`}return e}function js(e){let t=new Map;for(let n of e)t.has(n.id)||t.set(n.id,[]),t.get(n.id).push(n);for(let[n,s]of t)s.length<2||(s.sort((o,r)=>o.startLine-r.startLine||o.endLine-r.endLine),s.forEach((o,r)=>{r>0&&(o.id=`${n}#${r+1}`)}));return e}function ce(e,t){let n=null;for(let s of t)s.type!=="moduleRoot"&&e>=s.startLine&&e<=s.endLine&&(!n||s.endLine-s.startLine<n.endLine-n.startLine)&&(n=s);return n||t.find(s=>s.type==="moduleRoot")}function Es(e,t){let n=[];for(let[o,r]of e){let i=t.filter(c=>c.filePath===o);for(let c of r.calls){let a=ce(c.startLine,i);n.push({fromFileId:o,fromNodeId:a?.id??null,calleeNameRaw:c.calleeName,line:c.startLine,column:c.startColumn,branchPath:c.branchPath??[],firstArgText:c.firstArgText??null,deferred:c.deferred??!1,type:"call",callKind:c.callKind??"call",resolved:!1})}for(let c of r.methodCalls){let a=ce(c.startLine,i);n.push({fromFileId:o,fromNodeId:a?.id??null,calleeNameRaw:c.methodName,objectNameRaw:c.objectName,line:c.startLine,column:c.startColumn,branchPath:c.branchPath??[],firstArgText:c.firstArgText??null,deferred:c.deferred??!1,type:"methodCall",callKind:c.callKind??"methodCall",resolved:!1})}for(let c of r.returnEntries??[]){let a=ce(c.startLine,i);n.push({fromFileId:o,fromNodeId:a?.id??null,calleeNameRaw:c.label,line:c.startLine,column:c.startColumn,branchPath:c.branchPath??[],deferred:c.deferred??!1,type:"returnValue",resolved:!1})}for(let c of r.jsxElements){let a=ce(c.startLine,i);n.push({fromFileId:o,fromNodeId:a?.id??null,calleeNameRaw:c.calleeName,line:c.startLine,type:"call",callKind:"jsx",resolved:!1})}for(let c of r.callSites??[]){let a=ce(c.startLine,i);n.push({fromFileId:o,fromNodeId:a?.id??null,calleeNameRaw:c.calleeName,line:c.startLine,column:c.startColumn,branchPath:c.branchPath??[],firstArgText:c.firstArgText??null,deferred:c.deferred??!1,type:"callSite",callKind:c.callKind,chainHead:c.chainHead??null,chainHeadCalled:c.chainHeadCalled??!1,ctorName:c.ctorName??null,...c.thisProp?{thisProp:c.thisProp,thisMethod:c.thisMethod}:{},resolved:!1})}for(let c of r.socketEmits){let a=ce(c.startLine,i);n.push({fromFileId:o,fromNodeId:a?.id??null,eventName:c.eventName,line:c.startLine,type:"socketEmit",resolved:!1})}for(let c of r.rawSocketSends??[]){let a=ce(c.startLine,i);n.push({fromFileId:o,fromNodeId:a?.id??null,eventName:c.eventName,line:c.startLine,type:"rawSocketSend",resolved:!1})}for(let c of r.apiCalls){let a=ce(c.startLine,i);n.push({fromFileId:o,fromNodeId:a?.id??null,url:c.url,httpMethod:c.method,scope:c.scope,line:c.startLine,type:"apiCall",resolved:!1})}}let s=n.filter(o=>o.type==="apiCall").length;return n}function fe(e,t){let n=new Map;for(let s of t)s.filePath===e&&n.set(s.name,s.id);return n}function Et(e,t,n,s,o=null){if(n.has(e.calleeNameRaw))return{...e,targetNodeId:n.get(e.calleeNameRaw),confidence:.95,matchType:"local",resolved:!0};let r=[...s],i=s.legacySize??r.length,c=([,l])=>{let f=o?o.scopeOf(l):fe(l,t);return f.has(e.calleeNameRaw)?{...e,targetNodeId:f.get(e.calleeNameRaw),confidence:.85,matchType:"import",resolved:!0}:null};for(let l=0;l<i;l++){let f=c(r[l]);if(f)return f}let a=o?.bind?.resolveName(e.fromFileId,e.calleeNameRaw);if(a)return{...e,targetNodeId:a.id,confidence:.85,matchType:"import",resolved:!0};for(let l=i;l<r.length;l++){let f=c(r[l]);if(f)return f}return{...e,targetNodeId:null,confidence:0,matchType:"unresolved",resolved:!1}}function Cs(e,t,n=null){let s=n?n.method(e.objectNameRaw,e.calleeNameRaw):t.find(r=>r.type==="classMethod"&&r.className===e.objectNameRaw&&r.name===e.calleeNameRaw);if(s)return{...e,targetNodeId:s.id,confidence:.6,matchType:"methodHeuristic",resolved:!0};let o=n?.bind?.resolveMember(e.fromFileId,e.objectNameRaw,e.calleeNameRaw);return o?{...e,targetNodeId:o.id,confidence:.85,matchType:"import",resolved:!0}:{...e,targetNodeId:null,confidence:0,matchType:"unresolved",resolved:!1}}function Rs(e){return{...e,targetNodeId:null,confidence:0,matchType:"unresolvedExternal",resolved:!1}}function _s(e,t,n,s,o=null){if(e.callKind==="new"&&e.ctorName){let r=Et({...e,calleeNameRaw:e.ctorName},t,n,s,o);if(r.resolved)return{...r,calleeNameRaw:e.calleeNameRaw,matchType:r.matchType+"New"};let i=new Set([e.fromFileId,...s.values()]),c=o?o.ctorsOf(e.ctorName).find(a=>i.has(a.filePath)):t.find(a=>a.type==="classMethod"&&a.className===e.ctorName&&a.name==="constructor"&&i.has(a.filePath));return c?{...e,targetNodeId:c.id,confidence:c.filePath===e.fromFileId?.9:.8,matchType:(c.filePath===e.fromFileId?"local":"import")+"New",resolved:!0}:Rs(e)}if(e.callKind==="chainedCall"&&e.chainHead&&e.chainHeadCalled){let r=Et({...e,calleeNameRaw:e.chainHead},t,n,s,o);if(r.resolved)return{...e,targetNodeId:r.targetNodeId,confidence:r.confidence*.8,matchType:"chainHead",resolved:!0}}return Rs(e)}import qn from"node:path";import qe from"node:fs";import Y from"node:path";var Os=[".ts",".tsx",".mts",".cts",".js",".jsx",".mjs",".cjs"],Pc=["index.ts","index.tsx","index.mts","index.cts","index.js","index.jsx","index.mjs","index.cjs"],Mc={".js":[".ts",".tsx"],".jsx":[".tsx"],".mjs":[".mts"],".cjs":[".cts"]};var Ts=null,As=e=>{Ts=e},Fs=()=>Ts,Ls=e=>Y.resolve(e);function Ct(e,t){e=Y.resolve(e);let n=()=>{try{let i=Y.join(e,"package.json");if(!qe.existsSync(i))return null;let c=JSON.parse(qe.readFileSync(i,"utf8")).main;if(typeof c!="string")return null;let a=Y.resolve(e,c);return t.has(a)?a:Oc(a,t)}catch{return null}},s=Y.extname(e);if(s&&t.has(e))return e;let o=Mc[s];if(o)for(let i of o){let c=e.slice(0,-s.length)+i;if(t.has(c))return c}for(let i of Os)if(t.has(e+i))return e+i;let r=n();if(r)return r;for(let i of Pc){let c=Y.join(e,i);if(t.has(c))return c}return null}function Oc(e,t){if(Y.extname(e)&&t.has(e))return e;for(let s of Os)if(t.has(e+s))return e+s;return null}var Un=e=>{try{let n=qe.readFileSync(e,"utf8").replace(/^/,"").replace(/("(?:[^"\\]|\\.)*")|\/\/[^\n]*|\/\*[\s\S]*?\*\//g,(s,o)=>o??"");return JSON.parse(n.replace(/,(\s*[}\]])/g,"$1"))}catch{return null}};function Bs(e,t=new Set){if(t.has(e))return{baseUrl:null,paths:null};t.add(e);let n=Un(e);if(!n)return{baseUrl:null,paths:null};let s=null,o=null,r=n.extends?Array.isArray(n.extends)?n.extends:[n.extends]:[];for(let c of r){if(typeof c!="string"||!c.startsWith("."))continue;let a=Y.resolve(Y.dirname(e),c);(!qe.existsSync(a)||qe.statSync(a).isDirectory())&&(a=qe.existsSync(a+".json")?a+".json":Y.join(a,"tsconfig.json"));let l=Bs(a,t);l.baseUrl&&(s=l.baseUrl),l.paths&&(o=l.paths)}let i=n.compilerOptions??{};if(typeof i.baseUrl=="string"&&(s=Y.resolve(Y.dirname(e),i.baseUrl)),i.paths&&typeof i.paths=="object"){let c=s??Y.dirname(e);o=Object.entries(i.paths).map(([a,l])=>{let f=a.indexOf("*");return{prefix:f<0?a:a.slice(0,f),suffix:f<0?"":a.slice(f+1),wildcard:f>=0,targets:(Array.isArray(l)?l:[]).filter(y=>typeof y=="string").map(y=>Y.resolve(c,y))}}).sort((a,l)=>l.prefix.length-a.prefix.length)}return{baseUrl:s,paths:o}}function Tc(e,t){if(t=t.replace(/^\.\//,"").replace(/\/+$/,""),t.startsWith("!"))return[];let n=[],s=o=>{try{return qe.readdirSync(o,{withFileTypes:!0}).filter(r=>r.isDirectory()&&r.name!=="node_modules"&&!r.name.startsWith(".")).map(r=>Y.join(o,r.name))}catch{return[]}};if(t.endsWith("/**")){let o=Y.join(e,t.slice(0,-3)),r=i=>{for(let c of s(i))n.push(c),r(c)};r(o)}else t.endsWith("/*")?n.push(...s(Y.join(e,t.slice(0,-2)))):t.includes("*")||n.push(Y.join(e,t));return n}function Ac(e){let t=[],s=Un(Y.join(e,"package.json"))?.workspaces;Array.isArray(s)?t.push(...s):Array.isArray(s?.packages)&&t.push(...s.packages);try{let o=qe.readFileSync(Y.join(e,"pnpm-workspace.yaml"),"utf8"),r=!1;for(let i of o.split(/\r?\n/)){if(/^packages\s*:/.test(i)){r=!0;continue}if(r){let c=/^\s*-\s*['"]?([^'"#\s]+)['"]?/.exec(i);c?t.push(c[1]):/^\S/.test(i)&&(r=!1)}}}catch{}return t}function Ps(e,t){if(e==null)return null;let n=o=>{if(typeof o=="string")return o;if(Array.isArray(o)){for(let r of o){let i=n(r);if(i)return i}return null}if(o&&typeof o=="object"){for(let r of["source","import","module","default","require","node"])if(r in o){let i=n(o[r]);if(i)return i}}return null};if(typeof e=="string"||Array.isArray(e))return t==="."?n(e):null;let s=Object.keys(e);if(!s.some(o=>o.startsWith(".")))return t==="."?n(e):null;if(e[t]!=null)return n(e[t]);for(let o of s){let r=o.indexOf("*");if(r>0&&t.startsWith(o.slice(0,r))&&t.endsWith(o.slice(r+1))){let i=n(e[o]);if(i)return i.replace("*",t.slice(r,t.length-(o.length-r-1)))}}return null}function Hs(e,t,n={}){let s=Ls(e),o=new Set(t),r=new Map,i=u=>{if(r.has(u))return r.get(u);let v=null,p=Y.join(u,"tsconfig.json");return qe.existsSync(p)?v=Bs(p):u!==s&&Y.dirname(u)!==u&&u.startsWith(s)&&(v=i(Y.dirname(u))),r.set(u,v),v},c=new Map;for(let u of Ac(s))for(let v of Tc(s,u)){let p=Un(Y.join(v,"package.json"));p?.name&&!c.has(p.name)&&c.set(p.name,{dir:Ls(v),pkg:p})}let a=[...c.keys()].sort((u,v)=>v.length-u.length),l=(u,v,p)=>{let{dir:w,pkg:I}=c.get(u),g=[],b=$=>{if(!$)return;let S=Y.resolve(w,$);g.push(S);let m=Y.relative(w,S).split(Y.sep);["dist","build","lib","out","esm","cjs"].includes(m[0])&&g.push(Y.join(w,"src",...m.slice(1)))};if(v==="."){b(Ps(I.exports,"."));for(let $ of["source","module","main"])typeof I[$]=="string"&&b(I[$]);g.push(Y.join(w,"src","index"),Y.join(w,"index"))}else b(Ps(I.exports,v)),g.push(Y.join(w,v),Y.join(w,"src",v));for(let $ of g){let S=Ct($,p);if(S)return S}return null},f=u=>a.find(v=>u===v||u.startsWith(v+"/"))??null,y=(u,v)=>v?.paths?.some(p=>p.wildcard?u.startsWith(p.prefix)&&u.endsWith(p.suffix)&&u.length>=p.prefix.length+p.suffix.length:u===p.prefix)??!1;return{root:s,files:o,packages:c,isInternal(u,v){if(u.startsWith(".")||f(u))return!0;let p=i(Y.dirname(v));return!!(y(u,p)||p?.baseUrl&&!u.startsWith("@")&&Ct(Y.join(p.baseUrl,u),o))},resolve(u,v,p){if(u.startsWith("."))return Ct(Y.resolve(Y.dirname(v),u),p);let w=i(Y.dirname(v));if(w?.paths&&n.paths!==!1)for(let g of w.paths){let b=null;if(g.wildcard?u.startsWith(g.prefix)&&u.endsWith(g.suffix)&&u.length>=g.prefix.length+g.suffix.length&&(b=u.slice(g.prefix.length,u.length-g.suffix.length)):u===g.prefix&&(b=""),b!=null){for(let $ of g.targets){let S=Ct($.replace("*",b),p);if(S)return S}break}}let I=n.workspaces===!1?null:f(u);if(I){let g=l(I,u===I?".":"./"+u.slice(I.length+1),p);if(g)return g}if(w?.baseUrl&&n.paths!==!1){let g=Ct(Y.join(w.baseUrl,u),p);if(g)return g}return null}}}var Ms=new WeakMap;function Ds(e){if(e instanceof Set)return e;let t=Ms.get(e);return t||Ms.set(e,t=new Set(e)),t}var zs=new WeakMap;function Fc(e){let t=zs.get(e);return(!t||t.n!==e.length)&&(t={n:e.length,set:new Set(e)},zs.set(e,t)),t.set}function Gn(e,t,n){if(!e.startsWith("."))return null;let s=qn.dirname(t),o=qn.resolve(s,e),r=[o,...us().map(i=>`${o}${i}`),...ds().map(i=>qn.join(o,i))];for(let i of r)if(Fc(n).has(i))return i;return null}function ve(e,t,n){let s=Gn(e,t,n);if(s)return s;let o=Fs();return o?o.resolve(e,t,Ds(n)):null}function wt(e,t,n){let s=new Map;for(let o of t){let r=Gn(o.source,e,n);r&&s.set(o.source,r)}s.legacySize=s.size;for(let o of t){if(s.has(o.source))continue;let r=ve(o.source,e,n);r&&s.set(o.source,r)}return s}function Ws(e){let t=new Map,n=new Map,s=new Map;for(let o of e){if(o.type!=="classMethod")continue;let r=o.className+"\0"+o.name;n.has(r)||n.set(r,o),o.name==="constructor"&&(s.has(o.className)||s.set(o.className,[]),s.get(o.className).push(o))}return{scopeOf:o=>{let r=t.get(o);return r||(r=fe(o,e),t.set(o,r)),r},method:(o,r)=>n.get(o+"\0"+r),ctorsOf:o=>s.get(o)??[]}}function xt(e){return e?e.split("?")[0].split("/").map(t=>t.startsWith(":")||/^\d+$/.test(t)?"*":t).join("/"):""}var Bc=new Set(["function","arrowFunction"]);function Us(e,t,n,s){let o=new Map;for(let l of t){let f=o.get(l.filePath);f||o.set(l.filePath,f=[]),f.push(l)}let r=new Set;for(let l of s)l.resolved&&l.fromNodeId&&l.targetNodeId&&r.add(l.fromNodeId+"\0"+l.targetNodeId);let i=(l,f)=>(o.get(l)??[]).find(y=>Bc.has(y.type)&&f(y))??null,c=[];c.argBindings=[];let a=(l,f,y,u,v,p,w)=>{!f||!y||f.id===y.id||r.has(f.id+"\0"+y.id)||c.push({fromFileId:l,fromNodeId:f.id,calleeNameRaw:u,line:v,column:p,branchPath:[],firstArgText:null,deferred:!1,type:"reference",callKind:"reference",targetNodeId:y.id,confidence:w==="local"?.95:.85,matchType:w,resolved:!0})};for(let[l,f]of e){let y=o.get(l);if(y){for(let u of f.refArgs??[]){let v=null,p="local";if(u.b==="fn"?v=i(l,I=>I.name===u.name&&I.startLine===u.declLine):u.b==="import"&&(p="import",(u.ik==="default"||u.ik==="named"||u.ik==="cjs")&&(v=n.nodeForImport(l,u.src,u.ik,u.imp))),!v)continue;let w=ce(u.line,y);a(l,w,v,u.name,u.line,u.column,p),u.callLine!=null&&w&&w.id!==v.id&&c.argBindings.push({file:l,line:u.callLine,column:u.callColumn,targetNodeId:v.id,matchType:p,direct:u.via==="arg"})}for(let u of y){if(u.type!=="inlineHandler")continue;let v=null;for(let p of y)p===u||p.type==="moduleRoot"||p.startLine<=u.startLine&&p.endLine>=u.endLine&&!(p.startLine===u.startLine&&p.endLine===u.endLine)&&(!v||p.endLine-p.startLine<v.endLine-v.startLine)&&(v=p);v??=y.find(p=>p.type==="moduleRoot"),a(l,v,u,u.name,u.startLine,0,"local")}}}return c}function qs(e,t,n,s){let o=new Map,r=new Map;for(let c of e){if(r.set(c.id,c),c.type!=="classMethod")continue;let a=c.filePath+"\0"+c.className+"\0"+c.name,l=o.get(a);l?l.push(c):o.set(a,[c])}let i=(c,a)=>{for(let l of o.keys())if(l.startsWith(c+"\0"+a+"\0"))return!0;return!1};return function(a){let l=r.get(a.fromNodeId);if(!l||l.type!=="classMethod")return null;let f=t.get(a.fromFileId),y=(f?.classProps??[]).find(I=>I.className===l.className&&I.prop===a.thisProp);if(!y)return null;let u=null,v=null,p=(f.importBindings??[]).find(I=>I.local===y.type);if(p){let I=p.kind==="default"||p.kind==="named"?s.resolveImport(a.fromFileId,p.source,p.kind,p.imported):null;I?.local&&I.local!=="default"&&(u=I.file,v=I.local)}else i(a.fromFileId,y.type)&&(u=a.fromFileId,v=y.type);if(!u)return null;let w=o.get(u+"\0"+v+"\0"+a.thisMethod);return!w||w.length!==1?null:{...a,targetNodeId:w[0].id,confidence:.9,matchType:"typedProperty",resolved:!0}}}var Hc=new Set(["function","arrowFunction"]);function en(e,t,n){let s=new Map;for(let f of e){if(!Hc.has(f.type))continue;let y=f.filePath+"\0"+f.name;s.has(y)||s.set(y,f)}let o=new Map,r=(f,y)=>{let u=o.get(f);if(!u){u=new Map;for(let v of t.get(f)?.importBindings??[])u.has(v.local)||u.set(v.local,v);o.set(f,u)}return u.get(y)??null},i=(f,y)=>n(f).get(y)??null;function c(f,y,u=new Set){let v=f+"\0"+y;if(u.has(v))return null;u.add(v);let p=t.get(f)?.exportBindings;if(!p)return null;if(y==="default"){if(p.default)return{file:f,local:p.default==="<anon>"?"default":p.default}}else if(p.named?.[y])return{file:f,local:p.named[y]};for(let w of p.reexports??[]){if(w.exported!==y)continue;let I=i(f,w.source);if(I)return c(I,w.imported,u)}for(let w of p.nsReexports??[]){if(w.exported!==y)continue;let I=i(f,w.source);if(I)return{moduleFile:I}}if(y!=="default")for(let w of p.stars??[]){let I=i(f,w),g=I?c(I,y,u):null;if(g)return g}return null}let a=f=>f?.local?s.get(f.file+"\0"+f.local)??null:null;function l(f,y,u,v){let p=i(f,y);return p?u==="default"?c(p,"default"):u==="named"?c(p,v):{moduleFile:p,cjs:u==="cjs"}:null}return{lookupExport:c,resolveImport:l,nodeForImport(f,y,u,v){let p=l(f,y,u,v);return p?.moduleFile&&p.cjs?a(c(p.moduleFile,"default")):a(p)},resolveName(f,y){let u=r(f,y);return u?this.nodeForImport(f,u.source,u.kind,u.imported):null},resolveMember(f,y,u){let v=r(f,y);if(!v)return null;let p=l(f,v.source,v.kind,v.imported);return p?.moduleFile?a(c(p.moduleFile,u)):null},classForImport(f,y){let u=r(f,y);if(!u)return null;let v=l(f,u.source,u.kind,u.imported);return v?.local?{file:v.file,className:v.local==="default"?null:v.local}:null},bindingFor:r}}function Gs(e,t,n,s){let o=new Map,r=new Map;for(let u of t){if(u.type!=="classMethod")continue;r.set(u.id,u);let v=u.filePath+"\0"+u.className+"\0"+u.name,p=o.get(v);p?p.push(u):o.set(v,[u])}let i=(u,v)=>{let p=(n.get(u)?.classHeritage??[]).filter(w=>w.className===v);return p.length===1?p[0]:null},c=(u,v)=>(n.get(u)?.classHeritage??[]).filter(p=>p.className===v).length,a=new Map;for(let[u,v]of n)for(let p of v.classHeritage??[]){if(!p.superName)continue;let w=a.get(p.superName);w?w.push({file:u,className:p.className}):a.set(p.superName,[{file:u,className:p.className}])}let l=(u,v)=>{let p=new Set([u]),w=[u];for(;w.length;)for(let I of a.get(w.pop())??[]){if(o.has(I.file+"\0"+I.className+"\0"+v))return!0;p.has(I.className)||(p.add(I.className),w.push(I.className))}return!1},f=(u,v)=>{let w=(n.get(u)?.importBindings??[]).find(I=>I.local===v);if(w){let I=w.kind==="default"||w.kind==="named"?s.resolveImport(u,w.source,w.kind,w.imported):null;return I?.local&&I.local!=="default"&&I.file?{file:I.file,cls:I.local}:null}return c(u,v)===1?{file:u,cls:v}:null},y=0;for(let u of e){if(u.resolved||u.type!=="callSite"||u.callKind!=="thisCall"||u.thisBound===!1)continue;let v=/^this\s*\.\s*(#?[A-Za-z_$][\w$]*)$/.exec(u.calleeNameRaw??""),p=r.get(u.fromNodeId);if(!v||!p)continue;let w=v[1];if(c(p.filePath,p.className)!==1||l(p.className,w))continue;let I=p.filePath,g=p.className,b=null,$="thisMethod";for(let S=0;S<12;S++){let m=o.get(I+"\0"+g+"\0"+w);if(m){b=m.length===1?m[0]:null;break}let d=i(I,g);if(!d||!d.superName||d.unknownSuper)break;let k=f(I,d.superName);if(!k)break;({file:I,cls:g}=k),$="thisMethodInherited"}b&&(Object.assign(u,{targetNodeId:b.id,confidence:$==="thisMethod"?.9:.85,matchType:"thisMethod",thisInherited:$==="thisMethodInherited",resolved:!0}),y++)}return y}function Ys(e,t,n,s,o,r,i){let c=[],a=Ws(t),l=new Map,f=g=>l.get(g)??wt(g,n.get(g)?.imports??[],s);a.bind=en(t,n,f);let y=qs(t,n,f,a.bind),u=new Map;for(let g of e)u.has(g.fromFileId)||u.set(g.fromFileId,[]),u.get(g.fromFileId).push(g);for(let[g,b]of u){let $=n.get(g),S=fe(g,t),m=wt(g,$.imports,s);l.set(g,m);for(let d of b)if(d.type==="call")c.push(Et(d,t,S,m,a));else if(d.type==="methodCall")c.push(Cs(d,t,a));else if(d.type==="callSite")c.push((d.thisProp?y(d):null)??_s(d,t,S,m,a));else if(d.type==="returnValue")c.push({...d,targetNodeId:null,confidence:0,matchType:"returnValue",resolved:!1});else if(d.type==="apiCall")if(d.scope==="external")c.push({...d,targetNodeId:null,confidence:null,matchType:"externalService",resolved:!1});else{let k=xt(d.url),h=o.get(k);h?c.push({...d,targetNodeId:h,confidence:.5,matchType:"crossLayer",resolved:!0}):c.push({...d,targetNodeId:null,confidence:0,matchType:"unresolved",resolved:!1})}else if(d.type==="socketEmit"){let k=r.get(d.eventName);k?c.push({...d,targetNodeId:k,confidence:.5,matchType:"crossLayer",resolved:!0}):c.push({...d,targetNodeId:null,confidence:0,matchType:"unresolved",resolved:!1})}else if(d.type==="rawSocketSend"){let k=i?.get(d.eventName);k?c.push({...d,targetNodeId:k,confidence:.5,matchType:"crossLayer",resolved:!0}):c.push({...d,targetNodeId:null,confidence:0,matchType:"unresolved",resolved:!1})}}let v=Us(n,t,a.bind,c);for(let g of v)c.push(g);let p=new Map;for(let g of c){if(g.resolved||g.line==null||g.type!=="call"&&g.type!=="methodCall"&&g.type!=="callSite")continue;let b=g.fromFileId+" "+g.line+" "+g.column;(p.get(b)??p.set(b,[]).get(b)).push(g)}let w=[...v.argBindings].sort((g,b)=>b.direct-g.direct),I=new Set;for(let g of w){let b=g.file+" "+g.line+" "+g.column;if(I.has(b))continue;let $=(p.get(b)??[]).find(S=>S.fromNodeId!==g.targetNodeId);$&&(I.add(b),Object.assign($,{targetNodeId:g.targetNodeId,confidence:g.matchType==="local"?.95:.85,matchType:"argument",resolved:!0,viaArgument:!0}))}return Gs(c,t,n,a.bind),c}import Dc from"node:crypto";var zc=200,Js=(e,t)=>t.length<=zc?e+t:e+"#"+t.length+":"+Dc.createHash("sha256").update(t).digest("base64"),Wc=20,Uc=40;function Vs(e){let t=new Map,n=new WeakMap,s=a=>{if(typeof a=="string")return a.length>=Wc?Js("s",a):null;if(a&&typeof a=="object"){let l=n.get(a);if(l===void 0){let f=JSON.stringify(a);l=f.length>=Uc?Js("j",f):"",n.set(a,l)}return l||null}return null};(function a(l){let f=s(l);if(f){let y=t.get(f)??0;if(t.set(f,y+1),y>0)return}if(Array.isArray(l))for(let y of l)a(y);else if(l&&typeof l=="object")for(let y of Object.values(l))a(y)})(e);let o=[],r=new Map,i=a=>{let l=s(a),f=l&&t.get(l)>1;if(f&&r.has(l))return r.get(l);let y;if(typeof a=="string"?y=JSON.stringify(a):Array.isArray(a)?y="["+a.map(i).join(",")+"]":a&&typeof a=="object"?y="{"+Object.entries(a).map(([v,p])=>JSON.stringify(v)+":"+i(p)).join(",")+"}":y=JSON.stringify(a),!f)return y;let u="$"+o.length.toString(36);return o.push(`const ${u}=${y};`),r.set(l,u),u},c=i(e);return`(() => {${o.join(`
|
|
10
10
|
`)}
|
|
11
|
-
return ${c};})()`}function Yn(e,t,n,s){if(!e)return{targetId:null,via:null};if(n.has(e))return{targetId:n.get(e),via:"in-file"};if(s)for(let[,o]of s){let r=fe(o,t);if(r.has(e))return{targetId:r.get(e),via:"cross-file"}}return{targetId:null,via:null}}function Gs(e,t,n,s,o,r=[],i=null){if(!n.some(a=>!a.isInlineHandler)&&!s.some(a=>!a.isInlineHandler)&&!r.some(a=>!a.isInlineHandler))return e;let c=e.map(a=>({...a}));for(let a of n){if(a.isInlineHandler)continue;let l=a.nest?e.find(u=>u.type==="classMethod"&&u.filePath===t&&u.className===a.nest.className&&u.name===a.nest.methodName):null,{targetId:f,via:y}=a.nest?{targetId:l?.id??null,via:"in-file"}:Yn(a.handlerName,e,o,i);if(f){let u=c.find(v=>v.id===f);u&&(u.isEntryPoint=!0,u.trigger={type:"route",label:`${a.method.toUpperCase()} ${a.path}`,resolvedVia:y})}}for(let a of s){if(a.isInlineHandler)continue;let{targetId:l,via:f}=Yn(a.handlerName,e,o,i);if(l){let y=c.find(u=>u.id===l);y&&(y.isEntryPoint=!0,y.trigger={type:"listener",label:a.eventName,resolvedVia:f})}}for(let a of r){if(a.isInlineHandler)continue;let{targetId:l,via:f}=Yn(a.handlerName,e,o,i);if(l){let y=c.find(u=>u.id===l);y&&(y.isEntryPoint=!0,y.trigger={type:"socketListener",label:a.eventName,resolvedVia:f})}}return c}function Jn(e){let t=new Map,n=new Map;for(let s of e)s.resolved&&(t.set(s.fromNodeId,(t.get(s.fromNodeId)??0)+1),n.set(s.targetNodeId,(n.get(s.targetNodeId)??0)+1));return{outgoing:t,incoming:n}}function Ys(e,t,n=Jn(t)){if(e.type==="moduleRoot")return 0;let s=n.outgoing.get(e.id)??0,o=n.incoming.get(e.id)??0,r=e.exported?1.5:1;return s/(o+1)*r}function Js(e,t){let n=Jn(t),s=new Set;for(let i of e)n.incoming.has(i.id)&&s.add(i.filePath);let r=e.filter(i=>!(i.isEntryPoint||i.type==="moduleRoot"||!n.incoming.has(i.id)&&s.has(i.filePath))).map(i=>({...i,fallbackScore:Ys(i,t,n)}));return r.sort((i,c)=>c.fallbackScore-i.fallbackScore),r.slice(0,15)}function en(e){let t=new Map;for(let n of e)!n.resolved||!n.fromNodeId||!n.targetNodeId||(t.has(n.fromNodeId)||t.set(n.fromNodeId,[]),t.get(n.fromNodeId).push({targetNodeId:n.targetNodeId,line:n.line??null,column:n.column??null,branchPath:n.branchPath??[],edgeType:n.type}));return t}function tn(e,t,n,s=8,o=null){if(o){let l=tn(e,o,n,s),f=new Set(l.map(p=>p.nodeId)),y=l.slice();y.extraNodeIds=new Set;let u=p=>n.find(w=>w.id===p)?.category??"unknown",v=l.slice();for(;v.length>0;){let p=v.shift();if(!(p.depth>=s))for(let w of t.get(p.nodeId)||[]){let I=w.targetNodeId;if(f.has(I))continue;f.add(I);let g={nodeId:I,depth:p.depth+1,parentNodeId:p.nodeId,category:u(I),callLine:w.line,callColumn:w.column,branchPath:w.branchPath,edgeType:w.edgeType};y.push(g),y.extraNodeIds.add(I),v.push(g)}}return y}let r=new Set([e]),i=l=>n.find(f=>f.id===l)?.category??"unknown",c=[{nodeId:e,depth:0,parentNodeId:null,category:i(e)}],a=[{nodeId:e,depth:0}];for(;a.length>0;){let l=a.shift();if(l.depth>=s)continue;let f=t.get(l.nodeId)||[];for(let y of f){let u=y.targetNodeId;if(r.has(u))continue;r.add(u);let v={nodeId:u,depth:l.depth+1,parentNodeId:l.nodeId,category:i(u),callLine:y.line,callColumn:y.column,branchPath:y.branchPath,edgeType:y.edgeType};c.push(v),a.push(v)}}return c}function Vs(e,t,n,s=null){return t.filter(r=>r.filePath===e.filePath&&r.id!==e.id&&r.type!=="moduleRoot").filter(r=>!(s?s.has(r.id):n.some(c=>c.resolved&&c.targetNodeId===r.id)))}var Ks=new WeakMap,Xs=new WeakMap;function Dc(e){let t=Ks.get(e);if(t&&t.length===e.length)return t;let n=new Set,s=new Set,o=new Map;for(let r of e)r.resolved&&(r.targetNodeId===void 0||r.targetNodeId===null||(s.add(r.targetNodeId),r.matchType==="crossLayer"&&n.add(r.targetNodeId)),o.set(r.fromNodeId,(o.get(r.fromNodeId)??0)+1));return t={length:e.length,crossLayerTargets:n,incoming:s,outgoing:o},Ks.set(e,t),t}function zc(e,t,n){let s=Xs.get(e);if(s&&s.length===e.length&&s.edgesRef===n)return s.calledByFile;let o=new Map;for(let r of e){if(r.type==="moduleRoot"||!n.incoming.has(r.id))continue;let i=o.get(r.filePath);i||o.set(r.filePath,i=new Set),i.add(r.id)}return Xs.set(e,{length:e.length,edgesRef:n,calledByFile:o}),o}function Zs(e,t,n){if(e.type==="moduleRoot")return!1;let s=Dc(t);if(s.crossLayerTargets.has(e.id)||(s.outgoing.get(e.id)??0)>=4||new Set((e.returns||[]).map(a=>a.condition).filter(a=>a!==null)).size>=3)return!0;if(s.incoming.has(e.id)){let a=zc(n,t,s).get(e.filePath);if(!(!!a&&a.size-(a.has(e.id)?1:0)>0)){let f=Vs(e,n,t,s.incoming);if(f.length>0)return e.lexicalSiblings=f.map(y=>y.id),!0}}return!1}function Qs(e,t,n,s,o=8,r=null,i=null){let c=[],a=new Set(e.map(y=>y.id)),l=[...e],f=new Map;for(let y of n)f.has(y.id)||f.set(y.id,y);for(;l.length>0;){let y=l.shift(),u=tn(y.id,t,n,o,i);c.push({entryPointId:y.id,entryPointName:y.name,trigger:y.trigger??null,steps:u,...u.extraNodeIds?.size?{extraNodeIds:u.extraNodeIds}:{}});let v=r?new Set(tn(y.id,r,n,o).map(p=>p.nodeId)):null;for(let p of u){if(v&&!v.has(p.nodeId)||p.nodeId===y.id||a.has(p.nodeId))continue;let w=f.get(p.nodeId);w&&Zs(w,s,n)&&(a.add(w.id),p.hasOwnSubTrace=!0,w.lexicalSiblings&&(p.lexicalSiblings=w.lexicalSiblings),l.push({id:w.id,name:w.name,trigger:null}))}}return c}function er(e,t,n=ls){return e.filter((s,o)=>{if(o===0)return!0;let r=t.find(i=>i.id===s.nodeId);return r?!n.some(i=>r.name.toLowerCase().includes(i)):!0})}function tr(e){return e.steps.filter(n=>n.depth>0&&!e.extraNodeIds?.has(n.nodeId)).map(n=>n.nodeId).sort().join(" | ")}function nr(e){let t=new Map;for(let n of e){let s=tr(n),o=s===""?`__no_calls__${n.entryPointName}`:s;t.has(o)||t.set(o,[]),t.get(o).push(n)}return t}function or(e){let t=e[0];return{steps:t.steps,entryPointNames:e.map(n=>n.entryPointName),occurrences:e.length,name:t.entryPointName,trigger:t.trigger,tier:e.some(n=>n.origin==="physical")?"physical":"guessed",tierOrigin:e.some(n=>n.origin==="physical")?"physical":t.origin}}import nn from"node:path";function sr(e){if(!e.trigger)return null;if(e.trigger.type==="route")return`${e.trigger.label.split(" ")[1].split("/").filter(Boolean).join(" ").replace(/[-_]/g," ").split(" ").map(o=>o.charAt(0).toUpperCase()+o.slice(1)).join(" ")} Flow`;if(e.trigger.type==="listener"){let t=e.trigger.label;return`${t.charAt(0).toUpperCase()+t.slice(1)} Flow`}return null}function rr(e){return e.name.replace(/([A-Z])/g," $1").trim().split(" ").map(n=>n.charAt(0).toUpperCase()+n.slice(1)).join(" ")}var ir=60,Wc=24;function cr(e,t=null){let n=e.map(s=>{let o=sr(s),r=s.trigger?.workflowName??o??rr(s);return{...s,name:r}});return t?.nodes?Yc(n,t.nodes):n}var Vn=(e,t)=>e.length>t?e.slice(0,t-1)+"\u2026":e,Uc=new Set(["function","arrowFunction","classMethod"]);function qc(e){let t=new Map(e.map(o=>[o.id,o])),n=new Map,s=o=>{let r=n.get(o);return r||(r=e.filter(i=>i.filePath===o&&Uc.has(i.type)),n.set(o,r)),r};return o=>{let r=t.get(o.steps[0].nodeId);if(!r)return[null,null,null];let i=null;if(r.type==="classMethod")i=r.className;else{let l=null;for(let f of s(r.filePath))f===r||!(f.startLine<=r.startLine&&f.endLine>=r.endLine)||f.startLine===r.startLine&&f.endLine===r.endLine||(!l||f.endLine-f.startLine<l.endLine-l.startLine)&&(l=f);l&&(i=l.type==="classMethod"?l.className:l.name)}let c=null;if(o.trigger?.type==="route")c=String(o.trigger.label).split(" ")[0];else if(o.trigger?.type==="listener"){let l=/::listener:([^.#]+)\./.exec(r.id);l&&(c=l[1])}let a=nn.basename(r.filePath,nn.extname(r.filePath));return a==="index"&&(a=nn.basename(nn.dirname(r.filePath))),[i||null,c||null,a||null]}}var Gc=(e,t)=>{let n=t.map(s=>Vn(s,Wc)).join(", ");return e.endsWith(")")?e.slice(0,-1)+", "+n+")":e+" ("+n+")"};function Yc(e,t){let n=qc(t),s=e.map(i=>({w:i,base:i.name,parts:[],used:new Set,stuck:!1,q:null})),o=i=>i.parts.length?Gc(i.base,i.parts):i.base,r=()=>{let i=new Map;for(let c of s){let a=o(c);(i.get(a)??i.set(a,[]).get(a)).push(c)}return[...i.values()].filter(c=>c.length>1)};for(let i=0;i<4;i++){let c=!1;for(let a of r()){if(a.some(u=>u.stuck))continue;for(let u of a)u.q??=n(u.w);let l=[0,1,2].filter(u=>a.every(v=>!v.used.has(u))),f=l.find(u=>new Set(a.map(v=>v.q[u]??"")).size>1),y=f!==void 0;if(y||(f=l.find(u=>a.every(v=>v.q[u]))),f===void 0){for(let u of a)u.stuck=!0;continue}for(let u of a)u.used.add(f),u.q[f]&&u.parts.push(u.q[f]),y||(u.stuck=!0);c=!0}if(!c)break}for(let i of r())i.sort((c,a)=>c.w.steps[0].nodeId<a.w.steps[0].nodeId?-1:c.w.steps[0].nodeId>a.w.steps[0].nodeId?1:0),i.forEach((c,a)=>{a>0&&(c.suffix=` (${a+1})`)});return s.map(i=>{let c=o(i);return i.suffix&&(c=Vn(c,ir-i.suffix.length)+i.suffix),{...i.w,name:Vn(c,ir)}})}var Jc=e=>e;function ar(e,t){let n=new Map;for(let[s,o]of e){let r=t.filter(l=>l.filePath===s);if(r[0]?.category!=="backend")continue;let i=o.routes??[],c=Ae(s,o),a=fe(s,t);for(let l of i){let f=xt(l.path);if(l.isInlineHandler){let u=c.get(l);n.set(f,u);continue}if(l.nest){let u=Jc(r).find(v=>v.type==="classMethod"&&v.className===l.nest.className&&v.name===l.nest.methodName);u&&n.set(f,u.id);continue}if(!l.handlerName||!a.has(l.handlerName))continue;let y=a.get(l.handlerName);n.set(f,y)}}return n}import it from"node:fs";import te from"node:path";var on=[".ts",".tsx",".mts",".cts",".js",".jsx",".mjs",".cjs"],Vc=/(^|\/)(dist|build|out|built|compiled|esm|cjs|lib|output)(\/|$)/,lr=/(^|\/)(dist|build|out|built|compiled|esm|cjs|output)(\/|$)/,Kc=/\b(esbuild|tsup|tsdown|tsc|rollup|webpack|ncc|swc|babel|vite|parcel|bun\s+build|pkg|unbuild|microbundle|rspack)\b/,Xc=/^(tsup|tsdown|unbuild|build|rollup|vite|webpack|esbuild|rspack)[\w.-]*\.(mts|cts|mjs|cjs|js|ts)$/i,Fe=e=>{try{return it.statSync(e).isFile()}catch{return!1}},Kn=e=>e.split(te.sep).join("/"),Xn=e=>{if(Fe(e)&&on.includes(te.extname(e))&&!/\.d\.ts$/.test(e))return e;let t=e.replace(/\.(m|c)?js$/,"");for(let n of on)if(Fe(t+n)&&!/\.d\.ts$/.test(t+n))return t+n;return null},sn=(e,t)=>{let n=te.relative(e,t);return n&&!n.startsWith("..")&&!te.isAbsolute(n)&&!/(^|[\\/])node_modules([\\/]|$)/.test(n)};function Zc(e,t){let n=Fe(t+".map")?t+".map":null;if(!n&&Fe(t))try{let c=it.readFileSync(t,"utf8").slice(-400),a=/sourceMappingURL=([^\s*]+)/.exec(c);if(a&&!a[1].startsWith("data:")){let l=te.resolve(te.dirname(t),a[1]);Fe(l)&&(n=l)}}catch{}if(!n)return null;let s;try{s=JSON.parse(it.readFileSync(n,"utf8"))}catch{return null}let o=te.resolve(te.dirname(n),s.sourceRoot??""),r=(s.sources??[]).map(c=>te.resolve(o,c)).filter(c=>sn(e,c)&&Fe(c)&&on.includes(te.extname(c)));if(r.length===1)return r[0];let i=te.basename(t).replace(/\.(m|c)?js$/,"");return r.find(c=>te.basename(c).replace(/\.[^.]+$/,"")===i)??null}function Qc(e){try{return JSON.parse(it.readFileSync(e,"utf8").replace(/\/\*[\s\S]*?\*\//g,"").replace(/^\s*\/\/.*$/gm,"").replace(/,(\s*[}\]])/g,"$1"))}catch{return null}}function ea(e,t){for(let n of["tsconfig.build.json","tsconfig.json"]){let o=Qc(te.join(e,n))?.compilerOptions;if(!o?.outDir)continue;let r=Kn(te.normalize(o.outDir)).replace(/^\.\//,"").replace(/\/$/,"");if(!(t===r||t.startsWith(r+"/")))continue;let i=t.slice(r.length+1),c=o.rootDir?o.rootDir:it.existsSync(te.join(e,"src"))?"src":".",a=Xn(te.resolve(e,c,i));if(a)return a}return null}function ta(e,t){let n=t.split("/"),s=n.findIndex(r=>/^(dist|build|out|built|compiled|esm|cjs|lib|output)$/.test(r));if(s<0)return null;let o=n.slice(s+1).join("/");for(let r of["src","source","sources"]){let i=Xn(te.resolve(e,...n.slice(0,s),r,o));if(i&&sn(e,i))return i}return null}function na(e,t,n){let s=te.basename(n).replace(/\.(m|c)?js$/,"");for(let o of["build","compile","bundle","prepare","prepublishOnly","prepack","postinstall"]){let r=t.scripts?.[o];if(!r||!Kc.test(r))continue;let i=[];for(let l of r.split(/\s+/).map(f=>f.replace(/^["']|["']$/g,"").replace(/^--?[\w-]+=/,""))){if(!on.includes(te.extname(l))||/\.d\.ts$/.test(l))continue;let f=te.resolve(e,l);Fe(f)&&sn(e,f)&&!lr.test(Kn(te.relative(e,f)))&&i.push(f)}let c=[...new Set(i)];if(c.length===1)return c[0];let a=c.filter(l=>te.basename(l).replace(/\.[^.]+$/,"")===s);if(a.length===1)return a[0];if(c.length)return c[0]}return null}function oa(e,t){let n=[];try{n=it.readdirSync(e).filter(i=>Xc.test(i)).sort()}catch{return null}let s=te.basename(t).replace(/\.(m|c)?js$/,""),o=[];for(let i of n){let c;try{c=it.readFileSync(te.join(e,i),"utf8")}catch{continue}for(let a of c.matchAll(/\bentry(?:Points)?\s*:\s*[[{]?\s*(?:["'\w-]+\s*:\s*)?["'`]([^"'`]+)["'`]/g)){let l=Xn(te.resolve(e,a[1]));l&&sn(e,l)&&o.push(l)}}let r=[...new Set(o)];return r.length===1?r[0]:r.find(i=>te.basename(i).replace(/\.[^.]+$/,"")===s)??null}function rn(e,t,n){if(typeof t!="string"||!t)return null;let s=Kn(te.normalize(t)).replace(/^\.\//,""),o=te.resolve(e,s);if(!Vc.test(s)||Fe(o)&&!lr.test(s)||Fe(o)&&/\.ts$/.test(o))return null;let i=[["sourcemap",()=>Zc(e,o)],["tsconfig outDir",()=>ea(e,s)],["convention",()=>Fe(o)?null:ta(e,s)],["build script",()=>na(e,n??{},s)],["build config",()=>oa(e,s)]];for(let[c,a]of i){let l=null;try{l=a()}catch{}if(l&&l!==o)return{file:l,how:c}}return null}function fr(e,t){let n=new Map;for(let[s,o]of e){let r=o.socketListeners??[],i=Ae(s,o),c=fe(s,t);for(let a of r){if(a.isInlineHandler){let f=i.get(a);n.set(a.eventName,f);continue}if(!a.handlerName||!c.has(a.handlerName))continue;let l=c.get(a.handlerName);n.set(a.eventName,l)}}return n}import Zn from"node:fs";import U from"node:path";var Ne=e=>String(e??"").trim().replace(/^["']|["']$/g,""),cn=e=>e.replace(/^\s*#.*$/,"").replace(/\s+#.*$/,"");function ur(e){let t=/^(\/[A-Za-z0-9_\-./]*?)\/?(?=$|[:(*{[])/.exec(String(e).trim()),n=t?t[1]:"";return n==="/"?"":n.replace(/\/+$/,"")}function dr(e,t){let n=e.split(/\r?\n/).map(cn),s=v=>v.length-v.trimStart().length,o=[],r=null,i=!1,c=null,a=!1,l=0,f=null,y=()=>{f?.key&&f.fromService&&f.fromService!=="?"&&r.hostRefs.push({name:f.key,service:f.fromService,property:f.property}),f=null},u=(v,p,w)=>{p==="name"?v.name=Ne(w):p==="rootDir"?v.rootDir=Ne(w):p==="startCommand"&&(v.startCommand=Ne(w))};for(let v of n){if(!v.trim())continue;let p=s(v),w=v.trim();if(p===0){y(),r=null,a=!1,i=/^services\s*:/.test(w),c=null;continue}if(!i)continue;let I=w.startsWith("-");if(I&&(c==null||p===c)){c=p,y(),r={name:null,rootDir:null,startCommand:null,kept:[],hostRefs:[]},o.push(r),a=!1;let b=/^-\s*([A-Za-z]+)\s*:\s*(.*)$/.exec(w);b&&u(r,b[1],b[2]);continue}if(!r)continue;let g=/^(?:-\s*)?([A-Za-z]+)\s*:\s*(.*)$/.exec(w);if(g){if(g[1]==="envVars"){y(),a=!0,l=p;continue}if(a&&p>l){if(I&&(y(),f={key:null,fromService:null,property:null}),!f)continue;if(g[1]==="key")f.key=Ne(g[2]);else if(g[1]==="value"&&f.key){let b=Ge(f.key,Ne(g[2]),t);b&&r.kept.push(b)}else g[1]==="fromService"?f.fromService="?":g[1]==="name"&&f.fromService==="?"?f.fromService=Ne(g[2]):g[1]==="property"&&(f.property=Ne(g[2]));continue}a&&(y(),a=!1),u(r,g[1],g[2])}}return y(),o.filter(v=>v.name)}function pr(e,t){let n={app:null,ports:[],kept:[]},s="";for(let o of e.split(/\r?\n/)){let r=cn(o).trim();if(!r)continue;let i=/^\[\[?\s*([A-Za-z0-9_.]+)\s*\]\]?$/.exec(r);if(i){s=i[1];continue}let c=/^([A-Za-z_][A-Za-z0-9_]*)\s*=\s*(.*)$/.exec(r);if(!c)continue;let[,a,l]=c;if(s===""&&a==="app"){let f=Ne(l);/^[a-z0-9][a-z0-9-]*$/i.test(f)&&(n.app=f)}else if(a==="internal_port"){let f=Number(Ne(l));Number.isInteger(f)&&f>=1&&f<=65535&&n.ports.push(f)}else if(s==="env"){let f=Ge(a,Ne(l),t);f&&n.kept.push(f)}}return n}function mr(e,t){let n={ports:[],kept:[]},s=e.replace(/\\\r?\n/g," ");for(let o of s.split(/\r?\n/)){let r=o.trim(),i=/^EXPOSE\s+(.+)$/i.exec(r);if(i){for(let a of i[1].split(/\s+/)){let l=Number(a.replace(/\/\w+$/,""));Number.isInteger(l)&&l>=1&&l<=65535&&n.ports.push(l)}continue}if(i=/^(?:ENV|ARG)\s+(.+)$/i.exec(r),!i)continue;let c=i[1];if(/^[A-Za-z_][A-Za-z0-9_]*=/.test(c)){let a=/([A-Za-z_][A-Za-z0-9_]*)=("([^"]*)"|'([^']*)'|\S*)/g,l;for(;l=a.exec(c);){let f=Ge(l[1],l[3]??l[4]??l[2],t);f&&n.kept.push(f)}}else{let a=/^([A-Za-z_][A-Za-z0-9_]*)\s+(.*)$/.exec(c);if(a){let l=Ge(a[1],Ne(a[2]),t);l&&n.kept.push(l)}}}return n}function hr(e){let t;try{t=JSON.parse(e)}catch{return[]}let n=[];for(let s of["rewrites","redirects"])for(let o of Array.isArray(t?.[s])?t[s]:[]){let r=typeof o?.destination=="string"?o.destination:"",i=/\/:[A-Za-z_]+\*?$/.test(r)?Ye(r.replace(/\/:[A-Za-z_]+\*?$/,"")):null;i&&typeof o.source=="string"&&n.push({prefix:ur(o.source),target:i,kind:`vercel.json ${s}`,strip:!0})}return n}function gr(e){let t=[],n=!1,s=null,o=()=>{if(s?.from&&s.to&&/\/:[A-Za-z_]+\*?$/.test(s.to)){let r=Ye(s.to.replace(/\/:[A-Za-z_]+\*?$/,""));r&&t.push({prefix:ur(s.from),target:r,kind:"netlify.toml redirects",strip:!0})}s=null};for(let r of e.split(/\r?\n/)){let i=cn(r).trim();if(!i)continue;let c=/^\[\[?\s*([A-Za-z0-9_.]+)\s*\]\]?$/.exec(i);if(c){o(),n=c[1]==="redirects",s=n?{}:null;continue}if(!n||!s)continue;let a=/^(from|to)\s*=\s*(.*)$/.exec(i);a&&(s[a[1]]=Ne(a[2]))}return o(),t}function yr(e,t){let n;try{n=JSON.parse(e)}catch{return[]}let s=[],o=n&&typeof n=="object"?n.env:null;if(o&&typeof o=="object")for(let r of Object.keys(o).sort()){let i=o[r],c=typeof i=="string"?i:typeof i?.value=="string"?i.value:null,a=Ge(r,c,t);a&&s.push(a)}return s}function vr(e,t,n){let s=[];if(n){let o;try{o=JSON.parse(e)}catch{return s}let r=(i,c)=>{if(!(!i||typeof i!="object"||c>4))for(let a of Object.keys(i).sort()){let l=i[a];if(/^(env|envVars|variables|environment)$/i.test(a)&&l&&typeof l=="object"&&!Array.isArray(l))for(let f of Object.keys(l).sort()){let y=typeof l[f]=="string"?l[f]:typeof l[f]?.value=="string"?l[f].value:null,u=Ge(f,y,t);u&&s.push(u)}else r(l,c+1)}};r(o,0)}else{let o="";for(let r of e.split(/\r?\n/)){let i=cn(r).trim();if(!i)continue;let c=/^\[\[?\s*([A-Za-z0-9_.]+)\s*\]\]?$/.exec(i);if(c){o=c[1];continue}let a=/^([A-Za-z_][A-Za-z0-9_]*)\s*=\s*(.*)$/.exec(i);if(a&&/(^|\.)(env|variables|environment)$/i.test(o)){let l=Ge(a[1],Ne(a[2]),t);l&&s.push(l)}}}return s}var sa=[".env.local",".env",".env.development",".env.production",".env.example"],ra=/^(PORT|HTTP_PORT|HTTPS_PORT|SERVER_PORT|API_PORT|APP_PORT|WS_PORT|WSS_PORT|WEBSOCKET_PORT|LISTEN_PORT)$/,ia=/^PUBLIC_(?:[A-Z0-9]+_)*(?:ORIGIN|URL|HOST|BASE_URL)$/,ca=new Set(["localhost","127.0.0.1","0.0.0.0","[::1]","host.docker.internal"]),aa=512*1024,wr=e=>e.split(U.sep).join("/");function ct(e){try{let t=Zn.lstatSync(e);return!t.isFile()||t.isSymbolicLink()||t.size>aa?null:Zn.readFileSync(e,"utf8")}catch{return null}}function Ye(e){let t=String(e).trim().replace(/^["']|["']$/g,"");if(!/^(https?|wss?):\/\//i.test(t))return null;try{let n=new URL(t);if(!n.hostname)return null;let s=n.protocol.replace(":",""),o=n.hostname.toLowerCase(),r=n.port?Number(n.port):null,i=n.pathname.replace(/\/+$/,"");return{scheme:s,host:o,port:r,origin:`${s}://${o}${r?":"+r:""}`,path:i}}catch{return null}}function la(e){let t=String(e).trim().replace(/^["']|["']$/g,"");return!/^[a-z0-9]([a-z0-9.-]*[a-z0-9])?(:\d{1,5})?(\/[^\s?#]*)?$/i.test(t)||!/[a-z]/i.test(t.split(/[/:]/)[0])?null:Ye("http://"+t)}var Qn=e=>{let t=String(e).trim().replace(/^["']|["']$/g,"");if(!/^\d{1,5}$/.test(t))return null;let n=Number(t);return n>=1&&n<=65535?n:null};function fa(e){let t=new Map;for(let n of e.split(/\r?\n/)){let s=/^\s*(?:export\s+)?([A-Za-z_][A-Za-z0-9_]*)\s*=\s*(.*?)\s*$/.exec(n);if(!s)continue;let o=s[2];if(/^["']/.test(o)){let r=o[0],i=o.indexOf(r,1);o=i>0?o.slice(1,i):o.slice(1)}else o=o.replace(/\s+#.*$/,"");t.set(s[1],o)}return t}function Sr(e,t,n=0,s=new Set){let o=e.get(t);return o==null||n>5||s.has(t)||(s.add(t),o=o.replace(/\$\{([A-Za-z_][A-Za-z0-9_]*)(?::?-([^}]*))?\}/g,(r,i,c)=>{let a=e.has(i)?Sr(e,i,n+1,s):void 0;return a!=null&&a!==""?a:c??""}),s.delete(t)),o}function Ge(e,t,n){if(t==null)return null;if(ra.test(e)){let o=Qn(t);return o?{name:e,kind:"port",file:n,port:o}:null}let s=Ye(t)??(/(_URL|_URI|_HOST|_HOSTNAME|_ORIGIN|_ADDR|_ENDPOINT)$/i.test(e)?la(t):null);return s?{name:e,kind:"url",file:n,...s}:null}function xr(e,t){let n=[];for(let s of[...e.keys()].sort()){let o=Sr(e,s);if(o==null)continue;let r=Ge(s,o,t);r&&n.push(r)}return n}function ua(e){let t=e.split(/\r?\n/).map(l=>l.replace(/\s+#.*$/,"").replace(/\t/g," ")),n=l=>l.length-l.trimStart().length,s=[],o=t.findIndex(l=>/^services\s*:\s*$/.test(l));if(o<0)return s;let r=null,i=null,c=null,a=0;for(o=o+1;o<t.length;o++){let l=t[o];if(!l.trim())continue;let f=n(l),y=l.trim();if(f===0)break;if(r==null&&(r=f),f===r){let u=/^([A-Za-z0-9_.-]+)\s*:\s*$/.exec(y);u&&(i={name:u[1],ports:[],env:new Map,build:null},s.push(i),c=null);continue}if(i){if(f<=r+4&&/^[A-Za-z_]+\s*:/.test(y)&&!y.startsWith("-")){let u=/^([A-Za-z_]+)\s*:\s*(.*)$/.exec(y);c=u[1],a=f,c==="build"&&u[2]&&(i.build=u[2].replace(/^["']|["']$/g,""));continue}if(c==="build"&&/^context\s*:/.test(y)){i.build=y.replace(/^context\s*:\s*/,"").replace(/^["']|["']$/g,"");continue}if(c==="ports"&&y.startsWith("-")){let v=y.slice(1).trim().replace(/^["']|["']$/g,"").replace(/\/\w+$/,"").split(":"),p=v.slice(-2).map(w=>Qn(w));v.length===1&&p[0]?i.ports.push({host:null,container:p[0]}):v.length>=2&&p[0]&&p[1]&&i.ports.push({host:p[0],container:p[1]});continue}if(c==="environment"&&f>a){let u=y.startsWith("-")?/^-\s*([A-Za-z_][A-Za-z0-9_]*)\s*=\s*(.*)$/.exec(y):/^([A-Za-z_][A-Za-z0-9_]*)\s*:\s*(.*)$/.exec(y);u&&i.env.set(u[1],u[2].replace(/^["']|["']$/g,""))}}}return s}function kr(e,t){let n=[];if(t==="vite"){let s=e.search(/\bproxy\s*:/);if(s<0)return n;let o=e.slice(s,s+2500),r=/["'`](\/[^"'`]*)["'`]\s*:\s*(?:["'`](https?:\/\/[^"'`]+)["'`]|\{[^{}]*?target\s*:\s*["'`](https?:\/\/[^"'`]+)["'`])/g,i;for(;i=r.exec(o);){let c=Ye(i[2]??i[3]);c&&n.push({prefix:i[1].replace(/\/+$/,""),target:c,kind:"vite.config proxy"})}}else if(t==="next"){let s=/source\s*:\s*["'`](\/[^"'`:*]*)[^"'`]*["'`]\s*,\s*destination\s*:\s*["'`](https?:\/\/[^"'`]+?)(?:\/:[^"'`]*)?["'`]/g,o;for(;o=s.exec(e);){let r=Ye(o[2]);r&&n.push({prefix:o[1].replace(/\/+$/,""),target:r,kind:"next.config rewrites"})}}return n}function br(e,t,n){let s=g=>wr(U.relative(e,g)),o=new Map,r=new Map,i=new Map,c=(g,b,$)=>{(g.get(b)??g.set(b,new Set).get(b)).add($)},a=(g,b,$)=>{let S=i.get(g)??i.set(g,[]).get(g);S.some(m=>m.service===b&&m.via===$)||S.push({service:b,via:$})},l=g=>{let b=[],$=U.resolve(g),S=U.resolve(e);for(let m=0;m<8&&(b.push($),!($===S||U.dirname($)===$||($=U.dirname($),!$.startsWith(S))));m++);return b},f=new Map,y=new Map,u=(g,b)=>{let $=g.env.get(b.name)??g.env.set(b.name,[]).get(b.name);$.some(S=>S.file===b.file)||$.push(b),b.kind==="port"&&g.ports.add(b.port)};function v(g,b,$){let S=d=>s(U.join($,d)),m=d=>ct(U.join($,d));for(let d of an($))if(d==="fly.toml"){let k=m(d);if(k){let h=pr(k,S(d));for(let x of h.ports)b.ports.add(x);for(let x of h.kept)u(b,x);h.app&&(a(`${h.app.toLowerCase()}.internal`,g.name,"fly.toml app name"),a(`${h.app.toLowerCase()}.fly.dev`,g.name,"fly.toml app name"))}}else if(/^Dockerfile(\..+)?$/.test(d)){let k=m(d);if(k){let h=mr(k,S(d));for(let x of h.ports)b.weakPorts.add(x);for(let x of h.kept)u(b,x)}}else if(d==="railway.json"||d==="railway.toml"){let k=m(d);if(k)for(let h of vr(k,S(d),d.endsWith(".json")))u(b,h)}else if(d==="app.json"){let k=m(d);if(k)for(let h of yr(k,S(d)))u(b,h)}else if(d==="vercel.json"){let k=m(d);if(k)for(let h of hr(k))b.proxies.push({...h,file:S(d)})}else if(d==="netlify.toml"){let k=m(d);if(k)for(let h of gr(k))b.proxies.push({...h,file:S(d)})}}for(let g of t){let b={env:new Map,ports:new Set,weakPorts:new Set,proxies:[],isServer:!1};o.set(g.name,b);for(let $ of l(g.rootPath)){for(let S of sa){let m=ct(U.join($,S));if(m!=null)for(let d of xr(fa(m),s(U.join($,S)))){let k=b.env.get(d.name)??b.env.set(d.name,[]).get(d.name);k.some(h=>h.file===d.file)||k.push(d),d.kind==="port"&&$===U.resolve(g.rootPath)&&/(^|\/)\.env/.test(d.file)&&!/\.example$/.test(d.file)&&b.ports.add(d.port),d.kind==="port"&&$===U.resolve(g.rootPath)&&/\.example$/.test(d.file)&&b.ports.add(d.port)}}if($===U.resolve(g.rootPath)){try{let S=JSON.parse(ct(U.join($,"package.json"))??"null"),m=typeof S?.proxy=="string"?Ye(S.proxy):null;m&&b.proxies.push({prefix:"",target:m,kind:'package.json "proxy"',file:s(U.join($,"package.json"))})}catch{}for(let S of an($)){if(/^vite\.config\.(js|mjs|cjs|ts|mts)$/.test(S)){let m=ct(U.join($,S));if(m)for(let d of kr(m,"vite"))b.proxies.push({...d,file:s(U.join($,S))})}if(/^next\.config\.(js|mjs|cjs|ts)$/.test(S)){let m=ct(U.join($,S));if(m)for(let d of kr(m,"next"))b.proxies.push({...d,file:s(U.join($,S))})}}}$===U.resolve(g.rootPath)&&v(g,b,$);for(let S of an($))if(/^render\.ya?ml$/.test(S)&&!y.has(U.join($,S))){let m=ct(U.join($,S));m&&y.set(U.join($,S),dr(m,s(U.join($,S))))}for(let S of an($)){if(!/^docker-compose.*\.ya?ml$/.test(S)||f.has(U.join($,S)))continue;let m=ct(U.join($,S));m&&f.set(U.join($,S),ua(m))}}}for(let[g,b]of[...f].sort(($,S)=>$[0]<S[0]?-1:1)){let $=U.dirname(g);for(let S of b){let m=S.build?U.resolve($,S.build):null,d=t.find(h=>m&&U.resolve(h.rootPath)===m)??t.find(h=>h.name===S.name||U.basename(h.rootPath)===S.name);if(!d)continue;let k=o.get(d.name);for(let h of S.ports)k.ports.add(h.container),h.host&&k.ports.add(h.host);for(let h of xr(S.env,s(g)))(k.env.get(h.name)??k.env.set(h.name,[]).get(h.name)).push(h);a(S.name.toLowerCase(),d.name,"docker-compose service name")}}for(let[g,b]of[...y].sort(($,S)=>$[0]<S[0]?-1:1)){let $=U.dirname(g),S=new Map;for(let m of b){let d=U.resolve($,m.rootDir||"."),k=m.rootDir?t.find(x=>U.resolve(x.rootPath)===d):null;if(!k&&m.startCommand)for(let x of m.startCommand.split(/\s+/)){if(!/\.(c|m)?[jt]sx?$/.test(x)&&!/^[\w./-]+\/[\w.-]+$/.test(x))continue;let j=U.resolve(d,x),E=t.filter(M=>j.startsWith(U.resolve(M.rootPath)+U.sep)).sort((M,T)=>T.rootPath.length-M.rootPath.length)[0];if(E){k=E;break}}if(k=k??t.find(x=>x.name===m.name||U.basename(x.rootPath)===m.name),!k)continue;S.set(m.name,{target:k,c:m});let h=o.get(k.name);for(let x of m.kept)u(h,{...x,scoped:!0});a(m.name.toLowerCase(),k.name,"render.yaml service name"),a(`${m.name.toLowerCase()}.onrender.com`,k.name,"render.yaml service name (Render's default public address)")}for(let{target:m,c:d}of S.values())for(let k of d.hostRefs){let h=S.get(k.service);if(!h)continue;let x=[...h.c.kept].find(M=>M.kind==="port")?.port??null,j=k.property==="hostport"&&x,E=k.service.toLowerCase();u(o.get(m.name),{name:k.name,kind:"url",file:s(g),scheme:"http",host:E,port:j?x:null,origin:`http://${E}${j?":"+x:""}`,path:""})}}let p=g=>[...n.get(g.name)?.parseResults?.values()??[]].some(b=>(b.routes??[]).length>0);for(let g of t){let b=o.get(g.name);if(b.isServer=p(g),b.isServer){for(let[$,S]of b.env)if(ia.test($))for(let m of S)m.kind==="url"&&m.file&&(m.scoped||U.posix.dirname(m.file)===(wr(U.relative(e,g.rootPath))||"."))&&a(m.host,g.name,`${$} in ${m.file} (the server's own public address)`)}}for(let g of t){let b=o.get(g.name);for(let[,$]of n.get(g.name)?.parseResults??[])for(let S of $.httpClients?.listens??[])for(let m of w(b,S.parts)){let d=Qn(m.text);d&&b.ports.add(d)}}for(let g of t)for(let b of o.get(g.name).ports)c(r,b,g.name);for(let g of t)for(let b of o.get(g.name).weakPorts)t.some($=>o.get($.name).ports.has(b))||c(r,b,g.name);function w(g,b){let $=[{text:"",evidence:[]}];for(let S of b){let m;if(S.t==="lit")m=[{text:S.v,evidence:[]}];else if(S.t==="env"){let k=g.env.get(S.name)??[];m=[];for(let h of k)m.push({text:h.kind==="port"?String(h.port):h.origin+h.path,evidence:[{env:S.name,file:h.file}]});!m.length&&S.fallback&&(m=w(g,S.fallback).map(x=>({text:x.text,evidence:[{env:S.name,file:null,fallback:!0},...x.evidence]})))}else m=[];if(!m.length)return[];let d=[];for(let k of $)for(let h of m)if(d.push({text:k.text+h.text,evidence:[...k.evidence,...h.evidence]}),d.length>=8)break;$=d.slice(0,8)}return $}let I=(g,b)=>{let $=[],S=g.host,m=i.get(S)??[];for(let d of m)$.push(d);if(ca.has(S)||m.length&&m.some(d=>d.via==="docker-compose service name")){let d=g.port??(g.scheme==="https"||g.scheme==="wss",null);if(d)for(let k of r.get(d)??[])$.some(h=>h.service===k)||$.push({service:k,via:`port ${d} (a service listening there)`})}return $.filter(d=>d.service!==b)};return{resolveBase(g,b){let $=o.get(g);if(!$||!b.length)return{status:"unknown"};let S=w($,b);if(!S.length)return{status:"unknown"};let m=[],d=new Set;for(let x of S){let j=Ye(x.text)??(x.text.startsWith("//"),null);if(j){d.add(j.origin);for(let E of I(j,g))m.push({...E,u:j,evidence:x.evidence})}}if(!d.size)return{status:"unknown"};let k=[...new Set(m.map(x=>x.service))];if(k.length===0)return{status:"external",origins:[...d].sort()};if(k.length>1)return{status:"ambiguous",services:k.sort()};let h=m[0];return{status:"service",service:h.service,via:h.via,origin:h.u.origin,basePath:h.u.path,evidence:h.evidence.filter((x,j,E)=>E.findIndex(M=>M.env===x.env&&M.file===x.file)===j)}},resolveProxy(g,b){let $=o.get(g);for(let S of $?.proxies??[]){if(S.prefix&&b!==S.prefix&&!b.startsWith(S.prefix+"/"))continue;let m=I(S.target,g),d=[...new Set(m.map(k=>k.service))];if(d.length===1)return{status:"service",service:d[0],via:`${S.kind} ${S.prefix||"/"} -> ${S.target.origin}`,origin:S.target.origin,basePath:S.target.path,strip:S.strip?S.prefix.split("/").filter(Boolean).length:0,evidence:[{env:null,file:S.file}]}}return{status:"unknown"}},portsOf:g=>[...o.get(g)?.ports??[]].sort((b,$)=>b-$),hostClaims:()=>[...i].sort((g,b)=>g[0]<b[0]?-1:1)}}function an(e){try{return Zn.readdirSync(e).sort()}catch{return[]}}var ln=e=>String(e).toLowerCase();function fn(e){let t=[];for(let n of e)n.t==="lit"&&t.length&&t[t.length-1].t==="lit"?t[t.length-1]={t:"lit",v:t[t.length-1].v+n.v}:t.push(n);return t}function $r(e,t){let n=[];for(let s of e){if(s.t!=="param"){n.push(s);continue}let o=t?.get(s.index);o?n.push(...o):n.push({t:"ref",name:s.name})}return fn(n)}function eo(e){if(!e.length)return null;let t=e.slice(),n="none",s=null,o=t[0];if(o.t==="lit"){let l=/^(https?:)\/\/([^/?#]*)(.*)$/.exec(o.v);if(l){n="abs",s=l[2];let f=l[3];if(t=f?[{t:"lit",v:f},...t.slice(1)]:t.slice(1),/^(www\.)?(localhost|127\.0\.0\.1|\[::1\]|0\.0\.0\.0)(:\d+)?$/.test(s)===!1&&!/\.(local|internal|svc)$/.test(s)&&!/^[a-z0-9-]+(:\d+)?$/.test(s))return null}else if(!o.v.startsWith("/"))return null}else{for(n="var";t.length&&t[0].t!=="lit";)t.shift();if(!t.length||!t[0].v.startsWith("/"))return null}let r="",i=0,c=!1;for(let l of t){if(c)break;if(l.t==="lit"){let f=l.v.search(/[?#]/);f>=0?(r+=l.v.slice(0,f),c=!0):r+=l.v}else r+="",i++}if(!r.startsWith("/")&&!(r===""&&n==="abs"))return null;r===""&&(r="/");let a=r.split("/").slice(1).map(l=>l.includes("")?":p":l);for(;a.length>1&&a[a.length-1]==="";)a.pop();return{base:n,host:s,segments:a,placeholders:i,literal:n==="none"&&i===0}}function Nr(e){if(!e.length)return[];let t=e[0];if(t.t==="lit"){let s=/^((?:https?|wss?):\/\/[^/?#]*)/.exec(t.v);return s?[{t:"lit",v:s[1]}]:[]}let n=[];for(let s of e){if(s.t==="lit"&&s.v.startsWith("/"))break;n.push(s)}return n}var da=e=>String(e||"").split("/").filter(Boolean),Ir=e=>[...new Set(e)];function jr(e){let t=e.evidence??[];return{env:Ir(t.filter(n=>n.env).map(n=>n.env)),files:Ir(t.filter(n=>n.file).map(n=>n.file)),origin:e.origin,via:e.via,...t.some(n=>n.fallback)?{usedFallback:!0}:{}}}var Er=(e,t)=>"base URL "+(e.env.length?e.env.join(", ")+(e.files.length?" in "+e.files.join(", "):"")+" = ":e.files.length?"(from "+e.files.join(", ")+") ":"")+e.origin+" belongs to "+t+" ("+e.via+")",pa=e=>{let t=String(e).split(/[?#]/)[0].split("/").slice(1).map(n=>n.startsWith(":")||/^\{.*\}$/.test(n)||n==="*"?":p":n);for(;t.length>1&&t[t.length-1]==="";)t.pop();return t};function Cr(e,t){if(e.length===t.length){let n=!0,s=!0;for(let o=0;o<e.length;o++){let r=e[o],i=t[o];if(r!==i&&(n=!1),!(r===i||r===":p"||i===":p")){s=!1;break}}if(n)return 3;if(s)return 2}if(e[0]==="api"&&e.length>1){let n=e.slice(1);if(/^v\d+$/.test(n[0])&&n.length>1&&(n=n.slice(1)),n.length===t.length&&n.every((s,o)=>s===t[o]||s===":p"||t[o]===":p"))return 1}return 0}function ma(e,t,n,s,o){let r=(n.importBindings??[]).find(y=>y.local===s);if(!r)return null;let i=ve(r.source,t,o);if(!i)return null;let c=e.parseResults.get(i),a=y=>e.nodes.find(u=>u.filePath===i&&u.name===y&&u.type!=="moduleRoot")?.id??null;if(r.kind==="named"&&r.imported)return a(r.imported);let l=c?.exportBindings;if(l?.default&&l.default!=="<anon>")return a(l.default);let f=Object.keys(l?.named??{});return f.length===1?a(f[0]):null}function ha(e){let t=[],n=[...e.parseResults.keys()];for(let[s,o]of e.parseResults){let r=e.nodes.filter(a=>a.filePath===s);if(r[0]?.category!=="backend")continue;let i=Ae(s,o),c=fe(s,e.nodes);for(let a of o.routes??[]){let l=null;a.isInlineHandler?l=i.get(a):a.nest?l=r.find(y=>y.type==="classMethod"&&y.className===a.nest.className&&y.name===a.nest.methodName)?.id??null:a.handlerName&&c.has(a.handlerName)?l=c.get(a.handlerName):a.handlerName&&(l=ma(e,s,o,a.handlerName,n));let f=!1;l||(l=ce(a.startLine,r)?.id??null,f=!0),l&&t.push({method:ln(a.method),path:a.path,segments:pa(a.path),literal:!/[:*{]/.test(a.path),nodeId:l,file:s,line:a.startLine,fallback:f})}}return t}var ga=/^(ws|uws|websocket|@nestjs\/platform-ws|@fastify\/websocket|fastify-websocket|express-ws)$/,ya=/^(socket\.io|@nestjs\/platform-socket\.io|socket\.io-client)$/;function Rr(e){let t=[...e].some(s=>ya.test(s)),n=[...e].some(s=>ga.test(s));return t&&n?"unknown":t?"socketio":n?"ws":null}function va(e){let t=[],n=new Set;for(let[,s]of e.parseResults)for(let o of s.imports??[])n.add(o.source);for(let[s,o]of e.parseResults){let r=o.socketListeners??[],i=r.find(w=>w.eventName==="connection");if(!i)continue;let c=Ae(s,o),a=fe(s,e.nodes),l=w=>w.isInlineHandler?c.get(w):w.handlerName&&a.has(w.handlerName)?a.get(w.handlerName):null,f=l(i);if(!f)continue;let y=w=>i.handlerStartLine!=null&&w.startLine>=i.handlerStartLine&&w.startLine<=i.handlerEndLine,u=r.find(w=>w.eventName==="message"&&y(w))??r.find(w=>w.eventName==="message"),v=o.httpClients?.wsServers??[],p=Rr(new Set((o.imports??[]).map(w=>w.source)))??Rr(n)??"unknown";t.push({filePath:s,nodeId:f,line:i.startLine,messageNodeId:u?l(u):null,messageLine:u?.startLine??null,pathParts:v.find(w=>w.path)?.path??null,kind:p})}return t}function _r(e,t,n={}){let s=n.repoRoot?br(n.repoRoot,e,t):null,o=[],r=new Set,i={restCalls:0,restLinked:0,wsClients:0,wsLinked:0,wsSends:0,wsSendsLinked:0},c=l=>{let f=[l.fromService,l.fromNodeId,l.toService,l.toNodeId,l.via,l.key].join("\0");r.has(f)||(r.add(f),o.push(l))},a=new Map;for(let l of e){let f=t.get(l.name);f&&a.set(l.name,{routes:ha(f),wsServers:va(f)})}for(let l of e){let f=t.get(l.name);if(!f)continue;let y=[...f.parseResults.keys()],u=new Map,v=new Map;for(let[m,d]of f.parseResults){let k=d.httpClients;if(k){for(let h of k.httpInstances??[])(u.get(h.name)??u.set(h.name,[]).get(h.name)).push(h);for(let h of k.httpCalls??[])(h.parts.some(j=>j.t==="param")||h.method&&typeof h.method=="object")&&h.fn?.name&&(v.get(h.fn.name)??v.set(h.fn.name,[]).get(h.fn.name)).push({filePath:m,call:h})}}let p=m=>{if(!m.startsWith("inst:")&&!m.startsWith("obj:"))return[];let d=u.get(m.slice(m.indexOf(":")+1));return d&&d.length===1?d[0].parts:m.startsWith("obj:")?null:[{t:"ref",name:"?"}]},w=[],I=(m,d)=>ce(d,f.nodes.filter(k=>k.filePath===m)),g=new Set,b=m=>m.parts.some(d=>d.t==="param")||m.method&&typeof m.method=="object";for(let[m,d]of f.parseResults){let k=d.httpClients;if(k){for(let h of k.httpCalls??[]){if(b(h))continue;let x=p(h.client);if(x===null)continue;let j=I(m,h.line);j&&w.push({filePath:m,line:h.line,nodeId:j.id,method:h.method,parts:fn([...x,...h.parts]),via:h.client.replace(/^obj:/,"inst:"),wrapper:null})}for(let h of k.pathCallsites??[]){let x=v.get(h.callee);if(x)for(let j of x){let E=j.filePath===m;if(!E){let O=(d.importBindings??[]).find(C=>C.local===h.callee||C.imported===h.callee);O&&ve(O.source,m,y)===j.filePath&&(E=!0)}if(!E)continue;let M=new Map(h.args.map(O=>[O.i,O.parts])),T=typeof j.call.method=="object"&&j.call.method?(()=>{let O=M.get(j.call.method.param);return O&&O.length===1&&O[0].t==="lit"?O[0].v.toUpperCase():"?"})():j.call.method,L=I(m,h.line);L&&(g.add(j.call),w.push({filePath:m,line:h.line,nodeId:L.id,method:T,parts:$r([...p(j.call.client),...j.call.parts],M),via:j.call.client,wrapper:h.callee}))}}}}for(let[m,d]of f.parseResults)for(let k of d.httpClients?.httpCalls??[]){if(!b(k)||g.has(k))continue;let h=p(k.client);if(h===null)continue;let x=I(m,k.line);x&&w.push({filePath:m,line:k.line,nodeId:x.id,method:typeof k.method=="object"&&k.method?"?":k.method,parts:$r([...h,...k.parts],null),via:k.client.replace(/^obj:/,"inst:"),wrapper:null})}for(let m of w){let d=eo(m.parts);if(!d)continue;i.restCalls++;let k=0,h=[];for(let L of e){if(L.name===l.name)continue;let O=a.get(L.name);if(O)for(let C of O.routes){if(!(m.method==="?"||m.method==null||C.method===ln(m.method)||C.method==="all"||C.method==="use"))continue;let K=Cr(d.segments,C.segments);K&&(K>k&&(k=K,h.length=0),K===k&&h.push({service:L.name,route:C}))}}let x={status:"unknown"};if(s){let L=fn(m.parts);if(d.base==="none"?x=s.resolveProxy(l.name,"/"+d.segments.join("/")):x=s.resolveBase(l.name,Nr(L)),x.status==="service"){let O=da(x.basePath);if(O.length||x.strip){let C=[...O,...d.segments.slice(x.strip||0)];for(let z of a.get(x.service)?.routes??[])(m.method==="?"||m.method==null||z.method===ln(m.method)||z.method==="all"||z.method==="use")&&Cr(C,z.segments)&&!h.some(R=>R.service===x.service&&R.route.nodeId===z.nodeId)&&h.push({service:x.service,route:z,viaBasePath:!0})}}}if(!h.length)continue;let j=new Set(h.map(L=>L.service+"\0"+L.route.nodeId)),E=typeof m.method=="string"&&m.method!=="?",M=k===3&&d.literal&&E&&j.size===1&&h[0].route.literal&&!h[0].route.fallback&&h[0].route.method===ln(m.method),T=[];d.base==="var"&&T.push("base URL is a variable, so the target service is guessed from the path"),d.base==="abs"&&T.push("absolute URL"),d.placeholders&&T.push("path has parameters"),k===1&&T.push("leading /api removed from the client path"),k===2&&T.push("route parameters matched fuzzily"),E||T.push("method not known"),j.size>1&&T.push(j.size+" candidate routes"),h.some(L=>L.route.fallback)&&T.push("route handler not resolved: linked to the function that registers the route"),x.status==="external"&&T.push("base URL is "+x.origins.join(" / ")+", which no service of this repo owns"),x.status==="ambiguous"&&T.push("base URL could belong to "+x.services.join(" or "));for(let L of h){i.restLinked++;let O=!M&&x.status==="service"&&x.service===L.service&&!L.route.fallback,C=O?jr(x):null,z=M?"exact":O?"resolved":"inferred",K=!M&&x.status==="service"&&x.service!==L.service?["base URL belongs to "+x.service+", not this service"]:[];c({fromService:l.name,fromNodeId:m.nodeId,toService:L.service,toNodeId:L.route.nodeId,via:"httpCall",key:`${E?m.method:"ANY"} ${"/"+d.segments.join("/")}`,confidence:z,method:E?m.method:null,url:"/"+d.segments.join("/"),client:m.via,...m.wrapper?{wrapper:m.wrapper}:{},line:m.line,...M?{}:O?{reason:Er(C,L.service)+(E?"":"; method not known"),resolvedFrom:C}:{reason:[...T,...K].join("; ")||"path-only match"}})}}let $=[];for(let[m,d]of f.parseResults)for(let k of d.httpClients?.wsClients??[])$.push({filePath:m,w:k});let S=m=>m.client==="io"?"socketio":"ws";for(let{filePath:m,w:d}of $){let k=I(m,d.line);if(!k)continue;i.wsClients++;let h=fn(d.parts),x=/^wss?:\/\//.test(h[0]?.v??"")?eo([{t:"lit",v:h[0].v.replace(/^ws(s?):/,"http$1:")},...h.slice(1)]):eo(h),j=s&&x?s.resolveBase(l.name,Nr(h)):{status:"unknown"};for(let E of e)if(E.name!==l.name)for(let M of a.get(E.name)?.wsServers??[]){if(M.kind!=="unknown"&&M.kind!==S(d))continue;let T=M.pathParts&&M.pathParts.every(K=>K.t==="lit")?"/"+M.pathParts.map(K=>K.v).join("").replace(/^\//,""):null,L=x?"/"+x.segments.join("/"):null;if(T&&L&&T!==L&&T!=="/"&&L!=="/")continue;let O=!!(x&&x.literal&&T&&L===T&&M.kind!=="unknown"),C=!O&&j.status==="service"&&j.service===E.name,z=C?jr(j):null;i.wsLinked++,c({fromService:l.name,fromNodeId:k.id,toService:E.name,toNodeId:M.nodeId,via:"webSocket",key:L??"(url unknown)",confidence:O?"exact":C?"resolved":"inferred",url:L,client:d.client,line:d.line,...O?{}:C?{reason:Er(z,E.name),resolvedFrom:z}:{reason:"WebSocket connection matched to a WebSocket server of another service ("+(x?.base==="var"?"URL base is a variable":"no path on the server to compare")+(j.status==="external"?"; base URL is "+j.origins.join(" / ")+", which no service of this repo owns":"")+")"}})}}if($.length){let m=new Set($.map(({w:d})=>S(d)));for(let[d,k]of f.parseResults)for(let h of k.httpClients?.wsSends??[]){let x=I(d,h.line);if(x){i.wsSends++;for(let j of e)if(j.name!==l.name)for(let E of a.get(j.name)?.wsServers??[])!E.messageNodeId||E.kind!=="unknown"&&!m.has(E.kind)||(i.wsSendsLinked++,c({fromService:l.name,fromNodeId:x.id,toService:j.name,toNodeId:E.messageNodeId,via:"webSocketMessage",key:"message",eventName:"message",confidence:"inferred",client:h.recv,line:h.line,reason:"a message sent over a socket whose payload is built at run time; delivered to the message listener of a WebSocket server of another service"}))}}}}if(n.serverPush!==!1){let l=new Map;for(let y of o)if(y.via==="webSocket"){let u=y.fromService+"\0"+y.toService;(l.get(u)??l.set(u,[]).get(u)).push(y)}let f=new Map;for(let y of l.values())(f.get(y[0].toService)??f.set(y[0].toService,new Set).get(y[0].toService)).add(y[0].fromService);for(let[,y]of[...l].sort((u,v)=>u[0]<v[0]?-1:1)){let u=y[0].fromService,v=y[0].toService,p=t.get(u),w=t.get(v);if(!p||!w||!(a.get(v)?.wsServers??[]).length)continue;let I=new Set(y.map(S=>S.fromNodeId.split("::")[0])),g=[];for(let[S,m]of p.parseResults){if(!I.has(S))continue;let d=fe(S,p.nodes),k=Ae(S,m),h=p.nodes.filter(x=>x.filePath===S);for(let x of m.httpClients?.wsReceivers??[]){let j=x.handlerName&&d.get(x.handlerName)||ce(x.line,h)?.id;j&&g.push({id:j,line:x.line})}for(let x of m.socketListeners??[]){if(x.eventName!=="message")continue;let j=x.isInlineHandler?k.get(x):x.handlerName&&d.get(x.handlerName)||null;j&&g.push({id:j,line:x.startLine})}}let b=new Set(p.resolvedEdges.filter(S=>S.resolved&&S.targetNodeId&&S.type!=="returnValue").map(S=>S.fromNodeId));for(let S=g.length-1;S>=0;S--)b.has(g[S].id)||g.splice(S,1);if(!g.length)continue;let $=f.get(v)?.size??1;for(let[S,m]of w.parseResults){let d=w.nodes.filter(k=>k.filePath===S);for(let k of[...m.httpClients?.wsSends??[],...m.httpClients?.wsServerSends??[]]){let h=ce(k.line,d);if(h)for(let x of g)i.wsPushLinked=(i.wsPushLinked??0)+1,c({fromService:v,fromNodeId:h.id,toService:u,toNodeId:x.id,via:"webSocketDelivery",key:"message",eventName:"message",confidence:"inferred",client:k.recv,line:k.line,receiverLine:x.line,reason:"a message the server sends over a WebSocket (payload built at run time) is taken in by the message handler of "+u+", which connects to this server"+($>1?"; "+$+" services connect to this server, so it may be meant for another one":""),...$>1?{candidates:$}:{}})}}}}return o.sort((l,f)=>l.fromService+l.fromNodeId+l.via+l.key+l.toService+l.toNodeId<f.fromService+f.fromNodeId+f.via+f.key+f.toService+f.toNodeId?-1:1),{edges:o,stats:i}}import Pr from"node:fs";var wa=new Set("if for while switch catch return function super typeof new else do with await yield throw import export".split(" ")),xa=8;function Lr({files:e,resolveName:t,callArgs:n,matchClose:s,IDENT:o}){let r=new Map,i=m=>{let d=[],k=new RegExp(`\\bclass\\s+(${o})(?:\\s+extends\\s+(${o}))?[^{]*\\{`,"g"),h;for(;h=k.exec(m);){let x=h.index+h[0].length-1,j=s(m,x);j>0&&d.push({name:h[1],base:h[2]??null,open:x,close:j,start:h.index})}return d};for(let m of e){m.classes=i(m.t);for(let d of m.classes)r.set(d.name,(r.get(d.name)??0)+1)}let c=m=>r.get(m)===1,a=m=>{let d=m,k,h=/@[A-Za-z_$][\w$]*\s*\(/;for(;k=h.exec(d);){let x=s(d,k.index+k[0].length-1);if(x<0)break;d=d.slice(0,k.index)+d.slice(x+1)}return d},l="(?:(?:private|public|protected|readonly|override)\\s+)",f=m=>{let d=a(m).trim(),k=new RegExp(`^${l}*(${o})\\s*[?:=]`).exec(d)??new RegExp(`^${l}*(${o})\\s*$`).exec(d);return{name:k?k[1]:null,prop:new RegExp(`^${l}+`).test(d)}},y=(m,d)=>{let k=[],h=m.slice(d.open+1,d.close),x=new RegExp(`(?:^|[\\n;}{])\\s*(?:(?:public|private|protected|static|async|override)\\s+)*(${o})\\s*(?:<[^>(]*>)?\\s*\\(`,"g"),j;for(;j=x.exec(h);){if(wa.has(j[1]))continue;let E=n(h,j.index+j[0].length-1);if(!E)continue;let M=E.close+1;for(;M<h.length&&/\s/.test(h[M]);)M++;if(h[M]===":"){let O=h.indexOf("{",M);if(O<0)continue;M=O}if(h[M]!=="{")continue;let T=s(h,M);if(T<0)continue;let L=E.args.map(O=>f(O.text));k.push({name:j[1],params:L.map(O=>O.name),paramProps:L.map(O=>O.prop),body:h.slice(M+1,T)}),x.lastIndex=T}return k};for(let m of e)for(let d of m.classes)d.methods=y(m.t,d),d.ctor=d.methods.find(k=>k.name==="constructor")??null;let u=new Map,v=new Map;for(let m of e)for(let d of m.classes)for(let k of d.methods){if(k.name==="constructor")continue;let h=new RegExp(`new\\s+(?:Queue|Bull|BullQueue)\\s*(?:<[^>]*>)?\\s*\\(\\s*(${o})\\s*[,)]`).exec(k.body);h&&k.params.includes(h[1])&&(u.has(k.name)||u.set(k.name,new Set),u.get(k.name).add(k.params.indexOf(h[1])));let x=new RegExp(`new\\s+Worker\\s*(?:<[^>]*>)?\\s*\\(\\s*(${o})\\s*,\\s*(${o})\\s*[,)]`).exec(k.body);x&&k.params.includes(x[1])&&k.params.includes(x[2])&&(v.has(k.name)||v.set(k.name,new Map),v.get(k.name).set(k.params.indexOf(x[1]),k.params.indexOf(x[2])))}let p=(m,d)=>{let k=m.ctor?.params[d];if(!k)return new Set;let h=new Set([k]);m.ctor.paramProps[d]&&h.add("this."+k);let x=new RegExp(`this\\.(${o})\\s*=\\s*${k.replace(/\$/g,"\\$")}\\s*[;,\\n]`,"g"),j;for(;j=x.exec(m.ctor.body);)h.add("this."+j[1]);return h},w=(m,d)=>{let k=[],h=new RegExp(`(?<![\\w$])${d}\\s*\\(`,"g"),x;for(;x=h.exec(m);){let j=n(m,x.index+x[0].length-1);j&&k.push(j.args.map(E=>E.text.trim()))}return k},I=new Map,g=new Map;for(let m of e)for(let d of m.classes){if(!c(d.name)||!d.ctor)continue;let k=m.t.slice(d.open,d.close),h=new RegExp(`new\\s+(?:Queue|Bull|BullQueue)\\s*(?:<[^>]*>)?\\s*\\(\\s*(${o})\\s*[,)]`).exec(d.ctor.body);if(h&&d.ctor.params.includes(h[1]))I.set(d.name,{file:m.file,paramIndex:d.ctor.params.indexOf(h[1])});else{let x=null;for(let j=0;j<d.ctor.params.length&&x===null;j++){let E=p(d,j);for(let[M,T]of u)for(let L of w(k,M))for(let O of T)L[O]!==void 0&&E.has(L[O])&&(x=j)}x!==null&&I.set(d.name,{file:m.file,paramIndex:x})}for(let x=0;x<d.ctor.params.length;x++){let j=p(d,x),E=new Map;for(let M of d.methods)for(let[T,L]of v)for(let O of w(M.body,T))for(let[C,z]of L)O[C]!==void 0&&j.has(O[C])&&O[z]!==void 0&&M.params.includes(O[z])&&E.set(M.name,M.params.indexOf(O[z]));for(let M=0;M<3&&E.size;M++)for(let T of d.methods)for(let[L,O]of[...E])for(let C of w(T.body,"this\\."+L))C[O]!==void 0&&T.params.includes(C[O])&&!E.has(T.name)&&E.set(T.name,T.params.indexOf(C[O]));if(E.size){g.set(d.name,{file:m.file,paramIndex:x,registrars:E});break}}}let b=m=>{for(let d=0;d<xa;d++){let k=!1;for(let h of e)for(let x of h.classes){if(!x.base||m.has(x.name)||!c(x.name)||!c(x.base))continue;let j=m.get(x.base);if(!j)continue;if(j.name!==void 0||!x.ctor){m.set(x.name,{...j}),k=!0;continue}let E=/\bsuper\s*\(/.exec(x.ctor.body);if(!E)continue;let T=n(x.ctor.body,E.index+E[0].length-1)?.args[j.paramIndex];if(!T)continue;let L=t(T.text,h.file,h.t);if(L){m.set(x.name,{...j,name:L.name,how:L.how+" passed to the base class"}),k=!0;continue}let O=x.ctor.params.indexOf(T.text.trim());O>=0&&(m.set(x.name,{...j,paramIndex:O}),k=!0)}if(!k)break}};b(I),b(g);let $=new Map,S=new Map;for(let[m,d]of I)d.name!==void 0&&$.set(m,{name:d.name,how:d.how});for(let[m,d]of g)d.name!==void 0&&S.set(m,d);return{producerClasses:$,workerClasses:S,unique:c}}var ka=/\b(?:Queue|Bull|Worker|Processor|InjectQueue|WorkerHost)\b|\.process\s*\(|\b[A-Za-z_$]*(?:Queue|Worker)[A-Za-z_$]*(?:Service|Base)\b|\b(?:createQueue|createWorker|initWorker)\b/,Ie="[A-Za-z_$][\\w$]*",Sa=1024*1024;function Mr(e){let t="",n=0,s=null;for(;n<e.length;){let o=e[n],r=e[n+1];if(s){if(t+=o,o==="\\"){t+=e[n+1]??"",n+=2;continue}o===s&&(s=null),n++}else if(o==="/"&&r==="/")for(;n<e.length&&e[n]!==`
|
|
11
|
+
return ${c};})()`}function Yn(e,t,n,s){if(!e)return{targetId:null,via:null};if(n.has(e))return{targetId:n.get(e),via:"in-file"};if(s)for(let[,o]of s){let r=fe(o,t);if(r.has(e))return{targetId:r.get(e),via:"cross-file"}}return{targetId:null,via:null}}function Ks(e,t,n,s,o,r=[],i=null){if(!n.some(a=>!a.isInlineHandler)&&!s.some(a=>!a.isInlineHandler)&&!r.some(a=>!a.isInlineHandler))return e;let c=e.map(a=>({...a}));for(let a of n){if(a.isInlineHandler)continue;let l=a.nest?e.find(u=>u.type==="classMethod"&&u.filePath===t&&u.className===a.nest.className&&u.name===a.nest.methodName):null,{targetId:f,via:y}=a.nest?{targetId:l?.id??null,via:"in-file"}:Yn(a.handlerName,e,o,i);if(f){let u=c.find(v=>v.id===f);u&&(u.isEntryPoint=!0,u.trigger={type:"route",label:`${a.method.toUpperCase()} ${a.path}`,resolvedVia:y})}}for(let a of s){if(a.isInlineHandler)continue;let{targetId:l,via:f}=Yn(a.handlerName,e,o,i);if(l){let y=c.find(u=>u.id===l);y&&(y.isEntryPoint=!0,y.trigger={type:"listener",label:a.eventName,resolvedVia:f})}}for(let a of r){if(a.isInlineHandler)continue;let{targetId:l,via:f}=Yn(a.handlerName,e,o,i);if(l){let y=c.find(u=>u.id===l);y&&(y.isEntryPoint=!0,y.trigger={type:"socketListener",label:a.eventName,resolvedVia:f})}}return c}function Jn(e){let t=new Map,n=new Map;for(let s of e)s.resolved&&(t.set(s.fromNodeId,(t.get(s.fromNodeId)??0)+1),n.set(s.targetNodeId,(n.get(s.targetNodeId)??0)+1));return{outgoing:t,incoming:n}}function Xs(e,t,n=Jn(t)){if(e.type==="moduleRoot")return 0;let s=n.outgoing.get(e.id)??0,o=n.incoming.get(e.id)??0,r=e.exported?1.5:1;return s/(o+1)*r}function Zs(e,t){let n=Jn(t),s=new Set;for(let i of e)n.incoming.has(i.id)&&s.add(i.filePath);let r=e.filter(i=>!(i.isEntryPoint||i.type==="moduleRoot"||!n.incoming.has(i.id)&&s.has(i.filePath))).map(i=>({...i,fallbackScore:Xs(i,t,n)}));return r.sort((i,c)=>c.fallbackScore-i.fallbackScore),r.slice(0,15)}function tn(e){let t=new Map;for(let n of e)!n.resolved||!n.fromNodeId||!n.targetNodeId||(t.has(n.fromNodeId)||t.set(n.fromNodeId,[]),t.get(n.fromNodeId).push({targetNodeId:n.targetNodeId,line:n.line??null,column:n.column??null,branchPath:n.branchPath??[],edgeType:n.type}));return t}function nn(e,t,n,s=8,o=null){if(o){let l=nn(e,o,n,s),f=new Set(l.map(p=>p.nodeId)),y=l.slice();y.extraNodeIds=new Set;let u=p=>n.find(w=>w.id===p)?.category??"unknown",v=l.slice();for(;v.length>0;){let p=v.shift();if(!(p.depth>=s))for(let w of t.get(p.nodeId)||[]){let I=w.targetNodeId;if(f.has(I))continue;f.add(I);let g={nodeId:I,depth:p.depth+1,parentNodeId:p.nodeId,category:u(I),callLine:w.line,callColumn:w.column,branchPath:w.branchPath,edgeType:w.edgeType};y.push(g),y.extraNodeIds.add(I),v.push(g)}}return y}let r=new Set([e]),i=l=>n.find(f=>f.id===l)?.category??"unknown",c=[{nodeId:e,depth:0,parentNodeId:null,category:i(e)}],a=[{nodeId:e,depth:0}];for(;a.length>0;){let l=a.shift();if(l.depth>=s)continue;let f=t.get(l.nodeId)||[];for(let y of f){let u=y.targetNodeId;if(r.has(u))continue;r.add(u);let v={nodeId:u,depth:l.depth+1,parentNodeId:l.nodeId,category:i(u),callLine:y.line,callColumn:y.column,branchPath:y.branchPath,edgeType:y.edgeType};c.push(v),a.push(v)}}return c}function Qs(e,t,n,s=null){return t.filter(r=>r.filePath===e.filePath&&r.id!==e.id&&r.type!=="moduleRoot").filter(r=>!(s?s.has(r.id):n.some(c=>c.resolved&&c.targetNodeId===r.id)))}var er=new WeakMap,tr=new WeakMap;function qc(e){let t=er.get(e);if(t&&t.length===e.length)return t;let n=new Set,s=new Set,o=new Map;for(let r of e)r.resolved&&(r.targetNodeId===void 0||r.targetNodeId===null||(s.add(r.targetNodeId),r.matchType==="crossLayer"&&n.add(r.targetNodeId)),o.set(r.fromNodeId,(o.get(r.fromNodeId)??0)+1));return t={length:e.length,crossLayerTargets:n,incoming:s,outgoing:o},er.set(e,t),t}function Gc(e,t,n){let s=tr.get(e);if(s&&s.length===e.length&&s.edgesRef===n)return s.calledByFile;let o=new Map;for(let r of e){if(r.type==="moduleRoot"||!n.incoming.has(r.id))continue;let i=o.get(r.filePath);i||o.set(r.filePath,i=new Set),i.add(r.id)}return tr.set(e,{length:e.length,edgesRef:n,calledByFile:o}),o}function nr(e,t,n){if(e.type==="moduleRoot")return!1;let s=qc(t);if(s.crossLayerTargets.has(e.id)||(s.outgoing.get(e.id)??0)>=4||new Set((e.returns||[]).map(a=>a.condition).filter(a=>a!==null)).size>=3)return!0;if(s.incoming.has(e.id)){let a=Gc(n,t,s).get(e.filePath);if(!(!!a&&a.size-(a.has(e.id)?1:0)>0)){let f=Qs(e,n,t,s.incoming);if(f.length>0)return e.lexicalSiblings=f.map(y=>y.id),!0}}return!1}function or(e,t,n,s,o=8,r=null,i=null){let c=[],a=new Set(e.map(y=>y.id)),l=[...e],f=new Map;for(let y of n)f.has(y.id)||f.set(y.id,y);for(;l.length>0;){let y=l.shift(),u=nn(y.id,t,n,o,i);c.push({entryPointId:y.id,entryPointName:y.name,trigger:y.trigger??null,steps:u,...u.extraNodeIds?.size?{extraNodeIds:u.extraNodeIds}:{}});let v=r?new Set(nn(y.id,r,n,o).map(p=>p.nodeId)):null;for(let p of u){if(v&&!v.has(p.nodeId)||p.nodeId===y.id||a.has(p.nodeId))continue;let w=f.get(p.nodeId);w&&nr(w,s,n)&&(a.add(w.id),p.hasOwnSubTrace=!0,w.lexicalSiblings&&(p.lexicalSiblings=w.lexicalSiblings),l.push({id:w.id,name:w.name,trigger:null}))}}return c}function sr(e,t,n=ps){return e.filter((s,o)=>{if(o===0)return!0;let r=t.find(i=>i.id===s.nodeId);return r?!n.some(i=>r.name.toLowerCase().includes(i)):!0})}function rr(e){return e.steps.filter(n=>n.depth>0&&!e.extraNodeIds?.has(n.nodeId)).map(n=>n.nodeId).sort().join(" | ")}function ir(e){let t=new Map;for(let n of e){let s=rr(n),o=s===""?`__no_calls__${n.entryPointName}`:s;t.has(o)||t.set(o,[]),t.get(o).push(n)}return t}function cr(e){let t=e[0];return{steps:t.steps,entryPointNames:e.map(n=>n.entryPointName),occurrences:e.length,name:t.entryPointName,trigger:t.trigger,tier:e.some(n=>n.origin==="physical")?"physical":"guessed",tierOrigin:e.some(n=>n.origin==="physical")?"physical":t.origin}}import on from"node:path";function ar(e){if(!e.trigger)return null;if(e.trigger.type==="route")return`${e.trigger.label.split(" ")[1].split("/").filter(Boolean).join(" ").replace(/[-_]/g," ").split(" ").map(o=>o.charAt(0).toUpperCase()+o.slice(1)).join(" ")} Flow`;if(e.trigger.type==="listener"){let t=e.trigger.label;return`${t.charAt(0).toUpperCase()+t.slice(1)} Flow`}return null}function lr(e){return e.name.replace(/([A-Z])/g," $1").trim().split(" ").map(n=>n.charAt(0).toUpperCase()+n.slice(1)).join(" ")}var fr=60,Yc=24;function ur(e,t=null){let n=e.map(s=>{let o=ar(s),r=s.trigger?.workflowName??o??lr(s);return{...s,name:r}});return t?.nodes?Xc(n,t.nodes):n}var Vn=(e,t)=>e.length>t?e.slice(0,t-1)+"\u2026":e,Jc=new Set(["function","arrowFunction","classMethod"]);function Vc(e){let t=new Map(e.map(o=>[o.id,o])),n=new Map,s=o=>{let r=n.get(o);return r||(r=e.filter(i=>i.filePath===o&&Jc.has(i.type)),n.set(o,r)),r};return o=>{let r=t.get(o.steps[0].nodeId);if(!r)return[null,null,null];let i=null;if(r.type==="classMethod")i=r.className;else{let l=null;for(let f of s(r.filePath))f===r||!(f.startLine<=r.startLine&&f.endLine>=r.endLine)||f.startLine===r.startLine&&f.endLine===r.endLine||(!l||f.endLine-f.startLine<l.endLine-l.startLine)&&(l=f);l&&(i=l.type==="classMethod"?l.className:l.name)}let c=null;if(o.trigger?.type==="route")c=String(o.trigger.label).split(" ")[0];else if(o.trigger?.type==="listener"){let l=/::listener:([^.#]+)\./.exec(r.id);l&&(c=l[1])}let a=on.basename(r.filePath,on.extname(r.filePath));return a==="index"&&(a=on.basename(on.dirname(r.filePath))),[i||null,c||null,a||null]}}var Kc=(e,t)=>{let n=t.map(s=>Vn(s,Yc)).join(", ");return e.endsWith(")")?e.slice(0,-1)+", "+n+")":e+" ("+n+")"};function Xc(e,t){let n=Vc(t),s=e.map(i=>({w:i,base:i.name,parts:[],used:new Set,stuck:!1,q:null})),o=i=>i.parts.length?Kc(i.base,i.parts):i.base,r=()=>{let i=new Map;for(let c of s){let a=o(c);(i.get(a)??i.set(a,[]).get(a)).push(c)}return[...i.values()].filter(c=>c.length>1)};for(let i=0;i<4;i++){let c=!1;for(let a of r()){if(a.some(u=>u.stuck))continue;for(let u of a)u.q??=n(u.w);let l=[0,1,2].filter(u=>a.every(v=>!v.used.has(u))),f=l.find(u=>new Set(a.map(v=>v.q[u]??"")).size>1),y=f!==void 0;if(y||(f=l.find(u=>a.every(v=>v.q[u]))),f===void 0){for(let u of a)u.stuck=!0;continue}for(let u of a)u.used.add(f),u.q[f]&&u.parts.push(u.q[f]),y||(u.stuck=!0);c=!0}if(!c)break}for(let i of r())i.sort((c,a)=>c.w.steps[0].nodeId<a.w.steps[0].nodeId?-1:c.w.steps[0].nodeId>a.w.steps[0].nodeId?1:0),i.forEach((c,a)=>{a>0&&(c.suffix=` (${a+1})`)});return s.map(i=>{let c=o(i);return i.suffix&&(c=Vn(c,fr-i.suffix.length)+i.suffix),{...i.w,name:Vn(c,fr)}})}var Zc=e=>e;function dr(e,t){let n=new Map;for(let[s,o]of e){let r=t.filter(l=>l.filePath===s);if(r[0]?.category!=="backend")continue;let i=o.routes??[],c=Ae(s,o),a=fe(s,t);for(let l of i){let f=xt(l.path);if(l.isInlineHandler){let u=c.get(l);n.set(f,u);continue}if(l.nest){let u=Zc(r).find(v=>v.type==="classMethod"&&v.className===l.nest.className&&v.name===l.nest.methodName);u&&n.set(f,u.id);continue}if(!l.handlerName||!a.has(l.handlerName))continue;let y=a.get(l.handlerName);n.set(f,y)}}return n}import it from"node:fs";import te from"node:path";var sn=[".ts",".tsx",".mts",".cts",".js",".jsx",".mjs",".cjs"],Qc=/(^|\/)(dist|build|out|built|compiled|esm|cjs|lib|output)(\/|$)/,pr=/(^|\/)(dist|build|out|built|compiled|esm|cjs|output)(\/|$)/,ea=/\b(esbuild|tsup|tsdown|tsc|rollup|webpack|ncc|swc|babel|vite|parcel|bun\s+build|pkg|unbuild|microbundle|rspack)\b/,ta=/^(tsup|tsdown|unbuild|build|rollup|vite|webpack|esbuild|rspack)[\w.-]*\.(mts|cts|mjs|cjs|js|ts)$/i,Fe=e=>{try{return it.statSync(e).isFile()}catch{return!1}},Kn=e=>e.split(te.sep).join("/"),Xn=e=>{if(Fe(e)&&sn.includes(te.extname(e))&&!/\.d\.ts$/.test(e))return e;let t=e.replace(/\.(m|c)?js$/,"");for(let n of sn)if(Fe(t+n)&&!/\.d\.ts$/.test(t+n))return t+n;return null},rn=(e,t)=>{let n=te.relative(e,t);return n&&!n.startsWith("..")&&!te.isAbsolute(n)&&!/(^|[\\/])node_modules([\\/]|$)/.test(n)};function na(e,t){let n=Fe(t+".map")?t+".map":null;if(!n&&Fe(t))try{let c=it.readFileSync(t,"utf8").slice(-400),a=/sourceMappingURL=([^\s*]+)/.exec(c);if(a&&!a[1].startsWith("data:")){let l=te.resolve(te.dirname(t),a[1]);Fe(l)&&(n=l)}}catch{}if(!n)return null;let s;try{s=JSON.parse(it.readFileSync(n,"utf8"))}catch{return null}let o=te.resolve(te.dirname(n),s.sourceRoot??""),r=(s.sources??[]).map(c=>te.resolve(o,c)).filter(c=>rn(e,c)&&Fe(c)&&sn.includes(te.extname(c)));if(r.length===1)return r[0];let i=te.basename(t).replace(/\.(m|c)?js$/,"");return r.find(c=>te.basename(c).replace(/\.[^.]+$/,"")===i)??null}function oa(e){try{return JSON.parse(it.readFileSync(e,"utf8").replace(/\/\*[\s\S]*?\*\//g,"").replace(/^\s*\/\/.*$/gm,"").replace(/,(\s*[}\]])/g,"$1"))}catch{return null}}function sa(e,t){for(let n of["tsconfig.build.json","tsconfig.json"]){let o=oa(te.join(e,n))?.compilerOptions;if(!o?.outDir)continue;let r=Kn(te.normalize(o.outDir)).replace(/^\.\//,"").replace(/\/$/,"");if(!(t===r||t.startsWith(r+"/")))continue;let i=t.slice(r.length+1),c=o.rootDir?o.rootDir:it.existsSync(te.join(e,"src"))?"src":".",a=Xn(te.resolve(e,c,i));if(a)return a}return null}function ra(e,t){let n=t.split("/"),s=n.findIndex(r=>/^(dist|build|out|built|compiled|esm|cjs|lib|output)$/.test(r));if(s<0)return null;let o=n.slice(s+1).join("/");for(let r of["src","source","sources"]){let i=Xn(te.resolve(e,...n.slice(0,s),r,o));if(i&&rn(e,i))return i}return null}function ia(e,t,n){let s=te.basename(n).replace(/\.(m|c)?js$/,"");for(let o of["build","compile","bundle","prepare","prepublishOnly","prepack","postinstall"]){let r=t.scripts?.[o];if(!r||!ea.test(r))continue;let i=[];for(let l of r.split(/\s+/).map(f=>f.replace(/^["']|["']$/g,"").replace(/^--?[\w-]+=/,""))){if(!sn.includes(te.extname(l))||/\.d\.ts$/.test(l))continue;let f=te.resolve(e,l);Fe(f)&&rn(e,f)&&!pr.test(Kn(te.relative(e,f)))&&i.push(f)}let c=[...new Set(i)];if(c.length===1)return c[0];let a=c.filter(l=>te.basename(l).replace(/\.[^.]+$/,"")===s);if(a.length===1)return a[0];if(c.length)return c[0]}return null}function ca(e,t){let n=[];try{n=it.readdirSync(e).filter(i=>ta.test(i)).sort()}catch{return null}let s=te.basename(t).replace(/\.(m|c)?js$/,""),o=[];for(let i of n){let c;try{c=it.readFileSync(te.join(e,i),"utf8")}catch{continue}for(let a of c.matchAll(/\bentry(?:Points)?\s*:\s*[[{]?\s*(?:["'\w-]+\s*:\s*)?["'`]([^"'`]+)["'`]/g)){let l=Xn(te.resolve(e,a[1]));l&&rn(e,l)&&o.push(l)}}let r=[...new Set(o)];return r.length===1?r[0]:r.find(i=>te.basename(i).replace(/\.[^.]+$/,"")===s)??null}function cn(e,t,n){if(typeof t!="string"||!t)return null;let s=Kn(te.normalize(t)).replace(/^\.\//,""),o=te.resolve(e,s);if(!Qc.test(s)||Fe(o)&&!pr.test(s)||Fe(o)&&/\.ts$/.test(o))return null;let i=[["sourcemap",()=>na(e,o)],["tsconfig outDir",()=>sa(e,s)],["convention",()=>Fe(o)?null:ra(e,s)],["build script",()=>ia(e,n??{},s)],["build config",()=>ca(e,s)]];for(let[c,a]of i){let l=null;try{l=a()}catch{}if(l&&l!==o)return{file:l,how:c}}return null}function mr(e,t){let n=new Map;for(let[s,o]of e){let r=o.socketListeners??[],i=Ae(s,o),c=fe(s,t);for(let a of r){if(a.isInlineHandler){let f=i.get(a);n.set(a.eventName,f);continue}if(!a.handlerName||!c.has(a.handlerName))continue;let l=c.get(a.handlerName);n.set(a.eventName,l)}}return n}import Zn from"node:fs";import U from"node:path";var Ne=e=>String(e??"").trim().replace(/^["']|["']$/g,""),an=e=>e.replace(/^\s*#.*$/,"").replace(/\s+#.*$/,"");function hr(e){let t=/^(\/[A-Za-z0-9_\-./]*?)\/?(?=$|[:(*{[])/.exec(String(e).trim()),n=t?t[1]:"";return n==="/"?"":n.replace(/\/+$/,"")}function gr(e,t){let n=e.split(/\r?\n/).map(an),s=v=>v.length-v.trimStart().length,o=[],r=null,i=!1,c=null,a=!1,l=0,f=null,y=()=>{f?.key&&f.fromService&&f.fromService!=="?"&&r.hostRefs.push({name:f.key,service:f.fromService,property:f.property}),f=null},u=(v,p,w)=>{p==="name"?v.name=Ne(w):p==="rootDir"?v.rootDir=Ne(w):p==="startCommand"&&(v.startCommand=Ne(w))};for(let v of n){if(!v.trim())continue;let p=s(v),w=v.trim();if(p===0){y(),r=null,a=!1,i=/^services\s*:/.test(w),c=null;continue}if(!i)continue;let I=w.startsWith("-");if(I&&(c==null||p===c)){c=p,y(),r={name:null,rootDir:null,startCommand:null,kept:[],hostRefs:[]},o.push(r),a=!1;let b=/^-\s*([A-Za-z]+)\s*:\s*(.*)$/.exec(w);b&&u(r,b[1],b[2]);continue}if(!r)continue;let g=/^(?:-\s*)?([A-Za-z]+)\s*:\s*(.*)$/.exec(w);if(g){if(g[1]==="envVars"){y(),a=!0,l=p;continue}if(a&&p>l){if(I&&(y(),f={key:null,fromService:null,property:null}),!f)continue;if(g[1]==="key")f.key=Ne(g[2]);else if(g[1]==="value"&&f.key){let b=Ge(f.key,Ne(g[2]),t);b&&r.kept.push(b)}else g[1]==="fromService"?f.fromService="?":g[1]==="name"&&f.fromService==="?"?f.fromService=Ne(g[2]):g[1]==="property"&&(f.property=Ne(g[2]));continue}a&&(y(),a=!1),u(r,g[1],g[2])}}return y(),o.filter(v=>v.name)}function yr(e,t){let n={app:null,ports:[],kept:[]},s="";for(let o of e.split(/\r?\n/)){let r=an(o).trim();if(!r)continue;let i=/^\[\[?\s*([A-Za-z0-9_.]+)\s*\]\]?$/.exec(r);if(i){s=i[1];continue}let c=/^([A-Za-z_][A-Za-z0-9_]*)\s*=\s*(.*)$/.exec(r);if(!c)continue;let[,a,l]=c;if(s===""&&a==="app"){let f=Ne(l);/^[a-z0-9][a-z0-9-]*$/i.test(f)&&(n.app=f)}else if(a==="internal_port"){let f=Number(Ne(l));Number.isInteger(f)&&f>=1&&f<=65535&&n.ports.push(f)}else if(s==="env"){let f=Ge(a,Ne(l),t);f&&n.kept.push(f)}}return n}function vr(e,t){let n={ports:[],kept:[]},s=e.replace(/\\\r?\n/g," ");for(let o of s.split(/\r?\n/)){let r=o.trim(),i=/^EXPOSE\s+(.+)$/i.exec(r);if(i){for(let a of i[1].split(/\s+/)){let l=Number(a.replace(/\/\w+$/,""));Number.isInteger(l)&&l>=1&&l<=65535&&n.ports.push(l)}continue}if(i=/^(?:ENV|ARG)\s+(.+)$/i.exec(r),!i)continue;let c=i[1];if(/^[A-Za-z_][A-Za-z0-9_]*=/.test(c)){let a=/([A-Za-z_][A-Za-z0-9_]*)=("([^"]*)"|'([^']*)'|\S*)/g,l;for(;l=a.exec(c);){let f=Ge(l[1],l[3]??l[4]??l[2],t);f&&n.kept.push(f)}}else{let a=/^([A-Za-z_][A-Za-z0-9_]*)\s+(.*)$/.exec(c);if(a){let l=Ge(a[1],Ne(a[2]),t);l&&n.kept.push(l)}}}return n}function wr(e){let t;try{t=JSON.parse(e)}catch{return[]}let n=[];for(let s of["rewrites","redirects"])for(let o of Array.isArray(t?.[s])?t[s]:[]){let r=typeof o?.destination=="string"?o.destination:"",i=/\/:[A-Za-z_]+\*?$/.test(r)?Ye(r.replace(/\/:[A-Za-z_]+\*?$/,"")):null;i&&typeof o.source=="string"&&n.push({prefix:hr(o.source),target:i,kind:`vercel.json ${s}`,strip:!0})}return n}function xr(e){let t=[],n=!1,s=null,o=()=>{if(s?.from&&s.to&&/\/:[A-Za-z_]+\*?$/.test(s.to)){let r=Ye(s.to.replace(/\/:[A-Za-z_]+\*?$/,""));r&&t.push({prefix:hr(s.from),target:r,kind:"netlify.toml redirects",strip:!0})}s=null};for(let r of e.split(/\r?\n/)){let i=an(r).trim();if(!i)continue;let c=/^\[\[?\s*([A-Za-z0-9_.]+)\s*\]\]?$/.exec(i);if(c){o(),n=c[1]==="redirects",s=n?{}:null;continue}if(!n||!s)continue;let a=/^(from|to)\s*=\s*(.*)$/.exec(i);a&&(s[a[1]]=Ne(a[2]))}return o(),t}function kr(e,t){let n;try{n=JSON.parse(e)}catch{return[]}let s=[],o=n&&typeof n=="object"?n.env:null;if(o&&typeof o=="object")for(let r of Object.keys(o).sort()){let i=o[r],c=typeof i=="string"?i:typeof i?.value=="string"?i.value:null,a=Ge(r,c,t);a&&s.push(a)}return s}function Sr(e,t,n){let s=[];if(n){let o;try{o=JSON.parse(e)}catch{return s}let r=(i,c)=>{if(!(!i||typeof i!="object"||c>4))for(let a of Object.keys(i).sort()){let l=i[a];if(/^(env|envVars|variables|environment)$/i.test(a)&&l&&typeof l=="object"&&!Array.isArray(l))for(let f of Object.keys(l).sort()){let y=typeof l[f]=="string"?l[f]:typeof l[f]?.value=="string"?l[f].value:null,u=Ge(f,y,t);u&&s.push(u)}else r(l,c+1)}};r(o,0)}else{let o="";for(let r of e.split(/\r?\n/)){let i=an(r).trim();if(!i)continue;let c=/^\[\[?\s*([A-Za-z0-9_.]+)\s*\]\]?$/.exec(i);if(c){o=c[1];continue}let a=/^([A-Za-z_][A-Za-z0-9_]*)\s*=\s*(.*)$/.exec(i);if(a&&/(^|\.)(env|variables|environment)$/i.test(o)){let l=Ge(a[1],Ne(a[2]),t);l&&s.push(l)}}}return s}var aa=[".env.local",".env",".env.development",".env.production",".env.example"],la=/^(PORT|HTTP_PORT|HTTPS_PORT|SERVER_PORT|API_PORT|APP_PORT|WS_PORT|WSS_PORT|WEBSOCKET_PORT|LISTEN_PORT)$/,fa=/^PUBLIC_(?:[A-Z0-9]+_)*(?:ORIGIN|URL|HOST|BASE_URL)$/,ua=new Set(["localhost","127.0.0.1","0.0.0.0","[::1]","host.docker.internal"]),da=512*1024,br=e=>e.split(U.sep).join("/");function ct(e){try{let t=Zn.lstatSync(e);return!t.isFile()||t.isSymbolicLink()||t.size>da?null:Zn.readFileSync(e,"utf8")}catch{return null}}function Ye(e){let t=String(e).trim().replace(/^["']|["']$/g,"");if(!/^(https?|wss?):\/\//i.test(t))return null;try{let n=new URL(t);if(!n.hostname)return null;let s=n.protocol.replace(":",""),o=n.hostname.toLowerCase(),r=n.port?Number(n.port):null,i=n.pathname.replace(/\/+$/,"");return{scheme:s,host:o,port:r,origin:`${s}://${o}${r?":"+r:""}`,path:i}}catch{return null}}function pa(e){let t=String(e).trim().replace(/^["']|["']$/g,"");return!/^[a-z0-9]([a-z0-9.-]*[a-z0-9])?(:\d{1,5})?(\/[^\s?#]*)?$/i.test(t)||!/[a-z]/i.test(t.split(/[/:]/)[0])?null:Ye("http://"+t)}var Qn=e=>{let t=String(e).trim().replace(/^["']|["']$/g,"");if(!/^\d{1,5}$/.test(t))return null;let n=Number(t);return n>=1&&n<=65535?n:null};function ma(e){let t=new Map;for(let n of e.split(/\r?\n/)){let s=/^\s*(?:export\s+)?([A-Za-z_][A-Za-z0-9_]*)\s*=\s*(.*?)\s*$/.exec(n);if(!s)continue;let o=s[2];if(/^["']/.test(o)){let r=o[0],i=o.indexOf(r,1);o=i>0?o.slice(1,i):o.slice(1)}else o=o.replace(/\s+#.*$/,"");t.set(s[1],o)}return t}function Ir(e,t,n=0,s=new Set){let o=e.get(t);return o==null||n>5||s.has(t)||(s.add(t),o=o.replace(/\$\{([A-Za-z_][A-Za-z0-9_]*)(?::?-([^}]*))?\}/g,(r,i,c)=>{let a=e.has(i)?Ir(e,i,n+1,s):void 0;return a!=null&&a!==""?a:c??""}),s.delete(t)),o}function Ge(e,t,n){if(t==null)return null;if(la.test(e)){let o=Qn(t);return o?{name:e,kind:"port",file:n,port:o}:null}let s=Ye(t)??(/(_URL|_URI|_HOST|_HOSTNAME|_ORIGIN|_ADDR|_ENDPOINT)$/i.test(e)?pa(t):null);return s?{name:e,kind:"url",file:n,...s}:null}function $r(e,t){let n=[];for(let s of[...e.keys()].sort()){let o=Ir(e,s);if(o==null)continue;let r=Ge(s,o,t);r&&n.push(r)}return n}function ha(e){let t=e.split(/\r?\n/).map(l=>l.replace(/\s+#.*$/,"").replace(/\t/g," ")),n=l=>l.length-l.trimStart().length,s=[],o=t.findIndex(l=>/^services\s*:\s*$/.test(l));if(o<0)return s;let r=null,i=null,c=null,a=0;for(o=o+1;o<t.length;o++){let l=t[o];if(!l.trim())continue;let f=n(l),y=l.trim();if(f===0)break;if(r==null&&(r=f),f===r){let u=/^([A-Za-z0-9_.-]+)\s*:\s*$/.exec(y);u&&(i={name:u[1],ports:[],env:new Map,build:null},s.push(i),c=null);continue}if(i){if(f<=r+4&&/^[A-Za-z_]+\s*:/.test(y)&&!y.startsWith("-")){let u=/^([A-Za-z_]+)\s*:\s*(.*)$/.exec(y);c=u[1],a=f,c==="build"&&u[2]&&(i.build=u[2].replace(/^["']|["']$/g,""));continue}if(c==="build"&&/^context\s*:/.test(y)){i.build=y.replace(/^context\s*:\s*/,"").replace(/^["']|["']$/g,"");continue}if(c==="ports"&&y.startsWith("-")){let v=y.slice(1).trim().replace(/^["']|["']$/g,"").replace(/\/\w+$/,"").split(":"),p=v.slice(-2).map(w=>Qn(w));v.length===1&&p[0]?i.ports.push({host:null,container:p[0]}):v.length>=2&&p[0]&&p[1]&&i.ports.push({host:p[0],container:p[1]});continue}if(c==="environment"&&f>a){let u=y.startsWith("-")?/^-\s*([A-Za-z_][A-Za-z0-9_]*)\s*=\s*(.*)$/.exec(y):/^([A-Za-z_][A-Za-z0-9_]*)\s*:\s*(.*)$/.exec(y);u&&i.env.set(u[1],u[2].replace(/^["']|["']$/g,""))}}}return s}function Nr(e,t){let n=[];if(t==="vite"){let s=e.search(/\bproxy\s*:/);if(s<0)return n;let o=e.slice(s,s+2500),r=/["'`](\/[^"'`]*)["'`]\s*:\s*(?:["'`](https?:\/\/[^"'`]+)["'`]|\{[^{}]*?target\s*:\s*["'`](https?:\/\/[^"'`]+)["'`])/g,i;for(;i=r.exec(o);){let c=Ye(i[2]??i[3]);c&&n.push({prefix:i[1].replace(/\/+$/,""),target:c,kind:"vite.config proxy"})}}else if(t==="next"){let s=/source\s*:\s*["'`](\/[^"'`:*]*)[^"'`]*["'`]\s*,\s*destination\s*:\s*["'`](https?:\/\/[^"'`]+?)(?:\/:[^"'`]*)?["'`]/g,o;for(;o=s.exec(e);){let r=Ye(o[2]);r&&n.push({prefix:o[1].replace(/\/+$/,""),target:r,kind:"next.config rewrites"})}}return n}function jr(e,t,n){let s=g=>br(U.relative(e,g)),o=new Map,r=new Map,i=new Map,c=(g,b,$)=>{(g.get(b)??g.set(b,new Set).get(b)).add($)},a=(g,b,$)=>{let S=i.get(g)??i.set(g,[]).get(g);S.some(m=>m.service===b&&m.via===$)||S.push({service:b,via:$})},l=g=>{let b=[],$=U.resolve(g),S=U.resolve(e);for(let m=0;m<8&&(b.push($),!($===S||U.dirname($)===$||($=U.dirname($),!$.startsWith(S))));m++);return b},f=new Map,y=new Map,u=(g,b)=>{let $=g.env.get(b.name)??g.env.set(b.name,[]).get(b.name);$.some(S=>S.file===b.file)||$.push(b),b.kind==="port"&&g.ports.add(b.port)};function v(g,b,$){let S=d=>s(U.join($,d)),m=d=>ct(U.join($,d));for(let d of ln($))if(d==="fly.toml"){let k=m(d);if(k){let h=yr(k,S(d));for(let x of h.ports)b.ports.add(x);for(let x of h.kept)u(b,x);h.app&&(a(`${h.app.toLowerCase()}.internal`,g.name,"fly.toml app name"),a(`${h.app.toLowerCase()}.fly.dev`,g.name,"fly.toml app name"))}}else if(/^Dockerfile(\..+)?$/.test(d)){let k=m(d);if(k){let h=vr(k,S(d));for(let x of h.ports)b.weakPorts.add(x);for(let x of h.kept)u(b,x)}}else if(d==="railway.json"||d==="railway.toml"){let k=m(d);if(k)for(let h of Sr(k,S(d),d.endsWith(".json")))u(b,h)}else if(d==="app.json"){let k=m(d);if(k)for(let h of kr(k,S(d)))u(b,h)}else if(d==="vercel.json"){let k=m(d);if(k)for(let h of wr(k))b.proxies.push({...h,file:S(d)})}else if(d==="netlify.toml"){let k=m(d);if(k)for(let h of xr(k))b.proxies.push({...h,file:S(d)})}}for(let g of t){let b={env:new Map,ports:new Set,weakPorts:new Set,proxies:[],isServer:!1};o.set(g.name,b);for(let $ of l(g.rootPath)){for(let S of aa){let m=ct(U.join($,S));if(m!=null)for(let d of $r(ma(m),s(U.join($,S)))){let k=b.env.get(d.name)??b.env.set(d.name,[]).get(d.name);k.some(h=>h.file===d.file)||k.push(d),d.kind==="port"&&$===U.resolve(g.rootPath)&&/(^|\/)\.env/.test(d.file)&&!/\.example$/.test(d.file)&&b.ports.add(d.port),d.kind==="port"&&$===U.resolve(g.rootPath)&&/\.example$/.test(d.file)&&b.ports.add(d.port)}}if($===U.resolve(g.rootPath)){try{let S=JSON.parse(ct(U.join($,"package.json"))??"null"),m=typeof S?.proxy=="string"?Ye(S.proxy):null;m&&b.proxies.push({prefix:"",target:m,kind:'package.json "proxy"',file:s(U.join($,"package.json"))})}catch{}for(let S of ln($)){if(/^vite\.config\.(js|mjs|cjs|ts|mts)$/.test(S)){let m=ct(U.join($,S));if(m)for(let d of Nr(m,"vite"))b.proxies.push({...d,file:s(U.join($,S))})}if(/^next\.config\.(js|mjs|cjs|ts)$/.test(S)){let m=ct(U.join($,S));if(m)for(let d of Nr(m,"next"))b.proxies.push({...d,file:s(U.join($,S))})}}}$===U.resolve(g.rootPath)&&v(g,b,$);for(let S of ln($))if(/^render\.ya?ml$/.test(S)&&!y.has(U.join($,S))){let m=ct(U.join($,S));m&&y.set(U.join($,S),gr(m,s(U.join($,S))))}for(let S of ln($)){if(!/^docker-compose.*\.ya?ml$/.test(S)||f.has(U.join($,S)))continue;let m=ct(U.join($,S));m&&f.set(U.join($,S),ha(m))}}}for(let[g,b]of[...f].sort(($,S)=>$[0]<S[0]?-1:1)){let $=U.dirname(g);for(let S of b){let m=S.build?U.resolve($,S.build):null,d=t.find(h=>m&&U.resolve(h.rootPath)===m)??t.find(h=>h.name===S.name||U.basename(h.rootPath)===S.name);if(!d)continue;let k=o.get(d.name);for(let h of S.ports)k.ports.add(h.container),h.host&&k.ports.add(h.host);for(let h of $r(S.env,s(g)))(k.env.get(h.name)??k.env.set(h.name,[]).get(h.name)).push(h);a(S.name.toLowerCase(),d.name,"docker-compose service name")}}for(let[g,b]of[...y].sort(($,S)=>$[0]<S[0]?-1:1)){let $=U.dirname(g),S=new Map;for(let m of b){let d=U.resolve($,m.rootDir||"."),k=m.rootDir?t.find(x=>U.resolve(x.rootPath)===d):null;if(!k&&m.startCommand)for(let x of m.startCommand.split(/\s+/)){if(!/\.(c|m)?[jt]sx?$/.test(x)&&!/^[\w./-]+\/[\w.-]+$/.test(x))continue;let j=U.resolve(d,x),E=t.filter(M=>j.startsWith(U.resolve(M.rootPath)+U.sep)).sort((M,T)=>T.rootPath.length-M.rootPath.length)[0];if(E){k=E;break}}if(k=k??t.find(x=>x.name===m.name||U.basename(x.rootPath)===m.name),!k)continue;S.set(m.name,{target:k,c:m});let h=o.get(k.name);for(let x of m.kept)u(h,{...x,scoped:!0});a(m.name.toLowerCase(),k.name,"render.yaml service name"),a(`${m.name.toLowerCase()}.onrender.com`,k.name,"render.yaml service name (Render's default public address)")}for(let{target:m,c:d}of S.values())for(let k of d.hostRefs){let h=S.get(k.service);if(!h)continue;let x=[...h.c.kept].find(M=>M.kind==="port")?.port??null,j=k.property==="hostport"&&x,E=k.service.toLowerCase();u(o.get(m.name),{name:k.name,kind:"url",file:s(g),scheme:"http",host:E,port:j?x:null,origin:`http://${E}${j?":"+x:""}`,path:""})}}let p=g=>[...n.get(g.name)?.parseResults?.values()??[]].some(b=>(b.routes??[]).length>0);for(let g of t){let b=o.get(g.name);if(b.isServer=p(g),b.isServer){for(let[$,S]of b.env)if(fa.test($))for(let m of S)m.kind==="url"&&m.file&&(m.scoped||U.posix.dirname(m.file)===(br(U.relative(e,g.rootPath))||"."))&&a(m.host,g.name,`${$} in ${m.file} (the server's own public address)`)}}for(let g of t){let b=o.get(g.name);for(let[,$]of n.get(g.name)?.parseResults??[])for(let S of $.httpClients?.listens??[])for(let m of w(b,S.parts)){let d=Qn(m.text);d&&b.ports.add(d)}}for(let g of t)for(let b of o.get(g.name).ports)c(r,b,g.name);for(let g of t)for(let b of o.get(g.name).weakPorts)t.some($=>o.get($.name).ports.has(b))||c(r,b,g.name);function w(g,b){let $=[{text:"",evidence:[]}];for(let S of b){let m;if(S.t==="lit")m=[{text:S.v,evidence:[]}];else if(S.t==="env"){let k=g.env.get(S.name)??[];m=[];for(let h of k)m.push({text:h.kind==="port"?String(h.port):h.origin+h.path,evidence:[{env:S.name,file:h.file}]});!m.length&&S.fallback&&(m=w(g,S.fallback).map(x=>({text:x.text,evidence:[{env:S.name,file:null,fallback:!0},...x.evidence]})))}else m=[];if(!m.length)return[];let d=[];for(let k of $)for(let h of m)if(d.push({text:k.text+h.text,evidence:[...k.evidence,...h.evidence]}),d.length>=8)break;$=d.slice(0,8)}return $}let I=(g,b)=>{let $=[],S=g.host,m=i.get(S)??[];for(let d of m)$.push(d);if(ua.has(S)||m.length&&m.some(d=>d.via==="docker-compose service name")){let d=g.port??(g.scheme==="https"||g.scheme==="wss",null);if(d)for(let k of r.get(d)??[])$.some(h=>h.service===k)||$.push({service:k,via:`port ${d} (a service listening there)`})}return $.filter(d=>d.service!==b)};return{resolveBase(g,b){let $=o.get(g);if(!$||!b.length)return{status:"unknown"};let S=w($,b);if(!S.length)return{status:"unknown"};let m=[],d=new Set;for(let x of S){let j=Ye(x.text)??(x.text.startsWith("//"),null);if(j){d.add(j.origin);for(let E of I(j,g))m.push({...E,u:j,evidence:x.evidence})}}if(!d.size)return{status:"unknown"};let k=[...new Set(m.map(x=>x.service))];if(k.length===0)return{status:"external",origins:[...d].sort()};if(k.length>1)return{status:"ambiguous",services:k.sort()};let h=m[0];return{status:"service",service:h.service,via:h.via,origin:h.u.origin,basePath:h.u.path,evidence:h.evidence.filter((x,j,E)=>E.findIndex(M=>M.env===x.env&&M.file===x.file)===j)}},resolveProxy(g,b){let $=o.get(g);for(let S of $?.proxies??[]){if(S.prefix&&b!==S.prefix&&!b.startsWith(S.prefix+"/"))continue;let m=I(S.target,g),d=[...new Set(m.map(k=>k.service))];if(d.length===1)return{status:"service",service:d[0],via:`${S.kind} ${S.prefix||"/"} -> ${S.target.origin}`,origin:S.target.origin,basePath:S.target.path,strip:S.strip?S.prefix.split("/").filter(Boolean).length:0,evidence:[{env:null,file:S.file}]}}return{status:"unknown"}},portsOf:g=>[...o.get(g)?.ports??[]].sort((b,$)=>b-$),hostClaims:()=>[...i].sort((g,b)=>g[0]<b[0]?-1:1)}}function ln(e){try{return Zn.readdirSync(e).sort()}catch{return[]}}var fn=e=>String(e).toLowerCase();function un(e){let t=[];for(let n of e)n.t==="lit"&&t.length&&t[t.length-1].t==="lit"?t[t.length-1]={t:"lit",v:t[t.length-1].v+n.v}:t.push(n);return t}function Er(e,t){let n=[];for(let s of e){if(s.t!=="param"){n.push(s);continue}let o=t?.get(s.index);o?n.push(...o):n.push({t:"ref",name:s.name})}return un(n)}function eo(e){if(!e.length)return null;let t=e.slice(),n="none",s=null,o=t[0];if(o.t==="lit"){let l=/^(https?:)\/\/([^/?#]*)(.*)$/.exec(o.v);if(l){n="abs",s=l[2];let f=l[3];if(t=f?[{t:"lit",v:f},...t.slice(1)]:t.slice(1),/^(www\.)?(localhost|127\.0\.0\.1|\[::1\]|0\.0\.0\.0)(:\d+)?$/.test(s)===!1&&!/\.(local|internal|svc)$/.test(s)&&!/^[a-z0-9-]+(:\d+)?$/.test(s))return null}else if(!o.v.startsWith("/"))return null}else{for(n="var";t.length&&t[0].t!=="lit";)t.shift();if(!t.length||!t[0].v.startsWith("/"))return null}let r="",i=0,c=!1;for(let l of t){if(c)break;if(l.t==="lit"){let f=l.v.search(/[?#]/);f>=0?(r+=l.v.slice(0,f),c=!0):r+=l.v}else r+="",i++}if(!r.startsWith("/")&&!(r===""&&n==="abs"))return null;r===""&&(r="/");let a=r.split("/").slice(1).map(l=>l.includes("")?":p":l);for(;a.length>1&&a[a.length-1]==="";)a.pop();return{base:n,host:s,segments:a,placeholders:i,literal:n==="none"&&i===0}}function Cr(e){if(!e.length)return[];let t=e[0];if(t.t==="lit"){let s=/^((?:https?|wss?):\/\/[^/?#]*)/.exec(t.v);return s?[{t:"lit",v:s[1]}]:[]}let n=[];for(let s of e){if(s.t==="lit"&&s.v.startsWith("/"))break;n.push(s)}return n}var ga=e=>String(e||"").split("/").filter(Boolean),Rr=e=>[...new Set(e)];function _r(e){let t=e.evidence??[];return{env:Rr(t.filter(n=>n.env).map(n=>n.env)),files:Rr(t.filter(n=>n.file).map(n=>n.file)),origin:e.origin,via:e.via,...t.some(n=>n.fallback)?{usedFallback:!0}:{}}}var Lr=(e,t)=>"base URL "+(e.env.length?e.env.join(", ")+(e.files.length?" in "+e.files.join(", "):"")+" = ":e.files.length?"(from "+e.files.join(", ")+") ":"")+e.origin+" belongs to "+t+" ("+e.via+")",ya=e=>{let t=String(e).split(/[?#]/)[0].split("/").slice(1).map(n=>n.startsWith(":")||/^\{.*\}$/.test(n)||n==="*"?":p":n);for(;t.length>1&&t[t.length-1]==="";)t.pop();return t};function Pr(e,t){if(e.length===t.length){let n=!0,s=!0;for(let o=0;o<e.length;o++){let r=e[o],i=t[o];if(r!==i&&(n=!1),!(r===i||r===":p"||i===":p")){s=!1;break}}if(n)return 3;if(s)return 2}if(e[0]==="api"&&e.length>1){let n=e.slice(1);if(/^v\d+$/.test(n[0])&&n.length>1&&(n=n.slice(1)),n.length===t.length&&n.every((s,o)=>s===t[o]||s===":p"||t[o]===":p"))return 1}return 0}function va(e,t,n,s,o){let r=(n.importBindings??[]).find(y=>y.local===s);if(!r)return null;let i=ve(r.source,t,o);if(!i)return null;let c=e.parseResults.get(i),a=y=>e.nodes.find(u=>u.filePath===i&&u.name===y&&u.type!=="moduleRoot")?.id??null;if(r.kind==="named"&&r.imported)return a(r.imported);let l=c?.exportBindings;if(l?.default&&l.default!=="<anon>")return a(l.default);let f=Object.keys(l?.named??{});return f.length===1?a(f[0]):null}function wa(e){let t=[],n=[...e.parseResults.keys()];for(let[s,o]of e.parseResults){let r=e.nodes.filter(a=>a.filePath===s);if(r[0]?.category!=="backend")continue;let i=Ae(s,o),c=fe(s,e.nodes);for(let a of o.routes??[]){let l=null;a.isInlineHandler?l=i.get(a):a.nest?l=r.find(y=>y.type==="classMethod"&&y.className===a.nest.className&&y.name===a.nest.methodName)?.id??null:a.handlerName&&c.has(a.handlerName)?l=c.get(a.handlerName):a.handlerName&&(l=va(e,s,o,a.handlerName,n));let f=!1;l||(l=ce(a.startLine,r)?.id??null,f=!0),l&&t.push({method:fn(a.method),path:a.path,segments:ya(a.path),literal:!/[:*{]/.test(a.path),nodeId:l,file:s,line:a.startLine,fallback:f})}}return t}var xa=/^(ws|uws|websocket|@nestjs\/platform-ws|@fastify\/websocket|fastify-websocket|express-ws)$/,ka=/^(socket\.io|@nestjs\/platform-socket\.io|socket\.io-client)$/;function Mr(e){let t=[...e].some(s=>ka.test(s)),n=[...e].some(s=>xa.test(s));return t&&n?"unknown":t?"socketio":n?"ws":null}function Sa(e){let t=[],n=new Set;for(let[,s]of e.parseResults)for(let o of s.imports??[])n.add(o.source);for(let[s,o]of e.parseResults){let r=o.socketListeners??[],i=r.find(w=>w.eventName==="connection");if(!i)continue;let c=Ae(s,o),a=fe(s,e.nodes),l=w=>w.isInlineHandler?c.get(w):w.handlerName&&a.has(w.handlerName)?a.get(w.handlerName):null,f=l(i);if(!f)continue;let y=w=>i.handlerStartLine!=null&&w.startLine>=i.handlerStartLine&&w.startLine<=i.handlerEndLine,u=r.find(w=>w.eventName==="message"&&y(w))??r.find(w=>w.eventName==="message"),v=o.httpClients?.wsServers??[],p=Mr(new Set((o.imports??[]).map(w=>w.source)))??Mr(n)??"unknown";t.push({filePath:s,nodeId:f,line:i.startLine,messageNodeId:u?l(u):null,messageLine:u?.startLine??null,pathParts:v.find(w=>w.path)?.path??null,kind:p})}return t}function Or(e,t,n={}){let s=n.repoRoot?jr(n.repoRoot,e,t):null,o=[],r=new Set,i={restCalls:0,restLinked:0,wsClients:0,wsLinked:0,wsSends:0,wsSendsLinked:0},c=l=>{let f=[l.fromService,l.fromNodeId,l.toService,l.toNodeId,l.via,l.key].join("\0");r.has(f)||(r.add(f),o.push(l))},a=new Map;for(let l of e){let f=t.get(l.name);f&&a.set(l.name,{routes:wa(f),wsServers:Sa(f)})}for(let l of e){let f=t.get(l.name);if(!f)continue;let y=[...f.parseResults.keys()],u=new Map,v=new Map;for(let[m,d]of f.parseResults){let k=d.httpClients;if(k){for(let h of k.httpInstances??[])(u.get(h.name)??u.set(h.name,[]).get(h.name)).push(h);for(let h of k.httpCalls??[])(h.parts.some(j=>j.t==="param")||h.method&&typeof h.method=="object")&&h.fn?.name&&(v.get(h.fn.name)??v.set(h.fn.name,[]).get(h.fn.name)).push({filePath:m,call:h})}}let p=m=>{if(!m.startsWith("inst:")&&!m.startsWith("obj:"))return[];let d=u.get(m.slice(m.indexOf(":")+1));return d&&d.length===1?d[0].parts:m.startsWith("obj:")?null:[{t:"ref",name:"?"}]},w=[],I=(m,d)=>ce(d,f.nodes.filter(k=>k.filePath===m)),g=new Set,b=m=>m.parts.some(d=>d.t==="param")||m.method&&typeof m.method=="object";for(let[m,d]of f.parseResults){let k=d.httpClients;if(k){for(let h of k.httpCalls??[]){if(b(h))continue;let x=p(h.client);if(x===null)continue;let j=I(m,h.line);j&&w.push({filePath:m,line:h.line,nodeId:j.id,method:h.method,parts:un([...x,...h.parts]),via:h.client.replace(/^obj:/,"inst:"),wrapper:null})}for(let h of k.pathCallsites??[]){let x=v.get(h.callee);if(x)for(let j of x){let E=j.filePath===m;if(!E){let O=(d.importBindings??[]).find(C=>C.local===h.callee||C.imported===h.callee);O&&ve(O.source,m,y)===j.filePath&&(E=!0)}if(!E)continue;let M=new Map(h.args.map(O=>[O.i,O.parts])),T=typeof j.call.method=="object"&&j.call.method?(()=>{let O=M.get(j.call.method.param);return O&&O.length===1&&O[0].t==="lit"?O[0].v.toUpperCase():"?"})():j.call.method,L=I(m,h.line);L&&(g.add(j.call),w.push({filePath:m,line:h.line,nodeId:L.id,method:T,parts:Er([...p(j.call.client),...j.call.parts],M),via:j.call.client,wrapper:h.callee}))}}}}for(let[m,d]of f.parseResults)for(let k of d.httpClients?.httpCalls??[]){if(!b(k)||g.has(k))continue;let h=p(k.client);if(h===null)continue;let x=I(m,k.line);x&&w.push({filePath:m,line:k.line,nodeId:x.id,method:typeof k.method=="object"&&k.method?"?":k.method,parts:Er([...h,...k.parts],null),via:k.client.replace(/^obj:/,"inst:"),wrapper:null})}for(let m of w){let d=eo(m.parts);if(!d)continue;i.restCalls++;let k=0,h=[];for(let L of e){if(L.name===l.name)continue;let O=a.get(L.name);if(O)for(let C of O.routes){if(!(m.method==="?"||m.method==null||C.method===fn(m.method)||C.method==="all"||C.method==="use"))continue;let K=Pr(d.segments,C.segments);K&&(K>k&&(k=K,h.length=0),K===k&&h.push({service:L.name,route:C}))}}let x={status:"unknown"};if(s){let L=un(m.parts);if(d.base==="none"?x=s.resolveProxy(l.name,"/"+d.segments.join("/")):x=s.resolveBase(l.name,Cr(L)),x.status==="service"){let O=ga(x.basePath);if(O.length||x.strip){let C=[...O,...d.segments.slice(x.strip||0)];for(let z of a.get(x.service)?.routes??[])(m.method==="?"||m.method==null||z.method===fn(m.method)||z.method==="all"||z.method==="use")&&Pr(C,z.segments)&&!h.some(R=>R.service===x.service&&R.route.nodeId===z.nodeId)&&h.push({service:x.service,route:z,viaBasePath:!0})}}}if(!h.length)continue;let j=new Set(h.map(L=>L.service+"\0"+L.route.nodeId)),E=typeof m.method=="string"&&m.method!=="?",M=k===3&&d.literal&&E&&j.size===1&&h[0].route.literal&&!h[0].route.fallback&&h[0].route.method===fn(m.method),T=[];d.base==="var"&&T.push("base URL is a variable, so the target service is guessed from the path"),d.base==="abs"&&T.push("absolute URL"),d.placeholders&&T.push("path has parameters"),k===1&&T.push("leading /api removed from the client path"),k===2&&T.push("route parameters matched fuzzily"),E||T.push("method not known"),j.size>1&&T.push(j.size+" candidate routes"),h.some(L=>L.route.fallback)&&T.push("route handler not resolved: linked to the function that registers the route"),x.status==="external"&&T.push("base URL is "+x.origins.join(" / ")+", which no service of this repo owns"),x.status==="ambiguous"&&T.push("base URL could belong to "+x.services.join(" or "));for(let L of h){i.restLinked++;let O=!M&&x.status==="service"&&x.service===L.service&&!L.route.fallback,C=O?_r(x):null,z=M?"exact":O?"resolved":"inferred",K=!M&&x.status==="service"&&x.service!==L.service?["base URL belongs to "+x.service+", not this service"]:[];c({fromService:l.name,fromNodeId:m.nodeId,toService:L.service,toNodeId:L.route.nodeId,via:"httpCall",key:`${E?m.method:"ANY"} ${"/"+d.segments.join("/")}`,confidence:z,method:E?m.method:null,url:"/"+d.segments.join("/"),client:m.via,...m.wrapper?{wrapper:m.wrapper}:{},line:m.line,...M?{}:O?{reason:Lr(C,L.service)+(E?"":"; method not known"),resolvedFrom:C}:{reason:[...T,...K].join("; ")||"path-only match"}})}}let $=[];for(let[m,d]of f.parseResults)for(let k of d.httpClients?.wsClients??[])$.push({filePath:m,w:k});let S=m=>m.client==="io"?"socketio":"ws";for(let{filePath:m,w:d}of $){let k=I(m,d.line);if(!k)continue;i.wsClients++;let h=un(d.parts),x=/^wss?:\/\//.test(h[0]?.v??"")?eo([{t:"lit",v:h[0].v.replace(/^ws(s?):/,"http$1:")},...h.slice(1)]):eo(h),j=s&&x?s.resolveBase(l.name,Cr(h)):{status:"unknown"};for(let E of e)if(E.name!==l.name)for(let M of a.get(E.name)?.wsServers??[]){if(M.kind!=="unknown"&&M.kind!==S(d))continue;let T=M.pathParts&&M.pathParts.every(K=>K.t==="lit")?"/"+M.pathParts.map(K=>K.v).join("").replace(/^\//,""):null,L=x?"/"+x.segments.join("/"):null;if(T&&L&&T!==L&&T!=="/"&&L!=="/")continue;let O=!!(x&&x.literal&&T&&L===T&&M.kind!=="unknown"),C=!O&&j.status==="service"&&j.service===E.name,z=C?_r(j):null;i.wsLinked++,c({fromService:l.name,fromNodeId:k.id,toService:E.name,toNodeId:M.nodeId,via:"webSocket",key:L??"(url unknown)",confidence:O?"exact":C?"resolved":"inferred",url:L,client:d.client,line:d.line,...O?{}:C?{reason:Lr(z,E.name),resolvedFrom:z}:{reason:"WebSocket connection matched to a WebSocket server of another service ("+(x?.base==="var"?"URL base is a variable":"no path on the server to compare")+(j.status==="external"?"; base URL is "+j.origins.join(" / ")+", which no service of this repo owns":"")+")"}})}}if($.length){let m=new Set($.map(({w:d})=>S(d)));for(let[d,k]of f.parseResults)for(let h of k.httpClients?.wsSends??[]){let x=I(d,h.line);if(x){i.wsSends++;for(let j of e)if(j.name!==l.name)for(let E of a.get(j.name)?.wsServers??[])!E.messageNodeId||E.kind!=="unknown"&&!m.has(E.kind)||(i.wsSendsLinked++,c({fromService:l.name,fromNodeId:x.id,toService:j.name,toNodeId:E.messageNodeId,via:"webSocketMessage",key:"message",eventName:"message",confidence:"inferred",client:h.recv,line:h.line,reason:"a message sent over a socket whose payload is built at run time; delivered to the message listener of a WebSocket server of another service"}))}}}}if(n.serverPush!==!1){let l=new Map;for(let y of o)if(y.via==="webSocket"){let u=y.fromService+"\0"+y.toService;(l.get(u)??l.set(u,[]).get(u)).push(y)}let f=new Map;for(let y of l.values())(f.get(y[0].toService)??f.set(y[0].toService,new Set).get(y[0].toService)).add(y[0].fromService);for(let[,y]of[...l].sort((u,v)=>u[0]<v[0]?-1:1)){let u=y[0].fromService,v=y[0].toService,p=t.get(u),w=t.get(v);if(!p||!w||!(a.get(v)?.wsServers??[]).length)continue;let I=new Set(y.map(S=>S.fromNodeId.split("::")[0])),g=[];for(let[S,m]of p.parseResults){if(!I.has(S))continue;let d=fe(S,p.nodes),k=Ae(S,m),h=p.nodes.filter(x=>x.filePath===S);for(let x of m.httpClients?.wsReceivers??[]){let j=x.handlerName&&d.get(x.handlerName)||ce(x.line,h)?.id;j&&g.push({id:j,line:x.line})}for(let x of m.socketListeners??[]){if(x.eventName!=="message")continue;let j=x.isInlineHandler?k.get(x):x.handlerName&&d.get(x.handlerName)||null;j&&g.push({id:j,line:x.startLine})}}let b=new Set(p.resolvedEdges.filter(S=>S.resolved&&S.targetNodeId&&S.type!=="returnValue").map(S=>S.fromNodeId));for(let S=g.length-1;S>=0;S--)b.has(g[S].id)||g.splice(S,1);if(!g.length)continue;let $=f.get(v)?.size??1;for(let[S,m]of w.parseResults){let d=w.nodes.filter(k=>k.filePath===S);for(let k of[...m.httpClients?.wsSends??[],...m.httpClients?.wsServerSends??[]]){let h=ce(k.line,d);if(h)for(let x of g)i.wsPushLinked=(i.wsPushLinked??0)+1,c({fromService:v,fromNodeId:h.id,toService:u,toNodeId:x.id,via:"webSocketDelivery",key:"message",eventName:"message",confidence:"inferred",client:k.recv,line:k.line,receiverLine:x.line,reason:"a message the server sends over a WebSocket (payload built at run time) is taken in by the message handler of "+u+", which connects to this server"+($>1?"; "+$+" services connect to this server, so it may be meant for another one":""),...$>1?{candidates:$}:{}})}}}}return o.sort((l,f)=>l.fromService+l.fromNodeId+l.via+l.key+l.toService+l.toNodeId<f.fromService+f.fromNodeId+f.via+f.key+f.toService+f.toNodeId?-1:1),{edges:o,stats:i}}import Ar from"node:fs";var ba=new Set("if for while switch catch return function super typeof new else do with await yield throw import export".split(" ")),$a=8;function Tr({files:e,resolveName:t,callArgs:n,matchClose:s,IDENT:o}){let r=new Map,i=m=>{let d=[],k=new RegExp(`\\bclass\\s+(${o})(?:\\s+extends\\s+(${o}))?[^{]*\\{`,"g"),h;for(;h=k.exec(m);){let x=h.index+h[0].length-1,j=s(m,x);j>0&&d.push({name:h[1],base:h[2]??null,open:x,close:j,start:h.index})}return d};for(let m of e){m.classes=i(m.t);for(let d of m.classes)r.set(d.name,(r.get(d.name)??0)+1)}let c=m=>r.get(m)===1,a=m=>{let d=m,k,h=/@[A-Za-z_$][\w$]*\s*\(/;for(;k=h.exec(d);){let x=s(d,k.index+k[0].length-1);if(x<0)break;d=d.slice(0,k.index)+d.slice(x+1)}return d},l="(?:(?:private|public|protected|readonly|override)\\s+)",f=m=>{let d=a(m).trim(),k=new RegExp(`^${l}*(${o})\\s*[?:=]`).exec(d)??new RegExp(`^${l}*(${o})\\s*$`).exec(d);return{name:k?k[1]:null,prop:new RegExp(`^${l}+`).test(d)}},y=(m,d)=>{let k=[],h=m.slice(d.open+1,d.close),x=new RegExp(`(?:^|[\\n;}{])\\s*(?:(?:public|private|protected|static|async|override)\\s+)*(${o})\\s*(?:<[^>(]*>)?\\s*\\(`,"g"),j;for(;j=x.exec(h);){if(ba.has(j[1]))continue;let E=n(h,j.index+j[0].length-1);if(!E)continue;let M=E.close+1;for(;M<h.length&&/\s/.test(h[M]);)M++;if(h[M]===":"){let O=h.indexOf("{",M);if(O<0)continue;M=O}if(h[M]!=="{")continue;let T=s(h,M);if(T<0)continue;let L=E.args.map(O=>f(O.text));k.push({name:j[1],params:L.map(O=>O.name),paramProps:L.map(O=>O.prop),body:h.slice(M+1,T)}),x.lastIndex=T}return k};for(let m of e)for(let d of m.classes)d.methods=y(m.t,d),d.ctor=d.methods.find(k=>k.name==="constructor")??null;let u=new Map,v=new Map;for(let m of e)for(let d of m.classes)for(let k of d.methods){if(k.name==="constructor")continue;let h=new RegExp(`new\\s+(?:Queue|Bull|BullQueue)\\s*(?:<[^>]*>)?\\s*\\(\\s*(${o})\\s*[,)]`).exec(k.body);h&&k.params.includes(h[1])&&(u.has(k.name)||u.set(k.name,new Set),u.get(k.name).add(k.params.indexOf(h[1])));let x=new RegExp(`new\\s+Worker\\s*(?:<[^>]*>)?\\s*\\(\\s*(${o})\\s*,\\s*(${o})\\s*[,)]`).exec(k.body);x&&k.params.includes(x[1])&&k.params.includes(x[2])&&(v.has(k.name)||v.set(k.name,new Map),v.get(k.name).set(k.params.indexOf(x[1]),k.params.indexOf(x[2])))}let p=(m,d)=>{let k=m.ctor?.params[d];if(!k)return new Set;let h=new Set([k]);m.ctor.paramProps[d]&&h.add("this."+k);let x=new RegExp(`this\\.(${o})\\s*=\\s*${k.replace(/\$/g,"\\$")}\\s*[;,\\n]`,"g"),j;for(;j=x.exec(m.ctor.body);)h.add("this."+j[1]);return h},w=(m,d)=>{let k=[],h=new RegExp(`(?<![\\w$])${d}\\s*\\(`,"g"),x;for(;x=h.exec(m);){let j=n(m,x.index+x[0].length-1);j&&k.push(j.args.map(E=>E.text.trim()))}return k},I=new Map,g=new Map;for(let m of e)for(let d of m.classes){if(!c(d.name)||!d.ctor)continue;let k=m.t.slice(d.open,d.close),h=new RegExp(`new\\s+(?:Queue|Bull|BullQueue)\\s*(?:<[^>]*>)?\\s*\\(\\s*(${o})\\s*[,)]`).exec(d.ctor.body);if(h&&d.ctor.params.includes(h[1]))I.set(d.name,{file:m.file,paramIndex:d.ctor.params.indexOf(h[1])});else{let x=null;for(let j=0;j<d.ctor.params.length&&x===null;j++){let E=p(d,j);for(let[M,T]of u)for(let L of w(k,M))for(let O of T)L[O]!==void 0&&E.has(L[O])&&(x=j)}x!==null&&I.set(d.name,{file:m.file,paramIndex:x})}for(let x=0;x<d.ctor.params.length;x++){let j=p(d,x),E=new Map;for(let M of d.methods)for(let[T,L]of v)for(let O of w(M.body,T))for(let[C,z]of L)O[C]!==void 0&&j.has(O[C])&&O[z]!==void 0&&M.params.includes(O[z])&&E.set(M.name,M.params.indexOf(O[z]));for(let M=0;M<3&&E.size;M++)for(let T of d.methods)for(let[L,O]of[...E])for(let C of w(T.body,"this\\."+L))C[O]!==void 0&&T.params.includes(C[O])&&!E.has(T.name)&&E.set(T.name,T.params.indexOf(C[O]));if(E.size){g.set(d.name,{file:m.file,paramIndex:x,registrars:E});break}}}let b=m=>{for(let d=0;d<$a;d++){let k=!1;for(let h of e)for(let x of h.classes){if(!x.base||m.has(x.name)||!c(x.name)||!c(x.base))continue;let j=m.get(x.base);if(!j)continue;if(j.name!==void 0||!x.ctor){m.set(x.name,{...j}),k=!0;continue}let E=/\bsuper\s*\(/.exec(x.ctor.body);if(!E)continue;let T=n(x.ctor.body,E.index+E[0].length-1)?.args[j.paramIndex];if(!T)continue;let L=t(T.text,h.file,h.t);if(L){m.set(x.name,{...j,name:L.name,how:L.how+" passed to the base class"}),k=!0;continue}let O=x.ctor.params.indexOf(T.text.trim());O>=0&&(m.set(x.name,{...j,paramIndex:O}),k=!0)}if(!k)break}};b(I),b(g);let $=new Map,S=new Map;for(let[m,d]of I)d.name!==void 0&&$.set(m,{name:d.name,how:d.how});for(let[m,d]of g)d.name!==void 0&&S.set(m,d);return{producerClasses:$,workerClasses:S,unique:c}}var Na=/\b(?:Queue|Bull|Worker|Processor|InjectQueue|WorkerHost)\b|\.process\s*\(|\b[A-Za-z_$]*(?:Queue|Worker)[A-Za-z_$]*(?:Service|Base)\b|\b(?:createQueue|createWorker|initWorker)\b/,Ie="[A-Za-z_$][\\w$]*",Ia=1024*1024;function Fr(e){let t="",n=0,s=null;for(;n<e.length;){let o=e[n],r=e[n+1];if(s){if(t+=o,o==="\\"){t+=e[n+1]??"",n+=2;continue}o===s&&(s=null),n++}else if(o==="/"&&r==="/")for(;n<e.length&&e[n]!==`
|
|
12
12
|
`;)t+=" ",n++;else if(o==="/"&&r==="*"){for(t+=" ",n+=2;n<e.length&&!(e[n]==="*"&&e[n+1]==="/");)t+=e[n]===`
|
|
13
13
|
`?`
|
|
14
|
-
`:" ",n++;t+=" ",n+=2}else(o==='"'||o==="'"||o==="`")&&(s=o),t+=o,n++}return t}function no(e,t){let n={"(":")","[":"]","{":"}"},s=[],o=null;for(let r=t;r<e.length;r++){let i=e[r];if(o){i==="\\"?r++:i===o&&(o=null);continue}if(i==='"'||i==="'"||i==="`"){o=i;continue}if(n[i])s.push(n[i]);else if(i===")"||i==="]"||i==="}"){if(s.pop()!==i)return-1;if(!s.length)return r}}return-1}function at(e,t){let n=no(e,t);if(n<0)return null;let s=[],o=0,r=null,i=t+1;for(let c=t+1;c<n;c++){let a=e[c];if(r){a==="\\"?c++:a===r&&(r=null);continue}if(a==='"'||a==="'"||a==="`"){r=a;continue}a==="("||a==="["||a==="{"?o++:a===")"||a==="]"||a==="}"?o--:a===","&&o===0&&(s.push({text:e.slice(i,c),start:i}),i=c+1)}return e.slice(i,n).trim()&&s.push({text:e.slice(i,n),start:i}),{args:s,close:n}}function
|
|
15
|
-
`&&t.push(n+1);return n=>{let s=0,o=t.length-1;for(;s<o;){let r=s+o+1>>1;t[r]<=n?s=r:o=r-1}return s+1}}var $a=e=>{let t=e.trim(),n=/^(['"])([^'"\\\n]*)\1$/.exec(t);return n?n[2]:(n=/^`([^`$\\]*)`$/.exec(t),n?n[1]:null)},Or=e=>new RegExp(`(?:const|let|var|readonly|static)\\s+${e.replace(/\$/g,"\\$")}\\s*(?::[^=;{]+)?=\\s*(['"\`])([^'"\`$\\\\\\n]*)\\1`);function to(e,t){let n=t.exec(e);if(!n)return null;let s=e.indexOf("{",n.index+n[0].length-1);if(s<0)return null;let o=no(e,s);return o<0?null:e.slice(s+1,o)}function Tr(e,t,n){let s=t.replace(/\$/g,"\\$"),o=n.replace(/\$/g,"\\$"),r=to(e,new RegExp(`\\benum\\s+${s}\\s*\\{`));if(r){let i=new RegExp(`(?:^|[,{\\s])${o}\\s*=\\s*(['"\`])([^'"\`$\\\\\\n]*)\\1`).exec(r);return i?i[2]:null}if(r=to(e,new RegExp(`(?:const|let|var)\\s+${s}\\s*(?::[^=]+)?=\\s*\\{`))??to(e,new RegExp(`\\bclass\\s+${s}\\b[^{]*\\{`)),r){let i=new RegExp(`(?:^|[,{\\s])(?:static\\s+(?:readonly\\s+)?)?${o}\\s*[:=]\\s*(['"\`])([^'"\`$\\\\\\n]*)\\1`).exec(r);return i?i[2]:null}return null}function Na(e){let t=new Map,n=/import\s+(?:type\s+)?([^'";]*?)\s+from\s*['"]([^'"]+)['"]/g,s;for(;s=n.exec(e);){let o=s[1].trim(),r=s[2],i=/\{([^}]*)\}/.exec(o);if(i)for(let l of i[1].split(",")){let f=l.trim().replace(/^type\s+/,"");if(!f)continue;let y=/^(\S+)\s+as\s+(\S+)$/.exec(f);y?t.set(y[2],{spec:r,imported:y[1]}):t.set(f,{spec:r,imported:f})}let c=/\*\s*as\s+(\S+)/.exec(o);c&&t.set(c[1],{spec:r,imported:"*"});let a=/^([A-Za-z_$][\w$]*)\s*(?:,|$)/.exec(o);a&&!o.startsWith("{")&&!o.startsWith("*")&&t.set(a[1],{spec:r,imported:"default"})}return t}function Ar(e){let t=[],n,s=/export\s*\*\s*from\s*['"]([^'"]+)['"]/g;for(;n=s.exec(e);)t.push({spec:n[1],all:!0});let o=/export\s*\{([^}]*)\}\s*from\s*['"]([^'"]+)['"]/g;for(;n=o.exec(e);){let r=new Map;for(let i of n[1].split(",")){let c=i.trim();if(!c)continue;let a=/^(\S+)\s+as\s+(\S+)$/.exec(c);a?r.set(a[2],a[1]):r.set(c,c)}t.push({spec:n[2],names:r})}return t}function Fr(e,t,{readFile:n=s=>Pr.statSync(s).size>Sa?null:Pr.readFileSync(s,"utf8")}={}){let s=[],o=new Map,r=new Map;for(let h of e){let x=t.get(h.name);if(x){for(let j of x.files??[])s.push(j),r.has(j)||r.set(j,h.name);for(let j of x.nodes){let E=h.name+"\0"+j.filePath;o.has(E)||o.set(E,[]),o.get(E).push(j)}}}let i=new Map,c=h=>{if(i.has(h))return i.get(h);let x=null;try{x=Mr(n(h)??"")}catch{x=null}return i.size>400&&i.clear(),i.set(h,x),x},a=new Map,l=(h,x)=>{let j=a.get(h);return j||(j=Na(x),a.set(h,j)),j};function f(h,x,j){let E=c(h);if(E==null||j>3)return null;let M=Or(x).exec(E);if(M)return{value:M[2],how:"constant"};for(let T of Ar(E)){let L=T.all?x:T.names?.get(x);if(!L)continue;let O=ve(T.spec,h,s);if(O){let C=f(O,L,j+1);if(C)return C}}return null}function y(h,x,j,E){let M=c(h);if(M==null||E>3)return null;let T=Tr(M,x,j);if(T!=null)return{value:T,how:"enum or object member"};for(let L of Ar(M)){let O=L.all?x:L.names?.get(x);if(!O)continue;let C=ve(L.spec,h,s);if(C){let z=y(C,O,j,E+1);if(z)return z}}return null}function u(h,x,j){let E=String(h).trim().replace(/\s+as\s+[\w.<>[\]| ]+$/,"").replace(/!$/,"").trim(),M=/^\{\s*name\s*:\s*([\s\S]+?)\s*[,}]?\s*\}?$/.exec(E);M&&!/^['"`]/.test(E)&&(E=M[1].trim());let T=$a(E);if(T!==null)return T?{name:T,how:"literal"}:null;let L=new RegExp(`^(${Ie})$`).exec(E);if(L){let O=Or(L[1]).exec(j);if(O)return{name:O[2],how:"constant in the same file"};let C=l(x,j).get(L[1]);if(C&&C.imported!=="*"){let z=ve(C.spec,x,s);if(z){let K=f(z,C.imported==="default"?L[1]:C.imported,0);if(K)return{name:K.value,how:"imported constant"}}}return null}if(L=new RegExp(`^(${Ie})\\.(${Ie})$`).exec(E),L){let O=Tr(j,L[1],L[2]);if(O!=null)return{name:O,how:"enum or object member in the same file"};let C=l(x,j).get(L[1]);if(C){let z=ve(C.spec,x,s);if(z){let K=C.imported==="*"?f(z,L[2],0):y(z,C.imported==="default"?L[1]:C.imported,L[2],0);if(K)return{name:K.value,how:C.imported==="*"?"imported constant":"imported enum or object member"}}}}return null}let v=[];for(let h of s){let x=r.get(h);if(!x)continue;let j=null;try{j=n(h)}catch{j=null}if(j==null||!ka.test(j))continue;let E=Mr(j);v.push({file:h,service:x,t:E,line:ba(E)})}let{producerClasses:p,workerClasses:w,unique:I}=Lr({files:v,resolveName:u,callArgs:at,matchClose:no,IDENT:Ie}),g=[],b=[],$=0,S=0;for(let h of v){let{file:x,service:j,t:E}=h,M=o.get(j+"\0"+x)??[],T=A=>ce(h.line(A),M),L=new Map,O=(A,G)=>{(!L.has(A)||L.get(A)===null&&G)&&L.set(A,G)},C,z=new RegExp("new\\s+(?:Queue|Bull|BullQueue)\\s*(?:<[^>]*>)?\\s*\\(","g");for(;C=z.exec(E);){let A=E.slice(Math.max(0,C.index-160),C.index),G=new RegExp(`(${Ie})\\s*(?::[^=;]+)?=\\s*$`).exec(A),J=at(E,C.index+C[0].length-1);!G||!J||!J.args[0]||O(G[1],u(J.args[0].text,x,E))}let K=new RegExp("@InjectQueue\\s*\\(","g");for(;C=K.exec(E);){let A=at(E,C.index+C[0].length-1);if(!A)continue;let G=E.slice(A.close+1,A.close+200),J=new RegExp(`^\\s*(?:(?:private|public|protected|readonly)\\s+)*(${Ie})`).exec(G);J&&O(J[1],A.args[0]?u(A.args[0].text,x,E):null)}let R=new RegExp(`(?:private|public|protected)\\s+(?:readonly\\s+)?(${Ie})\\s*:\\s*(${Ie})`,"g"),W=new Map;for(;C=R.exec(E);)p.has(C[2])&&I(C[2])&&O(C[1],p.get(C[2])),w.has(C[2])&&I(C[2])&&W.set(C[1],w.get(C[2]));let X=new RegExp(`(${Ie})\\s*\\.\\s*(add|addBulk)\\s*\\(`,"g");for(;C=X.exec(E);){let A=L.get(C[1]);if(A===void 0)continue;let G=T(C.index);if(!A){$++;continue}G&&g.push({queue:A.name,how:A.how,service:j,nodeId:G.id,line:h.line(C.index)})}let oe=(A,G)=>{let J=A.trim();if(/^(?:async\s+)?(?:function\b|\([^)]*\)\s*(?::[^=]+)?=>|[\w$]+\s*=>)/.test(J))return{node:T(G+A.indexOf(J)),how:"inline handler"};let ae=new RegExp(`^this\\.(${Ie})(?:\\.bind\\(this\\)|\\(\\s*\\))?$`).exec(J),be=ae?ae[1]:new RegExp(`^(${Ie})$`).exec(J)?.[1];if(!be)return null;let he=M.filter(ie=>ie.type!=="moduleRoot"&&(ie.name===be||String(ie.name).endsWith("."+be)));if(he.length===1)return{node:he[0],how:"named handler"};if(ae&&he.length>1){let ie=h.classes.filter(N=>N.open<=G&&G<=N.close).sort((N,_)=>_.open-N.open)[0];if(ie){let N=he.filter(_=>_.startLine>=h.line(ie.open)&&_.endLine<=h.line(ie.close));if(N.length===1)return{node:N[0],how:"named handler"}}}let Me=l(x,E).get(be);if(Me){let ie=ve(Me.spec,x,s);if(ie){let N=(o.get(r.get(ie)+"\0"+ie)??[]).filter(_=>_.type!=="moduleRoot"&&_.name===(Me.imported==="default"?be:Me.imported));if(N.length===1)return{node:N[0],how:"imported handler",service:r.get(ie)}}}return null},re=new RegExp("new\\s+Worker\\s*(?:<[^>]*>)?\\s*\\(","g");for(;C=re.exec(E);){let A=at(E,C.index+C[0].length-1);if(!A||A.args.length<2)continue;let G=u(A.args[0].text,x,E);if(!G){S++;continue}let J=oe(A.args[1].text,A.args[1].start);J?.node&&b.push({queue:G.name,how:G.how+", "+J.how,service:J.service??j,nodeId:J.node.id,line:h.line(C.index)})}let dt=new RegExp(`(${Ie})\\s*\\.\\s*process\\s*\\(`,"g");for(;C=dt.exec(E);){let A=L.get(C[1]);if(A===void 0)continue;if(!A){S++;continue}let J=at(E,C.index+C[0].length-1)?.args.at(-1);if(!J)continue;let ae=oe(J.text,J.start);ae?.node&&b.push({queue:A.name,how:A.how+", "+ae.how,service:ae.service??j,nodeId:ae.node.id,line:h.line(C.index)})}let et=new RegExp("@Processor\\s*\\(","g");for(;C=et.exec(E);){let A=at(E,C.index+C[0].length-1);if(!A||!A.args[0])continue;let G=u(A.args[0].text,x,E),J=h.classes.find(_=>_.start>A.close&&_.start-A.close<400);if(!J)continue;if(!G){S++;continue}let ae=h.line(J.open),be=h.line(J.close),he=E.slice(J.open,J.close),Me=new Set(["process"]),ie=new RegExp(`@Process\\s*\\([^)]*\\)\\s*(?:(?:public|private|protected|async)\\s+)*(${Ie})\\s*\\(`,"g"),N;for(;N=ie.exec(he);)Me.add(N[1]);for(let _ of M){if(_.type==="moduleRoot"||_.startLine<ae||_.endLine>be)continue;let B=String(_.name).split(".").pop();Me.has(B)&&b.push({queue:G.name,how:G.how+", @Processor class method",service:j,nodeId:_.id,line:_.startLine})}}let $t=(A,G,J,ae,be)=>{let he;for(;he=ae.exec(G);){let ie=at(G,he.index+he[0].length-1)?.args[A.hi];if(!ie)continue;let N=oe(ie.text,J+ie.start);N?.node&&b.push({queue:A.name,how:A.how+", "+N.how+" registered through the worker base class",service:N.service??j,nodeId:N.node.id,line:be(J+he.index)})}};for(let A of h.classes){let G=w.get(A.name);if(!G||!I(A.name))continue;let J=E.slice(A.open,A.close);for(let[ae,be]of G.registrars)$t({name:G.name,how:G.how,hi:be},J,A.open,new RegExp(`this\\.${ae}\\s*\\(`,"g"),h.line)}for(let[A,G]of W)for(let[J,ae]of G.registrars)$t({name:G.name,how:G.how,hi:ae},E,0,new RegExp(`\\b${A.replace(/\$/g,"\\$")}\\s*\\.\\s*${J}\\s*\\(`,"g"),h.line)}let m=new Map;for(let h of b)m.has(h.queue)||m.set(h.queue,new Map),m.get(h.queue).set(h.nodeId,h);let d=[],k=new Set;for(let h of g.sort((x,j)=>x.queue<j.queue?-1:x.queue>j.queue?1:x.nodeId<j.nodeId?-1:x.nodeId>j.nodeId?1:x.line-j.line)){let x=m.get(h.queue);if(x)for(let j of[...x.values()].sort((E,M)=>E.nodeId<M.nodeId?-1:E.nodeId>M.nodeId?1:0)){if(j.nodeId===h.nodeId)continue;let E=[h.service,h.nodeId,j.service,j.nodeId,h.queue,h.line].join("\0");k.has(E)||(k.add(E),d.push({fromService:h.service,fromNodeId:h.nodeId,toService:j.service,toNodeId:j.nodeId,via:"queue",key:h.queue,queueName:h.queue,confidence:"inferred",reason:`queue "${h.queue}" (name from ${h.how}; consumer: ${j.how})`,line:h.line}))}}return{edges:d,stats:{producers:g.length,consumers:b.length,unresolvedProducers:$,unresolvedConsumers:S,files:v.length}}}function Br(e,t){let n=new Map;for(let[s,o]of e){let r=t.filter(c=>c.filePath===s),i=o.rawSocketTypeChecks??[];for(let c of i){let a=ce(c.startLine,r);a&&n.set(c.eventName,a.id)}}return n}import Ia from"node:fs";import ja from"node:path";function Hr(e){let t=["index.html","public/index.html","client/index.html","frontend/index.html","src/index.html"];for(let n of t){let s=ja.join(e,n);if(Ia.existsSync(s))return s}return null}import un from"node:fs";import dn from"node:path";var Ea=new Set(["node","tsx","ts-node","nodemon","bun","deno","ts-node-esm"]),Ca=new Set(["watch","run","start","dev"]),Ra=/\.[cm]?[jt]sx?$/,_a=["start","dev","serve","run"];function La(e){for(let t of String(e).split(/&&|\|\||;|\|/)){let n=t.trim().split(/\s+/).filter(Boolean).map(o=>o.replace(/^["']|["']$/g,"")),s=n.findIndex(o=>Ea.has(dn.basename(o).replace(/\.cmd$/,"")));if(!(s<0)){for(let o of n.slice(s+1))if(!(o.startsWith("-")||Ca.has(o)||o.includes("="))){if(Ra.test(o))return o;break}}}return null}var Pa=e=>String(e).replace(/^@[^/]+\//,"");function Dr(e){let t;try{t=JSON.parse(un.readFileSync(dn.join(e,"package.json"),"utf8"))}catch{return[]}let n=[],s=(o,r,i={})=>{if(typeof o!="string"||!o)return;let c=r==="script"?null:rn(e,o,t);c?n.push({file:c.file,kind:r,...i,mappedFrom:o,mappedBy:c.how}):n.push({file:dn.resolve(e,o),kind:r,...i})};if(typeof t.bin=="string")s(t.bin,"bin",{binName:Pa(t.name??dn.basename(e))});else if(t.bin&&typeof t.bin=="object")for(let[o,r]of Object.entries(t.bin))s(r,"bin",{binName:o});for(let o of _a){let r=t.scripts?.[o]&&La(t.scripts[o]);r&&s(r,"script")}return s(t.main,"main"),n}function zr(e){try{let t=un.openSync(e,"r"),n=Buffer.alloc(120),s=un.readSync(t,n,0,120,0);return un.closeSync(t),/^#!.*\b(node|tsx|ts-node|bun)\b/.test(n.toString("utf8",0,s).split(/\r?\n/)[0])}catch{return!1}}import pn from"node:fs";import lt from"node:path";var Ma=50,Oa=/^(tsup|tsdown|unbuild|build|rollup|vite|webpack|esbuild)[\w.-]*\.(mts|cts|mjs|cjs|js|ts)$/i,Wr=["",".js",".mjs",".cjs",".jsx",".ts",".tsx",".mts",".cts","/index.js","/index.ts","/index.mjs","/index.cjs","/index.tsx","/index.jsx"];function oo(e){if(typeof e=="string")return e;if(Array.isArray(e)){for(let t of e){let n=oo(t);if(n)return n}return null}if(e&&typeof e=="object")for(let t of["import","node","require","default"]){let n=oo(e[t]);if(n)return n}return null}function Ur(e,t){let n;try{n=JSON.parse(pn.readFileSync(lt.join(e,"package.json"),"utf8"))}catch{return null}let s=n.exports,o=typeof s=="string"||Array.isArray(s)?s:s&&typeof s=="object"?s["."]??(Object.keys(s).some(l=>l.startsWith("."))?null:s):null,r=oo(o)??(typeof n.module=="string"?n.module:null)??(typeof n.main=="string"?n.main:null);if(!r)return null;let i=new Set(t.map(l=>lt.resolve(l))),c=lt.resolve(e,r);for(let l of Wr)if(i.has(c+l))return t.find(f=>lt.resolve(f)===c+l);let a=[];try{a=pn.readdirSync(e).filter(l=>Oa.test(l)).sort()}catch{}for(let l of a){let f;try{f=pn.readFileSync(lt.join(e,l),"utf8")}catch{continue}let y=/\bentry(?:Points)?\s*:\s*[\[{]?\s*(?:["'\w-]+\s*:\s*)?["'`]([^"'`]+)["'`]/.exec(f);if(!y)continue;let u=lt.resolve(e,y[1]);for(let v of Wr)if(i.has(u+v))return t.find(p=>lt.resolve(p)===u+v)}return null}function qr(e,t,n,s,o=null){let r=new Map;for(let w of n){let I=r.get(w.filePath);I||r.set(w.filePath,I=[]),I.push(w)}let i=new Map,c=(w,I)=>{I&&(!i.has(I.id)||w<i.get(I.id))&&i.set(I.id,w)},a=new Map,l=(w,I)=>{let g=a.get(w);if(!g){g=new Map;let b="";try{b=pn.readFileSync(w,"utf8")}catch{}for(let $ of b.matchAll(/^[ \t]*(?:export\s+)?const\s+([\w$]+)\s*(?::[^=\n]+)?=\s*([\w$]+)\s*(?:as\s+[^;\n]+)?;?[ \t]*$/gm))$[1]!==$[2]&&g.set($[1],$[2]);a.set(w,g)}return g.get(I)??null},f=(w,I)=>(r.get(w)??[]).find(g=>(g.type==="function"||g.type==="arrowFunction")&&g.name===I),y=(w,I)=>(r.get(w)??[]).filter(g=>g.type==="classMethod"&&g.className===I&&g.name!=="constructor"&&!/^[_#]/.test(g.name)),u=new Set;function v(w,I,g,b=0){let $=f(w,g);if($){c(I,$);return}let S=y(w,g);for(let j of S)c(`${I}.${j.name}`,j);if(S.length||!o)return;let m=o.resolveName(w,g);if(m){c(I,m);return}let d=o.bindingFor(w,g),k=d&&b<3?o.resolveImport(w,d.source,d.kind,d.imported):null;if(k?.file&&k.local&&k.local!=="default"&&l(k.file,k.local)){v(k.file,I,k.local,b+1);return}let h=o.classForImport(w,g);if(h?.className)for(let j of y(h.file,h.className))c(`${I}.${j.name}`,j);if(h?.className)return;let x=l(w,g);x&&b<3&&v(w,I,x,b+1)}function p(w,I,g){let b=w+"|"+(g?[...g.keys()].sort().join(","):"*");if(u.has(b)||I>3)return;u.add(b);let $=t.get(w)?.exportBindings;if(!$)return;let S=m=>!g||g.has(m);for(let[m,d]of Object.entries($.named??{}))S(m)&&v(w,g?.get(m)??m,d);$.default&&S("default")&&$.default!=="<anon>"&&v(w,g?.get("default")??$.default,$.default);for(let m of $.reexports??[]){if(!S(m.exported))continue;let d=ve(m.source,w,s);d&&p(d,I+1,new Map([[m.imported,g?.get(m.exported)??m.exported]]))}for(let m of $.stars??[]){let d=ve(m,w,s);d&&(g?p(d,I+1,g):p(d,I+1,null))}}return p(e,0,null),[...i].map(([w,I])=>({name:I,nodeId:w})).sort((w,I)=>w.name<I.name?-1:w.name>I.name?1:w.nodeId<I.nodeId?-1:1).slice(0,Ma)}import mn from"node:fs";import Rt from"node:path";var so=null,ro=null,Gr=()=>so?Rt.join(so,".canopy","last-stage.txt"):null,Yr=e=>{so=e?Rt.resolve(e):null},hn=()=>ro;function Ta(){let e=process.memoryUsage(),t=n=>Math.round(n/1048576);return{rssMB:t(e.rss),heapUsedMB:t(e.heapUsed),externalMB:t(e.external),arrayBuffersMB:t(e.arrayBuffers)}}var Aa=()=>process.env.CANOPY_DEBUG_MEM==="1"||process.env.CANOPY_DEBUG_MEM==="true";function Je(e){ro=e;let t=Gr();if(t)try{mn.mkdirSync(Rt.dirname(t),{recursive:!0}),mn.writeFileSync(t,e)}catch{}if(Aa()){let n=Ta();process.stderr.write(`[mem] ${e}: rss ${n.rssMB} MB, heapUsed ${n.heapUsedMB} MB, external ${n.externalMB} MB, arrayBuffers ${n.arrayBuffersMB} MB
|
|
16
|
-
`)}}function
|
|
14
|
+
`:" ",n++;t+=" ",n+=2}else(o==='"'||o==="'"||o==="`")&&(s=o),t+=o,n++}return t}function no(e,t){let n={"(":")","[":"]","{":"}"},s=[],o=null;for(let r=t;r<e.length;r++){let i=e[r];if(o){i==="\\"?r++:i===o&&(o=null);continue}if(i==='"'||i==="'"||i==="`"){o=i;continue}if(n[i])s.push(n[i]);else if(i===")"||i==="]"||i==="}"){if(s.pop()!==i)return-1;if(!s.length)return r}}return-1}function at(e,t){let n=no(e,t);if(n<0)return null;let s=[],o=0,r=null,i=t+1;for(let c=t+1;c<n;c++){let a=e[c];if(r){a==="\\"?c++:a===r&&(r=null);continue}if(a==='"'||a==="'"||a==="`"){r=a;continue}a==="("||a==="["||a==="{"?o++:a===")"||a==="]"||a==="}"?o--:a===","&&o===0&&(s.push({text:e.slice(i,c),start:i}),i=c+1)}return e.slice(i,n).trim()&&s.push({text:e.slice(i,n),start:i}),{args:s,close:n}}function ja(e){let t=[0];for(let n=0;n<e.length;n++)e[n]===`
|
|
15
|
+
`&&t.push(n+1);return n=>{let s=0,o=t.length-1;for(;s<o;){let r=s+o+1>>1;t[r]<=n?s=r:o=r-1}return s+1}}var Ea=e=>{let t=e.trim(),n=/^(['"])([^'"\\\n]*)\1$/.exec(t);return n?n[2]:(n=/^`([^`$\\]*)`$/.exec(t),n?n[1]:null)},Br=e=>new RegExp(`(?:const|let|var|readonly|static)\\s+${e.replace(/\$/g,"\\$")}\\s*(?::[^=;{]+)?=\\s*(['"\`])([^'"\`$\\\\\\n]*)\\1`);function to(e,t){let n=t.exec(e);if(!n)return null;let s=e.indexOf("{",n.index+n[0].length-1);if(s<0)return null;let o=no(e,s);return o<0?null:e.slice(s+1,o)}function Hr(e,t,n){let s=t.replace(/\$/g,"\\$"),o=n.replace(/\$/g,"\\$"),r=to(e,new RegExp(`\\benum\\s+${s}\\s*\\{`));if(r){let i=new RegExp(`(?:^|[,{\\s])${o}\\s*=\\s*(['"\`])([^'"\`$\\\\\\n]*)\\1`).exec(r);return i?i[2]:null}if(r=to(e,new RegExp(`(?:const|let|var)\\s+${s}\\s*(?::[^=]+)?=\\s*\\{`))??to(e,new RegExp(`\\bclass\\s+${s}\\b[^{]*\\{`)),r){let i=new RegExp(`(?:^|[,{\\s])(?:static\\s+(?:readonly\\s+)?)?${o}\\s*[:=]\\s*(['"\`])([^'"\`$\\\\\\n]*)\\1`).exec(r);return i?i[2]:null}return null}function Ca(e){let t=new Map,n=/import\s+(?:type\s+)?([^'";]*?)\s+from\s*['"]([^'"]+)['"]/g,s;for(;s=n.exec(e);){let o=s[1].trim(),r=s[2],i=/\{([^}]*)\}/.exec(o);if(i)for(let l of i[1].split(",")){let f=l.trim().replace(/^type\s+/,"");if(!f)continue;let y=/^(\S+)\s+as\s+(\S+)$/.exec(f);y?t.set(y[2],{spec:r,imported:y[1]}):t.set(f,{spec:r,imported:f})}let c=/\*\s*as\s+(\S+)/.exec(o);c&&t.set(c[1],{spec:r,imported:"*"});let a=/^([A-Za-z_$][\w$]*)\s*(?:,|$)/.exec(o);a&&!o.startsWith("{")&&!o.startsWith("*")&&t.set(a[1],{spec:r,imported:"default"})}return t}function Dr(e){let t=[],n,s=/export\s*\*\s*from\s*['"]([^'"]+)['"]/g;for(;n=s.exec(e);)t.push({spec:n[1],all:!0});let o=/export\s*\{([^}]*)\}\s*from\s*['"]([^'"]+)['"]/g;for(;n=o.exec(e);){let r=new Map;for(let i of n[1].split(",")){let c=i.trim();if(!c)continue;let a=/^(\S+)\s+as\s+(\S+)$/.exec(c);a?r.set(a[2],a[1]):r.set(c,c)}t.push({spec:n[2],names:r})}return t}function zr(e,t,{readFile:n=s=>Ar.statSync(s).size>Ia?null:Ar.readFileSync(s,"utf8")}={}){let s=[],o=new Map,r=new Map;for(let h of e){let x=t.get(h.name);if(x){for(let j of x.files??[])s.push(j),r.has(j)||r.set(j,h.name);for(let j of x.nodes){let E=h.name+"\0"+j.filePath;o.has(E)||o.set(E,[]),o.get(E).push(j)}}}let i=new Map,c=h=>{if(i.has(h))return i.get(h);let x=null;try{x=Fr(n(h)??"")}catch{x=null}return i.size>400&&i.clear(),i.set(h,x),x},a=new Map,l=(h,x)=>{let j=a.get(h);return j||(j=Ca(x),a.set(h,j)),j};function f(h,x,j){let E=c(h);if(E==null||j>3)return null;let M=Br(x).exec(E);if(M)return{value:M[2],how:"constant"};for(let T of Dr(E)){let L=T.all?x:T.names?.get(x);if(!L)continue;let O=ve(T.spec,h,s);if(O){let C=f(O,L,j+1);if(C)return C}}return null}function y(h,x,j,E){let M=c(h);if(M==null||E>3)return null;let T=Hr(M,x,j);if(T!=null)return{value:T,how:"enum or object member"};for(let L of Dr(M)){let O=L.all?x:L.names?.get(x);if(!O)continue;let C=ve(L.spec,h,s);if(C){let z=y(C,O,j,E+1);if(z)return z}}return null}function u(h,x,j){let E=String(h).trim().replace(/\s+as\s+[\w.<>[\]| ]+$/,"").replace(/!$/,"").trim(),M=/^\{\s*name\s*:\s*([\s\S]+?)\s*[,}]?\s*\}?$/.exec(E);M&&!/^['"`]/.test(E)&&(E=M[1].trim());let T=Ea(E);if(T!==null)return T?{name:T,how:"literal"}:null;let L=new RegExp(`^(${Ie})$`).exec(E);if(L){let O=Br(L[1]).exec(j);if(O)return{name:O[2],how:"constant in the same file"};let C=l(x,j).get(L[1]);if(C&&C.imported!=="*"){let z=ve(C.spec,x,s);if(z){let K=f(z,C.imported==="default"?L[1]:C.imported,0);if(K)return{name:K.value,how:"imported constant"}}}return null}if(L=new RegExp(`^(${Ie})\\.(${Ie})$`).exec(E),L){let O=Hr(j,L[1],L[2]);if(O!=null)return{name:O,how:"enum or object member in the same file"};let C=l(x,j).get(L[1]);if(C){let z=ve(C.spec,x,s);if(z){let K=C.imported==="*"?f(z,L[2],0):y(z,C.imported==="default"?L[1]:C.imported,L[2],0);if(K)return{name:K.value,how:C.imported==="*"?"imported constant":"imported enum or object member"}}}}return null}let v=[];for(let h of s){let x=r.get(h);if(!x)continue;let j=null;try{j=n(h)}catch{j=null}if(j==null||!Na.test(j))continue;let E=Fr(j);v.push({file:h,service:x,t:E,line:ja(E)})}let{producerClasses:p,workerClasses:w,unique:I}=Tr({files:v,resolveName:u,callArgs:at,matchClose:no,IDENT:Ie}),g=[],b=[],$=0,S=0;for(let h of v){let{file:x,service:j,t:E}=h,M=o.get(j+"\0"+x)??[],T=A=>ce(h.line(A),M),L=new Map,O=(A,G)=>{(!L.has(A)||L.get(A)===null&&G)&&L.set(A,G)},C,z=new RegExp("new\\s+(?:Queue|Bull|BullQueue)\\s*(?:<[^>]*>)?\\s*\\(","g");for(;C=z.exec(E);){let A=E.slice(Math.max(0,C.index-160),C.index),G=new RegExp(`(${Ie})\\s*(?::[^=;]+)?=\\s*$`).exec(A),J=at(E,C.index+C[0].length-1);!G||!J||!J.args[0]||O(G[1],u(J.args[0].text,x,E))}let K=new RegExp("@InjectQueue\\s*\\(","g");for(;C=K.exec(E);){let A=at(E,C.index+C[0].length-1);if(!A)continue;let G=E.slice(A.close+1,A.close+200),J=new RegExp(`^\\s*(?:(?:private|public|protected|readonly)\\s+)*(${Ie})`).exec(G);J&&O(J[1],A.args[0]?u(A.args[0].text,x,E):null)}let R=new RegExp(`(?:private|public|protected)\\s+(?:readonly\\s+)?(${Ie})\\s*:\\s*(${Ie})`,"g"),W=new Map;for(;C=R.exec(E);)p.has(C[2])&&I(C[2])&&O(C[1],p.get(C[2])),w.has(C[2])&&I(C[2])&&W.set(C[1],w.get(C[2]));let Z=new RegExp(`(${Ie})\\s*\\.\\s*(add|addBulk)\\s*\\(`,"g");for(;C=Z.exec(E);){let A=L.get(C[1]);if(A===void 0)continue;let G=T(C.index);if(!A){$++;continue}G&&g.push({queue:A.name,how:A.how,service:j,nodeId:G.id,line:h.line(C.index)})}let oe=(A,G)=>{let J=A.trim();if(/^(?:async\s+)?(?:function\b|\([^)]*\)\s*(?::[^=]+)?=>|[\w$]+\s*=>)/.test(J))return{node:T(G+A.indexOf(J)),how:"inline handler"};let ae=new RegExp(`^this\\.(${Ie})(?:\\.bind\\(this\\)|\\(\\s*\\))?$`).exec(J),be=ae?ae[1]:new RegExp(`^(${Ie})$`).exec(J)?.[1];if(!be)return null;let he=M.filter(ie=>ie.type!=="moduleRoot"&&(ie.name===be||String(ie.name).endsWith("."+be)));if(he.length===1)return{node:he[0],how:"named handler"};if(ae&&he.length>1){let ie=h.classes.filter(N=>N.open<=G&&G<=N.close).sort((N,_)=>_.open-N.open)[0];if(ie){let N=he.filter(_=>_.startLine>=h.line(ie.open)&&_.endLine<=h.line(ie.close));if(N.length===1)return{node:N[0],how:"named handler"}}}let Me=l(x,E).get(be);if(Me){let ie=ve(Me.spec,x,s);if(ie){let N=(o.get(r.get(ie)+"\0"+ie)??[]).filter(_=>_.type!=="moduleRoot"&&_.name===(Me.imported==="default"?be:Me.imported));if(N.length===1)return{node:N[0],how:"imported handler",service:r.get(ie)}}}return null},re=new RegExp("new\\s+Worker\\s*(?:<[^>]*>)?\\s*\\(","g");for(;C=re.exec(E);){let A=at(E,C.index+C[0].length-1);if(!A||A.args.length<2)continue;let G=u(A.args[0].text,x,E);if(!G){S++;continue}let J=oe(A.args[1].text,A.args[1].start);J?.node&&b.push({queue:G.name,how:G.how+", "+J.how,service:J.service??j,nodeId:J.node.id,line:h.line(C.index)})}let dt=new RegExp(`(${Ie})\\s*\\.\\s*process\\s*\\(`,"g");for(;C=dt.exec(E);){let A=L.get(C[1]);if(A===void 0)continue;if(!A){S++;continue}let J=at(E,C.index+C[0].length-1)?.args.at(-1);if(!J)continue;let ae=oe(J.text,J.start);ae?.node&&b.push({queue:A.name,how:A.how+", "+ae.how,service:ae.service??j,nodeId:ae.node.id,line:h.line(C.index)})}let et=new RegExp("@Processor\\s*\\(","g");for(;C=et.exec(E);){let A=at(E,C.index+C[0].length-1);if(!A||!A.args[0])continue;let G=u(A.args[0].text,x,E),J=h.classes.find(_=>_.start>A.close&&_.start-A.close<400);if(!J)continue;if(!G){S++;continue}let ae=h.line(J.open),be=h.line(J.close),he=E.slice(J.open,J.close),Me=new Set(["process"]),ie=new RegExp(`@Process\\s*\\([^)]*\\)\\s*(?:(?:public|private|protected|async)\\s+)*(${Ie})\\s*\\(`,"g"),N;for(;N=ie.exec(he);)Me.add(N[1]);for(let _ of M){if(_.type==="moduleRoot"||_.startLine<ae||_.endLine>be)continue;let B=String(_.name).split(".").pop();Me.has(B)&&b.push({queue:G.name,how:G.how+", @Processor class method",service:j,nodeId:_.id,line:_.startLine})}}let $t=(A,G,J,ae,be)=>{let he;for(;he=ae.exec(G);){let ie=at(G,he.index+he[0].length-1)?.args[A.hi];if(!ie)continue;let N=oe(ie.text,J+ie.start);N?.node&&b.push({queue:A.name,how:A.how+", "+N.how+" registered through the worker base class",service:N.service??j,nodeId:N.node.id,line:be(J+he.index)})}};for(let A of h.classes){let G=w.get(A.name);if(!G||!I(A.name))continue;let J=E.slice(A.open,A.close);for(let[ae,be]of G.registrars)$t({name:G.name,how:G.how,hi:be},J,A.open,new RegExp(`this\\.${ae}\\s*\\(`,"g"),h.line)}for(let[A,G]of W)for(let[J,ae]of G.registrars)$t({name:G.name,how:G.how,hi:ae},E,0,new RegExp(`\\b${A.replace(/\$/g,"\\$")}\\s*\\.\\s*${J}\\s*\\(`,"g"),h.line)}let m=new Map;for(let h of b)m.has(h.queue)||m.set(h.queue,new Map),m.get(h.queue).set(h.nodeId,h);let d=[],k=new Set;for(let h of g.sort((x,j)=>x.queue<j.queue?-1:x.queue>j.queue?1:x.nodeId<j.nodeId?-1:x.nodeId>j.nodeId?1:x.line-j.line)){let x=m.get(h.queue);if(x)for(let j of[...x.values()].sort((E,M)=>E.nodeId<M.nodeId?-1:E.nodeId>M.nodeId?1:0)){if(j.nodeId===h.nodeId)continue;let E=[h.service,h.nodeId,j.service,j.nodeId,h.queue,h.line].join("\0");k.has(E)||(k.add(E),d.push({fromService:h.service,fromNodeId:h.nodeId,toService:j.service,toNodeId:j.nodeId,via:"queue",key:h.queue,queueName:h.queue,confidence:"inferred",reason:`queue "${h.queue}" (name from ${h.how}; consumer: ${j.how})`,line:h.line}))}}return{edges:d,stats:{producers:g.length,consumers:b.length,unresolvedProducers:$,unresolvedConsumers:S,files:v.length}}}function Wr(e,t){let n=new Map;for(let[s,o]of e){let r=t.filter(c=>c.filePath===s),i=o.rawSocketTypeChecks??[];for(let c of i){let a=ce(c.startLine,r);a&&n.set(c.eventName,a.id)}}return n}import Ra from"node:fs";import _a from"node:path";function Ur(e){let t=["index.html","public/index.html","client/index.html","frontend/index.html","src/index.html"];for(let n of t){let s=_a.join(e,n);if(Ra.existsSync(s))return s}return null}import dn from"node:fs";import pn from"node:path";var La=new Set(["node","tsx","ts-node","nodemon","bun","deno","ts-node-esm"]),Pa=new Set(["watch","run","start","dev"]),Ma=/\.[cm]?[jt]sx?$/,Oa=["start","dev","serve","run"];function Ta(e){for(let t of String(e).split(/&&|\|\||;|\|/)){let n=t.trim().split(/\s+/).filter(Boolean).map(o=>o.replace(/^["']|["']$/g,"")),s=n.findIndex(o=>La.has(pn.basename(o).replace(/\.cmd$/,"")));if(!(s<0)){for(let o of n.slice(s+1))if(!(o.startsWith("-")||Pa.has(o)||o.includes("="))){if(Ma.test(o))return o;break}}}return null}var Aa=e=>String(e).replace(/^@[^/]+\//,"");function qr(e){let t;try{t=JSON.parse(dn.readFileSync(pn.join(e,"package.json"),"utf8"))}catch{return[]}let n=[],s=(o,r,i={})=>{if(typeof o!="string"||!o)return;let c=r==="script"?null:cn(e,o,t);c?n.push({file:c.file,kind:r,...i,mappedFrom:o,mappedBy:c.how}):n.push({file:pn.resolve(e,o),kind:r,...i})};if(typeof t.bin=="string")s(t.bin,"bin",{binName:Aa(t.name??pn.basename(e))});else if(t.bin&&typeof t.bin=="object")for(let[o,r]of Object.entries(t.bin))s(r,"bin",{binName:o});for(let o of Oa){let r=t.scripts?.[o]&&Ta(t.scripts[o]);r&&s(r,"script")}return s(t.main,"main"),n}function Gr(e){try{let t=dn.openSync(e,"r"),n=Buffer.alloc(120),s=dn.readSync(t,n,0,120,0);return dn.closeSync(t),/^#!.*\b(node|tsx|ts-node|bun)\b/.test(n.toString("utf8",0,s).split(/\r?\n/)[0])}catch{return!1}}import mn from"node:fs";import lt from"node:path";var Fa=50,Ba=/^(tsup|tsdown|unbuild|build|rollup|vite|webpack|esbuild)[\w.-]*\.(mts|cts|mjs|cjs|js|ts)$/i,Yr=["",".js",".mjs",".cjs",".jsx",".ts",".tsx",".mts",".cts","/index.js","/index.ts","/index.mjs","/index.cjs","/index.tsx","/index.jsx"];function oo(e){if(typeof e=="string")return e;if(Array.isArray(e)){for(let t of e){let n=oo(t);if(n)return n}return null}if(e&&typeof e=="object")for(let t of["import","node","require","default"]){let n=oo(e[t]);if(n)return n}return null}function Jr(e,t){let n;try{n=JSON.parse(mn.readFileSync(lt.join(e,"package.json"),"utf8"))}catch{return null}let s=n.exports,o=typeof s=="string"||Array.isArray(s)?s:s&&typeof s=="object"?s["."]??(Object.keys(s).some(l=>l.startsWith("."))?null:s):null,r=oo(o)??(typeof n.module=="string"?n.module:null)??(typeof n.main=="string"?n.main:null);if(!r)return null;let i=new Set(t.map(l=>lt.resolve(l))),c=lt.resolve(e,r);for(let l of Yr)if(i.has(c+l))return t.find(f=>lt.resolve(f)===c+l);let a=[];try{a=mn.readdirSync(e).filter(l=>Ba.test(l)).sort()}catch{}for(let l of a){let f;try{f=mn.readFileSync(lt.join(e,l),"utf8")}catch{continue}let y=/\bentry(?:Points)?\s*:\s*[\[{]?\s*(?:["'\w-]+\s*:\s*)?["'`]([^"'`]+)["'`]/.exec(f);if(!y)continue;let u=lt.resolve(e,y[1]);for(let v of Yr)if(i.has(u+v))return t.find(p=>lt.resolve(p)===u+v)}return null}function Vr(e,t,n,s,o=null){let r=new Map;for(let w of n){let I=r.get(w.filePath);I||r.set(w.filePath,I=[]),I.push(w)}let i=new Map,c=(w,I)=>{I&&(!i.has(I.id)||w<i.get(I.id))&&i.set(I.id,w)},a=new Map,l=(w,I)=>{let g=a.get(w);if(!g){g=new Map;let b="";try{b=mn.readFileSync(w,"utf8")}catch{}for(let $ of b.matchAll(/^[ \t]*(?:export\s+)?const\s+([\w$]+)\s*(?::[^=\n]+)?=\s*([\w$]+)\s*(?:as\s+[^;\n]+)?;?[ \t]*$/gm))$[1]!==$[2]&&g.set($[1],$[2]);a.set(w,g)}return g.get(I)??null},f=(w,I)=>(r.get(w)??[]).find(g=>(g.type==="function"||g.type==="arrowFunction")&&g.name===I),y=(w,I)=>(r.get(w)??[]).filter(g=>g.type==="classMethod"&&g.className===I&&g.name!=="constructor"&&!/^[_#]/.test(g.name)),u=new Set;function v(w,I,g,b=0){let $=f(w,g);if($){c(I,$);return}let S=y(w,g);for(let j of S)c(`${I}.${j.name}`,j);if(S.length||!o)return;let m=o.resolveName(w,g);if(m){c(I,m);return}let d=o.bindingFor(w,g),k=d&&b<3?o.resolveImport(w,d.source,d.kind,d.imported):null;if(k?.file&&k.local&&k.local!=="default"&&l(k.file,k.local)){v(k.file,I,k.local,b+1);return}let h=o.classForImport(w,g);if(h?.className)for(let j of y(h.file,h.className))c(`${I}.${j.name}`,j);if(h?.className)return;let x=l(w,g);x&&b<3&&v(w,I,x,b+1)}function p(w,I,g){let b=w+"|"+(g?[...g.keys()].sort().join(","):"*");if(u.has(b)||I>3)return;u.add(b);let $=t.get(w)?.exportBindings;if(!$)return;let S=m=>!g||g.has(m);for(let[m,d]of Object.entries($.named??{}))S(m)&&v(w,g?.get(m)??m,d);$.default&&S("default")&&$.default!=="<anon>"&&v(w,g?.get("default")??$.default,$.default);for(let m of $.reexports??[]){if(!S(m.exported))continue;let d=ve(m.source,w,s);d&&p(d,I+1,new Map([[m.imported,g?.get(m.exported)??m.exported]]))}for(let m of $.stars??[]){let d=ve(m,w,s);d&&(g?p(d,I+1,g):p(d,I+1,null))}}return p(e,0,null),[...i].map(([w,I])=>({name:I,nodeId:w})).sort((w,I)=>w.name<I.name?-1:w.name>I.name?1:w.nodeId<I.nodeId?-1:1).slice(0,Fa)}import hn from"node:fs";import Rt from"node:path";var so=null,ro=null,Kr=()=>so?Rt.join(so,".canopy","last-stage.txt"):null,Xr=e=>{so=e?Rt.resolve(e):null},gn=()=>ro;function Ha(){let e=process.memoryUsage(),t=n=>Math.round(n/1048576);return{rssMB:t(e.rss),heapUsedMB:t(e.heapUsed),externalMB:t(e.external),arrayBuffersMB:t(e.arrayBuffers)}}var Da=()=>process.env.CANOPY_DEBUG_MEM==="1"||process.env.CANOPY_DEBUG_MEM==="true";function Je(e){ro=e;let t=Kr();if(t)try{hn.mkdirSync(Rt.dirname(t),{recursive:!0}),hn.writeFileSync(t,e)}catch{}if(Da()){let n=Ha();process.stderr.write(`[mem] ${e}: rss ${n.rssMB} MB, heapUsed ${n.heapUsedMB} MB, external ${n.externalMB} MB, arrayBuffers ${n.arrayBuffersMB} MB
|
|
16
|
+
`)}}function Zr(){ro=null;let e=Kr();if(e)try{hn.rmSync(e,{force:!0})}catch{}}function Qr(e){try{return hn.readFileSync(Rt.join(Rt.resolve(e),".canopy","last-stage.txt"),"utf8").trim().slice(0,120)||null}catch{return null}}import ti from"node:path";import{fileURLToPath as za}from"node:url";import{Parser as ei,Language as Wa}from"web-tree-sitter";var Cd=ti.dirname(za(globalThis.__canopyUrl("src/stage2_parse/initHtmlParser.js")));async function ni(){await ei.init();let e=new ei,t=ti.join(Ft("tree-sitter-html"),"tree-sitter-html.wasm"),n=await Wa.load(t);return e.setLanguage(n),{parser:e,language:n}}function oi(e,t){let s=vo(t,"htmlScriptRoot.scm").matches(e.rootNode);for(let o of s){let r=o.captures.find(c=>c.name==="attr_name"),i=o.captures.find(c=>c.name==="script_src");if(r&&r.node.text==="src"&&i)return i.node.text}return null}function si(e,t,n){let s=[];e.forEach((a,l)=>{a.steps.forEach(f=>{if(!f.hasOwnSubTrace)return;let y=e.findIndex((u,v)=>v!==l&&u.steps[0]?.nodeId===f.nodeId);y!==-1&&s.push({fromWorkflowIndex:l,toWorkflowIndex:y,atNodeId:f.nodeId})})});let o=new Map;for(let a of t)o.set(a.id,a.serviceName??null);let r=new Map;function i(a,l,f,y){if(!a||!l||a===l)return;let u=`${a} -> ${l} -> ${f}`;r.has(u)?r.get(u).count+=1:r.set(u,{fromService:a,toService:l,viaMatchType:f,count:1});let v=r.get(u);y==="exact"?v.exact=(v.exact??0)+1:y==="inferred"?v.inferred=(v.inferred??0)+1:y==="resolved"&&(v.resolved=(v.resolved??0)+1)}for(let a of n){if(!a.resolved||!a.fromNodeId||!a.targetNodeId)continue;let l=o.get(a.fromNodeId)??null,f=o.get(a.targetNodeId)??null;i(l,f,a.matchType,a.confidence)}let c=Array.from(r.values());return{workflowLinks:s,serviceLinks:c}}var Ga=Q.dirname(Ua(globalThis.__canopyUrl("src/index.js"))),ri=24*1e3*1e3;async function io(e,t={}){e=Q.resolve(e),console.log(`
|
|
17
17
|
Analyzing: ${e}
|
|
18
|
-
`);let n=Date.now(),s=()=>{let N=Math.round((Date.now()-n)/1e3);return N>=60?`${Math.floor(N/60)} min ${N%60} s`:`${N} s`},o=N=>{try{t.onProgress?.(N)}catch{}};Je("finding source files"),console.log("Stage 1: finding source files...");let r=t.discovered??jt(e),i=r.files;
|
|
19
|
-
Stage 1b: partitioning files by service...`);let f=
|
|
20
|
-
Stage 2: parsing (all files, once \u2014 see note above)...`),Je("reading files");let p=await xo(i,c,a,{onProgress:t.onProgress,grammars:l,noCache:!!t.noCache,say:o});function w(N){let _=new Set;for(let B of N){let P=p.get(B);if(P)for(let H of P.imports){let le=ve(H.source,B,i);le&&v.includes(le)&&_.add(le)}}return[..._]}let I=new Map;for(let N of f){let _=u.get(N.name),B=w(_);I.set(N.name,[..._,...B]),console.log(` ${N.name}: ${_.length} own + ${B.length} shared file(s) pulled in by real imports = ${_.length+B.length} total scope`)}let g=f.filter(N=>!I.get(N.name)?.length);g.length&&(console.log(` excluding ${g.length} service(s) with 0 files: ${g.map(N=>N.name).join(", ")}`),f=f.filter(N=>I.get(N.name)?.length));let b=null,$=
|
|
21
|
-
--- Service: ${N.name} (${N.kind}) \u2014 ${_.length} files in scope ---`),!_.length){console.log(" 0 files \u2014 nothing to trace for this service."),S.set(N.name,{nodes:[],resolvedEdges:[],workflows:[],routeIndex:new Map,eventIndex:new Map,rawEventIndex:new Map,parseResults:new Map});continue}let B=wo(new Map(_.map(F=>[F,p.get(F)]))),P=
|
|
22
|
-
--- Stage 5 (stitch): cross-service edge resolution ---`),Je("linking services together"),o(`linking services together (${s()})`);let h=[],x=0,j=0;for(let N of f){let _=S.get(N.name);if(!_||!_.resolvedEdges.length)continue;let B=_.resolvedEdges.filter(P=>!P.resolved&&(P.type==="apiCall"||P.type==="socketEmit"||P.type==="rawSocketSend"));for(let P of B){let H=null,le=null;for(let D of f){if(D.name===N.name)continue;let
|
|
23
|
-
`);return{available:!0,filePath:N,startLine:H,endLine:le,text:D}}catch(P){return{available:!1,reason:`source unavailable: ${P.code==="ENOENT"?"file not found (deleted or moved)":P.message}`}}}let L=/^(addEventListener|removeEventListener|on|once|postMessage|onmessage|subscribe)$/i,O=new Set(["call","methodCall","callSite"]),C=new WeakMap;function z(N,_){let B=C.get(N);if(!B||B.n!==N.length){B={n:N.length,by:new Map};for(let P of N){let H=B.by.get(P.fromNodeId);H||B.by.set(P.fromNodeId,H=[]),H.push(P)}C.set(N,B)}return B.by.get(_)??[]}function K(N,_,B,P,H=null){let le=D=>!!(H&&!P&&!D.deferred&&D.resolved&&D.targetNodeId&&O.has(D.type)&&D.targetNodeId!==N&&H.inWorkflow.has(D.targetNodeId)&&!H.children.has(D.targetNodeId));return z(_,N).filter(D=>D.type!=="apiCall").filter(D=>D.resolved&&D.targetNodeId?le(D):!!D.deferred===P).map(D=>{let
|
|
24
|
-
Done: ${
|
|
25
|
-
`),
|
|
26
|
-
`+
|
|
27
|
-
workflows.json omitted (${A===null?"over 500":(A.length/1e6).toFixed(1)} MB plain); workflows.js written with shared sub-structures (${(N.length/1e6).toFixed(1)} MB)`)}else we.writeFileSync(
|
|
28
|
-
Saved to output/workflows.json`),we.writeFileSync(
|
|
29
|
-
Note on output shape: workflows.json entries gained two additive fields (serviceId, servicesTouched) \u2014 every field the old shape had (steps, name, trigger, occurrences, ...) is unchanged, so the existing viewer keeps working without modification.`);let ie=new Map;for(let N of f){let _=S.get(N.name);if(!_)continue;let B=re.clone(_.nodes.map(H=>({id:H.id,name:H.name,type:H.type,filePath:H.filePath,bodyHash:H.bodyHash??null,startLine:H.startLine===0?0:H.startLine,endLine:H.endLine===Number.MAX_SAFE_INTEGER?null:H.endLine,serviceName:H.serviceName,isEntryPoint:!!H.isEntryPoint}))),P=
|
|
30
|
-
`)[0]+" (the map is fine; search falls back to the traced nodes)")}return{status:"new-version",version:I,ms:Date.now()-o,coverage:y.coverage}}finally{Ve.rmSync(f,{recursive:!0,force:!0})}}function
|
|
31
|
-
`+
|
|
18
|
+
`);let n=Date.now(),s=()=>{let N=Math.round((Date.now()-n)/1e3);return N>=60?`${Math.floor(N/60)} min ${N%60} s`:`${N} s`},o=N=>{try{t.onProgress?.(N)}catch{}};Je("finding source files"),console.log("Stage 1: finding source files...");let r=t.discovered??jt(e),i=r.files;As(Hs(e,i)),console.log(` found ${i.length} files`);let{parser:c,language:a,grammars:l}=await yo();await go({grammars:l},i),console.log(`
|
|
19
|
+
Stage 1b: partitioning files by service...`);let f=xs(e,i),y=ks(f,i,e);f=y.services,y.added&&console.log(` note: ${y.added.reason} (service "${y.added.name}")`),console.log(` detected ${f.length} services: ${f.map(N=>`${N.name} (${N.kind})`).join(", ")}`);let u=new Map(f.map(N=>[N.name,[]])),v=[];for(let N of i){let _=rt(N,f);_?u.get(_).push(N):v.push(N)}console.log(" file partition:");for(let N of f)console.log(` ${N.name}: ${u.get(N.name).length} files`);console.log(` unassigned (shared/root-level): ${v.length} files`),v.length&&(console.log(" rule: these don't get their own Stage 5-7 run (no service of their own to have routes/listeners for) \u2014"),console.log(" each one is added to a service's parse scope ONLY if a file already in that"),console.log(" service actually imports it, so intra-service calls into shared code still resolve.")),console.log(`
|
|
20
|
+
Stage 2: parsing (all files, once \u2014 see note above)...`),Je("reading files");let p=await xo(i,c,a,{onProgress:t.onProgress,grammars:l,noCache:!!t.noCache,say:o});function w(N){let _=new Set;for(let B of N){let P=p.get(B);if(P)for(let H of P.imports){let le=ve(H.source,B,i);le&&v.includes(le)&&_.add(le)}}return[..._]}let I=new Map;for(let N of f){let _=u.get(N.name),B=w(_);I.set(N.name,[..._,...B]),console.log(` ${N.name}: ${_.length} own + ${B.length} shared file(s) pulled in by real imports = ${_.length+B.length} total scope`)}let g=f.filter(N=>!I.get(N.name)?.length);g.length&&(console.log(` excluding ${g.length} service(s) with 0 files: ${g.map(N=>N.name).join(", ")}`),f=f.filter(N=>I.get(N.name)?.length));let b=null,$=Ur(e);if($){let{parser:N,language:_}=await ni(),B=we.readFileSync($,"utf-8"),P=N.parse(B),H=oi(P,_);if(H){let le=Q.dirname($),D=Q.join(le,H);i.includes(D)&&(b=D,console.log(` found HTML root: ${H} -> ${D}`))}}let S=new Map,m=0,d=0,k=0;for(let N of f){let _=I.get(N.name);if(m++,Je(`linking calls: service ${m} of ${f.length}`),o(`linking calls: service ${m} of ${f.length} (${s()})`),console.log(`
|
|
21
|
+
--- Service: ${N.name} (${N.kind}) \u2014 ${_.length} files in scope ---`),!_.length){console.log(" 0 files \u2014 nothing to trace for this service."),S.set(N.name,{nodes:[],resolvedEdges:[],workflows:[],routeIndex:new Map,eventIndex:new Map,rawEventIndex:new Map,parseResults:new Map});continue}let B=wo(new Map(_.map(F=>[F,p.get(F)]))),P=Ss(B,f),H=bs(B,f);P=js(P.concat(H)),console.log(` Stage 3: materialized ${H.length} inline-handler nodes before edge construction`);let le=Es(B,P),D=dr(B,P),Se=mr(B,P),ee=Wr(B,P);for(let F of _){let ne=new Set(B.get(F)?.exportedNames??[]);for(let V of P.filter(q=>q.filePath===F))V.exported=ne.has(V.name)}let ge=Ys(le,P,B,_,D,Se,ee),Ce=ge.filter(F=>F.resolved).length;console.log(` Stage 4 (scoped): resolved ${Ce}/${ge.length} edges`);for(let F of _){let ne=B.get(F),V=ne?.routes??[],q=ne?.listeners??[],se=fe(F,P),Oe=wt(F,ne?.imports??[],_),At=[];N.kind==="server"&&(At=ne?.socketListeners??[]),P=Ks(P,F,V,q,se,At,Oe)}let _e=P.filter(F=>F.isEntryPoint),tt=_e.filter(F=>F.trigger?.resolvedVia==="in-file").length,Ze=_e.filter(F=>F.trigger?.resolvedVia==="cross-file").length,De=_e.filter(F=>F.trigger?.resolvedVia==="inline").length;console.log(` Stage 5 entry points by resolution: in-file named ${tt}, cross-file named (BUG A) ${Ze}, inline (BUG B) ${De}`);let Ot=ge.filter(F=>F.type!=="reference"&&!F.viaArgument&&F.matchType!=="thisMethod"),Tt=Zs(P,Ot),nt=[];if(N.kind==="client"&&b&&_.includes(b)&&nt.push({id:`${b}::__module_root__`,name:"main",trigger:{type:"htmlRoot",label:"index.html script"}}),!nt.length){let F=Kt(N.rootPath,i),ne=F&&_.find(V=>Q.resolve(V)===F.entry);ne&&(console.log(` found HTML root for ${N.name}: ${Q.relative(e,F.indexHtml)} -> ${Q.relative(e,ne)} (${F.via})`),nt.push({id:`${ne}::__module_root__`,name:"main",trigger:{type:"htmlRoot",label:"index.html script"}}))}let pt=[];if(N.kind==="server"){let F=Q.join(N.rootPath,"package.json");if(we.existsSync(F))try{let ne=JSON.parse(we.readFileSync(F,"utf-8")),V=ne.main;if(!V&&ne.scripts?.start){let q=ne.scripts.start.match(/([\w./-]+\.(?:js|mjs|cjs|ts))/);q&&(V=q[1])}if(V){let q=Q.resolve(N.rootPath,V),se=_.find(Oe=>Q.resolve(Oe)===q);if(!se){let Oe=cn(N.rootPath,V,ne);Oe&&(se=_.find(At=>Q.resolve(At)===Oe.file))}se?pt.push({id:`${se}::__module_root__`,name:"main",trigger:{type:"processBootstrap",label:`${V} (package.json main)`}}):console.log(` note: ${N.name}'s package.json names "${V}" as its entry, but that file isn't in this service's own traced scope \u2014 no bootstrap workflow added.`)}}catch{}}if(!nt.length){let F=new Set(pt.map(q=>q.id.split("::")[0])),ne=new Set;for(let q of ge)q.resolved&&q.fromNodeId.endsWith("::__module_root__")&&ne.add(q.fromNodeId);let V=qr(N.rootPath).map(q=>({...q,file:_.find(se=>Q.resolve(se)===q.file)})).filter(q=>q.file);for(let q of _)Gr(q)&&!V.some(se=>se.file===q)&&V.push({file:q,kind:"shebang"});for(let q of V){if(F.has(q.file)||vt(Q.relative(e,q.file))||!ne.has(`${q.file}::__module_root__`))continue;F.add(q.file);let se=Q.relative(N.rootPath,q.file).split(Q.sep).join("/"),Oe=q.kind==="bin"?`CLI: ${q.binName}`:`Start: ${se}`;pt.push({id:`${q.file}::__module_root__`,name:"main",trigger:{type:"processBootstrap",label:`${se} (${q.kind==="bin"?"package.json bin":q.kind==="script"?"package.json script":q.kind==="main"?"package.json main":"#! shebang"}${q.mappedFrom?`, built to ${q.mappedFrom}`:""})`,workflowName:Oe}})}}let Nt=[];if(nt.length+pt.length+_e.filter(F=>!vt(Q.relative(e,F.filePath))).length===0){let F=Jr(N.rootPath,_);if(F){let ne=Q.relative(N.rootPath,F).split(Q.sep).join("/"),q=en(P,B,se=>wt(se,B.get(se)?.imports??[],_));for(let se of Vr(F,B,P,_,q))Nt.push({id:se.nodeId,name:P.find(Oe=>Oe.id===se.nodeId)?.name??se.name,trigger:{type:"publicApi",label:`${se.name} (exported from ${ne})`,workflowName:`API: ${se.name}`}});Nt.length&&console.log(` public API of ${N.name}: ${Nt.length} exported function(s)/method(s) from ${ne}`)}}let po=new Set(Nt.map(F=>F.id)),Ci=po.size?Tt.filter(F=>!po.has(F.id)):Tt,En=[...nt,...pt,..._e,...Nt,...Ci];console.log(` Stage 5 total entry points: ${En.length} (${nt.length} HTML root, ${pt.length} process bootstrap, ${_e.length} pattern-matched, ${Tt.length} fallback)`);let Ri=tn(ge),_i=or(En,Ri,P,Ot,8,Ot.length===ge.length?null:tn(Ot),ge.some(F=>F.matchType==="thisMethod")?tn(ge.filter(F=>F.matchType!=="thisMethod")):null),Li=new Set(Tt.map(F=>F.id)),Pi=F=>F.trigger?"physical":Li.has(F.entryPointId)?"fallback":"hub",Mi=_i.map(F=>({...F,origin:Pi(F),steps:sr(F.steps,P)})),Oi=ir(Mi),mo=Array.from(Oi.values()).map(cr),ho=mo.filter(F=>!vt(Q.relative(e,String(F.steps[0]?.nodeId??"").split("::")[0])));k+=mo.length-ho.length;let mt=ur(ho,{nodes:P});if(mt.some(F=>F.trigger)){let F=new Set(ge.filter(V=>V.type!=="returnValue"&&V.type!=="reference").map(V=>V.fromNodeId)),ne=new Set(mt.filter(V=>!V.trigger&&V.steps.length===1&&!F.has(V.steps[0].nodeId)).map(V=>V.steps[0].nodeId));ne.size&&(mt=mt.filter(V=>V.trigger||!ne.has(V.steps[0].nodeId)||V.steps.length>1),d+=ne.size)}console.log(` Stage 6-7: -> ${mt.length} named workflows for ${N.name}`),S.set(N.name,{nodes:P,resolvedEdges:ge,routeIndex:D,eventIndex:Se,rawEventIndex:ee,workflows:mt,parseResults:B,files:_,entryPointCount:En.length})}console.log(`
|
|
22
|
+
--- Stage 5 (stitch): cross-service edge resolution ---`),Je("linking services together"),o(`linking services together (${s()})`);let h=[],x=0,j=0;for(let N of f){let _=S.get(N.name);if(!_||!_.resolvedEdges.length)continue;let B=_.resolvedEdges.filter(P=>!P.resolved&&(P.type==="apiCall"||P.type==="socketEmit"||P.type==="rawSocketSend"));for(let P of B){let H=null,le=null;for(let D of f){if(D.name===N.name)continue;let Se=S.get(D.name);if(!Se)continue;let ee=null;if(P.type==="apiCall"&&P.scope!=="external"?ee=Se.routeIndex.get(xt(P.url)):P.type==="socketEmit"?ee=Se.eventIndex.get(P.eventName):P.type==="rawSocketSend"&&(ee=Se.rawEventIndex.get(P.eventName)),ee){H=ee,le=D.name;break}}H?(h.push({fromService:N.name,fromNodeId:P.fromNodeId,toService:le,toNodeId:H,via:P.type,key:P.url||P.eventName,confidence:"inferred",reason:"name-only match",...P.type==="apiCall"?{url:P.url}:{eventName:P.eventName}}),x++):j++}}console.log(` stitched ${x} cross-service edges`);let E=Or(f,S,{repoRoot:e});for(let N of E.edges)h.push(N);console.log(` + ${E.edges.length} links from HTTP clients / WebSockets (${E.edges.filter(N=>N.confidence==="exact").length} exact, ${E.edges.filter(N=>N.confidence==="resolved").length} resolved)`),console.log(` ${j} unresolved calls remain unresolved even after checking every other service`);try{let N=zr(f,S);for(let _ of N.edges)h.push(_);console.log(` + ${N.edges.length} queue links (${N.stats.producers} producers, ${N.stats.consumers} consumers with a known queue name; ${N.stats.unresolvedProducers+N.stats.unresolvedConsumers} left unlinked because the queue name could not be known for sure)`)}catch(N){console.log(` queue links skipped: ${N?.message??N}`)}if(t.lowMemory)for(let N of p.values())for(let _ of Object.keys(N))_!=="hadErrors"&&_!=="warnings"&&_!=="failed"&&_!=="skipped"&&_!=="errorMessage"&&delete N[_];let M=new Map;function T(N,_,B){if(!N||_==null||B==null)return{available:!1,reason:"no line range recorded for this node"};try{M.has(N)||(M.set(N,we.readFileSync(N,"utf-8").split(/\r\n|\n/)),M.size>256&&M.delete(M.keys().next().value));let P=M.get(N),H=Math.max(_,1),le=Math.min(B,P.length);if(H>P.length)return{available:!1,reason:"recorded line range is past the end of the current file \u2014 source has likely moved"};let D=P.slice(H-1,le).join(`
|
|
23
|
+
`);return{available:!0,filePath:N,startLine:H,endLine:le,text:D}}catch(P){return{available:!1,reason:`source unavailable: ${P.code==="ENOENT"?"file not found (deleted or moved)":P.message}`}}}let L=/^(addEventListener|removeEventListener|on|once|postMessage|onmessage|subscribe)$/i,O=new Set(["call","methodCall","callSite"]),C=new WeakMap;function z(N,_){let B=C.get(N);if(!B||B.n!==N.length){B={n:N.length,by:new Map};for(let P of N){let H=B.by.get(P.fromNodeId);H||B.by.set(P.fromNodeId,H=[]),H.push(P)}C.set(N,B)}return B.by.get(_)??[]}function K(N,_,B,P,H=null){let le=D=>!!(H&&!P&&!D.deferred&&D.resolved&&D.targetNodeId&&O.has(D.type)&&D.targetNodeId!==N&&H.inWorkflow.has(D.targetNodeId)&&!H.children.has(D.targetNodeId));return z(_,N).filter(D=>D.type!=="apiCall").filter(D=>D.resolved&&D.targetNodeId?le(D):!!D.deferred===P).map(D=>{let Se=D.type==="returnValue",ee=!Se&&L.test(D.calleeNameRaw||""),ge=(D.branchPath??[]).map(Ze=>({...Ze,source:B?T(B,Ze.conditionLine,Ze.conditionLine):{available:!1,reason:"owning function's node not found"}})),Ce=D.objectNameRaw?`${D.objectNameRaw}.${D.calleeNameRaw}`:D.calleeNameRaw,_e=Se?Ce:D.firstArgText?`${Ce}(${D.firstArgText})`:Ce,tt=le(D);return{label:_e,line:D.line??null,column:D.column??null,branchPath:ge,source:B?T(B,D.line,D.line):{available:!1,reason:"owning function's node not found"},tag:tt?"called-elsewhere":Se?"return-value":ee?"runtime-dispatched":"unresolvable-call-site",...tt?{targetNodeId:D.targetNodeId}:{},reason:tt?"a call to a function this workflow shows under another step (a function is placed once, under the first step that reaches it); it runs here, at this line, in this order":Se?"the value this branch returns \u2014 not a function call, just what this path produces":ee?`registered via ${D.calleeNameRaw}(...) \u2014 the handler runs later, outside this function's own execution`:P?"runs later, outside this function's own execution (an effect cleanup, a deferred callback)":"call target could not be statically resolved to a declared function (dynamic dispatch, external/browser API, or computed member access) \u2014 but it still runs here, in this order"}})}function R(N,_,B){return K(N,_,B,!0)}function W(N,_,B,P){return K(N,_,B,!1,P)}let Z=[];for(let N of f){let _=S.get(N.name);if(!_)continue;let B=new Map(_.nodes.map(P=>[P.id,P]));for(let P of _.workflows){let H=new Set([N.name]),le=new Set(P.steps.map(ee=>ee.nodeId)),D=new Map;for(let ee of P.steps)ee.parentNodeId!=null&&(D.get(ee.parentNodeId)??D.set(ee.parentNodeId,new Set).get(ee.parentNodeId)).add(ee.nodeId);let Se=P.steps.map(ee=>{let ge=h.find(De=>De.via!=="queue"&&De.fromService===N.name&&De.fromNodeId===ee.nodeId),Ce=B.get(ee.nodeId),_e=ee.parentNodeId?B.get(ee.parentNodeId):null,tt=(ee.branchPath??[]).map(De=>({...De,source:_e?T(_e.filePath,De.conditionLine,De.conditionLine):{available:!1,reason:"owning function's node not found"}})),Ze={...ee,branchPath:tt,source:Ce?T(Ce.filePath,Ce.startLine,Ce.endLine):{available:!1,reason:"node not found in this service's own graph"},alsoCallsRuntime:R(ee.nodeId,_.resolvedEdges,Ce?.filePath),inlineCalls:W(ee.nodeId,_.resolvedEdges,Ce?.filePath,{inWorkflow:le,children:D.get(ee.nodeId)??new Set})};return ge&&(H.add(ge.toService),Ze.crossesInto=ge.toService),Ze});Z.push({...P,steps:Se,serviceId:N.name,servicesTouched:[...H]})}}console.log(`
|
|
24
|
+
Done: ${Z.length} named workflows across all services
|
|
25
|
+
`),Z.forEach(N=>console.log(` - [${N.serviceId}] ${N.name} (${N.steps.length} steps, ${N.occurrences} entry point(s))`)),Je("writing the map"),o(`writing the map (${s()})`);let oe=t.outputDir??process.env.CANOPY_OUTPUT_DIR??Q.join(Ga,"..","output");we.existsSync(oe)||we.mkdirSync(oe,{recursive:!0});let re=Qt(e),dt=new Set(f.flatMap(N=>I.get(N.name)??[])),et=ys({discovered:r,parseResults:p,scopeFiles:dt,rel:re.rel,rootService:y.added});et.testWorkflowsExcluded=k,et.guessedWorkflowsDropped=d;let $t={repoRoot:re.repoRoot,coverage:et};we.writeFileSync(Q.join(oe,"meta.js"),`const meta = ${JSON.stringify($t,null,2)};`),we.writeFileSync(Q.join(oe,"meta.json"),JSON.stringify($t,null,2)),console.log(`
|
|
26
|
+
`+Gt(et)),we.existsSync(Q.join(oe,"history.js"))||we.writeFileSync(Q.join(oe,"history.js"),"const canopyHistory = null;");let A=null;try{A=re.json(Z,2)}catch(N){if(!(N instanceof RangeError))throw N}let G=A===null||A.length>ri;if(G&&A!==null)try{A=re.json(Z)}catch(N){if(!(N instanceof RangeError))throw N;A=null}if(G&&(A===null||A.length>ri)){let N=Vs(A===null?re.walk(Z):JSON.parse(A));we.writeFileSync(Q.join(oe,"workflows.js"),`const workflows = ${N};`),we.rmSync(Q.join(oe,"workflows.json"),{force:!0}),console.log(`
|
|
27
|
+
workflows.json omitted (${A===null?"over 500":(A.length/1e6).toFixed(1)} MB plain); workflows.js written with shared sub-structures (${(N.length/1e6).toFixed(1)} MB)`)}else we.writeFileSync(Q.join(oe,"workflows.json"),A),console.log(`
|
|
28
|
+
Saved to output/workflows.json`),we.writeFileSync(Q.join(oe,"workflows.js"),`const workflows = ${A};`),console.log("Saved to output/workflows.js (for the viewer)");let J=f.flatMap(N=>S.get(N.name)?.nodes??[]),ae=h.filter(N=>N.via!=="queue").map(N=>({fromNodeId:N.fromNodeId,targetNodeId:N.toNodeId,resolved:!0,matchType:"crossLayer",confidence:N.confidence})),be=[...f.flatMap(N=>S.get(N.name)?.resolvedEdges??[]),...ae],he=si(Z,J,be);he.crossServiceEdges=h,we.writeFileSync(Q.join(oe,"systemGraph.js"),`const systemGraph = ${re.json(he,2)};`);let Me=f.map(({isRepoRoot:N,ownsLeftovers:_,...B})=>({...B,nodeCount:J.filter(P=>P.serviceName===B.name).length,workflowCount:Z.filter(P=>P.serviceId===B.name).length}));we.writeFileSync(Q.join(oe,"services.js"),`const services = ${re.json(Me,2)};`),console.log(`Saved to output/systemGraph.js (${he.workflowLinks.length} workflow links, ${he.serviceLinks.length} service links)`),console.log("Saved to output/services.js"),console.log(`
|
|
29
|
+
Note on output shape: workflows.json entries gained two additive fields (serviceId, servicesTouched) \u2014 every field the old shape had (steps, name, trigger, occurrences, ...) is unchanged, so the existing viewer keeps working without modification.`);let ie=new Map;for(let N of f){let _=S.get(N.name);if(!_)continue;let B=re.clone(_.nodes.map(H=>({id:H.id,name:H.name,type:H.type,filePath:H.filePath,bodyHash:H.bodyHash??null,startLine:H.startLine===0?0:H.startLine,endLine:H.endLine===Number.MAX_SAFE_INTEGER?null:H.endLine,serviceName:H.serviceName,isEntryPoint:!!H.isEntryPoint}))),P=Is(re.clone(_.resolvedEdges.map(H=>({fromNodeId:H.fromNodeId,targetNodeId:H.targetNodeId??null,type:H.type,callKind:H.callKind,calleeNameRaw:H.calleeNameRaw,eventName:H.eventName,url:H.url,line:H.line??null,column:H.column??null,resolved:!!H.resolved,matchType:H.matchType??null}))));ie.set(N.name,{nodes:B,edges:P})}return{workflows:Z,perService:S,crossServiceEdges:h,services:f,publicGraph:ie,publicWorkflows:re.clone(Z),publicCrossServiceEdges:re.clone(h),fingerprint:Xt(Ns(i,re.rel)),analyzedFileCount:i.length,repoRoot:re.repoRoot,coverage:et}}var Ya=process.argv[1]&&globalThis.__canopyUrl("src/index.js")===qa(Q.resolve(process.argv[1])).href;Ya&&io(process.argv[2]||process.cwd()).catch(e=>{console.error("Pipeline failed:",e),process.exit(1)});var Va=ue.join(ue.dirname(ii(globalThis.__canopyUrl("src/history/sync.js"))),"..","..","output"),Ka=["workflows.json","workflows.js","systemGraph.js","services.js","meta.js","meta.json","history.js"],Xa=ue.dirname(ii(globalThis.__canopyUrl("src/history/sync.js"))).split(ue.sep).includes("node_modules"),Be=e=>process.env.CANOPY_OUTPUT_DIR||(Xa&&e?ue.join(ue.resolve(e),".canopy","output"):Va);async function Za(e,t){let n=console.log;console.log=()=>{};try{return await io(e,t)}finally{console.log=n}}function Qa(e){try{let t=JSON.parse(Ve.readFileSync(ue.join(Be(e),"meta.json"),"utf8"));return t.coverage&&ue.resolve(t.repoRoot)===ue.resolve(e)?t.coverage:null}catch{return null}}async function el(e,{full:t=!1}={}){let n=ue.resolve(e),s=Qt(n),o=jt(n),r=await Ho(n,o.files,s.rel,{full:t});return{fingerprint:Xt(r.hashes),reused:r.reused,rehashed:r.rehashed,discovered:o}}async function tl(e,{keep:t,say:n=()=>{},full:s=!1}){let o=Date.now(),r=ot(e),i=r.versions[r.versions.length-1],c=await el(e,{full:s}),a=c.fingerprint,l=!!i&&i.fingerprint===a&&(s||i.engineVersion!==Bt()||i.outputFormat!==ko);if(i&&i.fingerprint===a&&!l&&!s){try{Po(e,Be(e))}catch{}return{status:"no-changes",version:i,ms:Date.now()-o,coverage:Qa(e),fast:c}}let f=Ve.mkdtempSync(ue.join(Ja.tmpdir(),"canopy-sync-"));try{let y=await Za(e,{outputDir:f,onProgress:n,lowMemory:!0,noCache:s,discovered:c.discovered});Je("storing the version"),n(`storing the version (${Math.round((Date.now()-o)/1e3)} s)`);let u=zo(y),v=Do(u),p={nodes:u.nodes.length,edges:u.edges.length,workflows:u.workflows.length,physicalWorkflows:u.workflows.filter(d=>d.tier==="physical").length,crossServiceEdges:u.crossServiceEdges.length},w=Ao(e),I=bo(e,v,u,p,t,{refresh:l,protect:w?[w.version]:[]}),g=So();g&&n("history: "+g);let b=Re(e,["rev-parse","--abbrev-ref","HEAD"]),$=Re(e,["rev-parse","HEAD^{tree}"]);To(e,{engineFingerprint:Bt(),projectRoot:ue.resolve(e),lastAnalysed:{version:I.version,fingerprint:I.fingerprint,headSha:I.headSha,treeHash:$,branch:b}});let S=await import("./chunk-ILPARXQH.js").catch(()=>null);S&&S.writeHistoryJs(e,f);let m=Be(e);Ve.mkdirSync(m,{recursive:!0});for(let d of Ka)Ve.existsSync(ue.join(f,d))?Ve.copyFileSync(ue.join(f,d),ue.join(m,d)):Ve.rmSync(ue.join(m,d),{force:!0});try{Je("building the search index"),n(`building the search index (${Math.round((Date.now()-o)/1e3)} s)`),Lo(e,m)}catch(d){n("the search index could not be built: "+String(d.message).split(`
|
|
30
|
+
`)[0]+" (the map is fine; search falls back to the traced nodes)")}return{status:"new-version",version:I,ms:Date.now()-o,coverage:y.coverage}}finally{Ve.rmSync(f,{recursive:!0,force:!0})}}function nl(e,t=()=>{}){let n=Fo(e);if(!n.ok){let s=Bo(e);t(`The saved history in .canopy was damaged (${n.problems[0]}). It was moved to .canopy/${s} and Canopy is starting a fresh one; this run rebuilds everything.`)}Oo(e,Bt())}async function yn(e,{keep:t=Ht,say:n=console.log,full:s=!1}={}){if(e=ue.resolve(e),Dt(e),Ve.mkdirSync(ye(e).root,{recursive:!0}),nl(e,n),!Eo(e,process.env.CANOPY_VERSION??null,n))return Ro(e),n("sync already running - one rerun queued"),{status:"queued"};let o;try{do o=await tl(e,{keep:t,say:n,full:s}),s=!1,o.status==="no-changes"?n(`no changes (v${o.version.version} ${o.version.fingerprint.slice(0,7)}) [${o.ms} ms]`):n(`v${o.version.version} ${o.version.fingerprint.slice(0,7)} stored: ${o.version.counts.nodes} nodes, ${o.version.counts.edges} edges, ${o.version.counts.workflows} workflows, ${(o.version.bytes/1024/1024).toFixed(2)} MB${o.version.gzip?" (gzip)":""} [${o.ms} ms]`),o.coverage&&n(`
|
|
31
|
+
`+Gt(o.coverage));while(_o(e))}finally{Co(e)}if(o&&o.status!=="queued")try{let r=null;try{r=JSON.parse(Ve.readFileSync(ue.join(Be(e),"services.js"),"utf8").replace(/^const services = /,"").replace(/;\s*$/,"")).length}catch{}ze().syncCompleted({ms:o.ms,files:o.coverage?.analyzed,services:r})}catch{}return o}import pe from"node:fs";import Le from"node:path";import{spawn as ol}from"node:child_process";import{fileURLToPath as sl}from"node:url";var _t="# >>> canopy sync (managed block - do not edit) >>>",li="# <<< canopy sync <<<",ft=["post-commit","post-merge"],rl=globalThis.__canopyBundle??Le.join(Le.dirname(sl(globalThis.__canopyUrl("src/history/hooks.js"))),"..","cli.js"),il=e=>Le.resolve(e).split(Le.sep).join("/");function Lt(e){let t=Re(e,["rev-parse","--git-path","hooks"]);if(!t)throw new Error(`not a git repository: ${e}`);return Le.resolve(e,t)}var ci=JSON.parse(pe.readFileSync(Le.join(Te,"package.json"),"utf8")),cl=ci.name+"@"+ci.version,ai=e=>il(e).replace(/(["$`\\])/g,"\\$1");function vn(e){return[_t,"(",` if command -v canopy >/dev/null 2>&1; then canopy sync --background "${ai(e)}" >/dev/null 2>&1 </dev/null`,` elif command -v npx >/dev/null 2>&1; then ( npx --yes ${cl} sync --background "${ai(e)}" >/dev/null 2>&1 </dev/null & )`,' else echo "canopy not found; skipping map update"'," fi",") || true",li].join(`
|
|
32
32
|
`)+`
|
|
33
|
-
`}var
|
|
34
|
-
`+
|
|
35
|
-
`+
|
|
33
|
+
`}var wn=()=>new RegExp(`\\n?${_t.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}[\\s\\S]*?${li.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}\\n?`);function Pt(e){let t=Lt(e);pe.mkdirSync(t,{recursive:!0});let n=[];for(let s of ft){let o=Le.join(t,s),r=pe.existsSync(o)?pe.readFileSync(o,"utf8"):null,i;r===null?i=`#!/bin/sh
|
|
34
|
+
`+vn(e):wn().test(r)?i=r.replace(wn(),()=>`
|
|
35
|
+
`+vn(e)):i=r+(r.endsWith(`
|
|
36
36
|
`)?"":`
|
|
37
37
|
`)+`
|
|
38
|
-
`+
|
|
39
|
-
`));try{
|
|
40
|
-
`);i.replace(/^#!.*\n?/,"").trim()===""?
|
|
38
|
+
`+vn(e),pe.writeFileSync(o,i.replace(/\r\n/g,`
|
|
39
|
+
`));try{pe.chmodSync(o,493)}catch{}n.push(o)}return n}function fi(e){let t=Lt(e),n=[];for(let s of ft){let o=Le.join(t,s);if(!pe.existsSync(o))continue;let r=pe.readFileSync(o,"utf8");if(!wn().test(r))continue;let i=r.replace(wn(),`
|
|
40
|
+
`);i.replace(/^#!.*\n?/,"").trim()===""?pe.rmSync(o,{force:!0}):pe.writeFileSync(o,i.replace(/\n{3,}/g,`
|
|
41
41
|
|
|
42
|
-
`)),n.push(o)}return n}function
|
|
42
|
+
`)),n.push(o)}return n}function ui(e){if(!pe.existsSync(Le.resolve(e)))return null;let t=ye(e);pe.mkdirSync(t.root,{recursive:!0});let n=pe.openSync(t.log,"a");pe.writeSync(n,`
|
|
43
43
|
--- ${new Date().toISOString()} sync requested (pid ${process.pid})
|
|
44
|
-
`);let s=Object.fromEntries(Object.entries(process.env).filter(([r])=>!/^GIT_/i.test(r)||r.toUpperCase()==="GIT_EXEC_PATH"));s.CANOPY_HOOK="1";let o=
|
|
45
|
-
`);c.includes(_t)&&(s++,c.includes(n)&&o++)}return s<ft.length?"absent":o===ft.length?"current":"outdated"}import He from"node:fs";import Ke from"node:path";import{execFileSync as
|
|
46
|
-
`)[0]}t.push({name:s,critical:o,ok:c,detail:a,fix:i})};return n("Node version >= 18",!0,()=>({ok:Number(process.versions.node.split(".")[0])>=18,detail:"v"+process.versions.node}),"install Node 18 or newer from https://nodejs.org and run canopy again"),n("tree-sitter grammars (wasm)",!0,()=>{let s=[["web-tree-sitter","web-tree-sitter.wasm"],["tree-sitter-javascript","tree-sitter-javascript.wasm"],["tree-sitter-typescript","tree-sitter-typescript.wasm"],["tree-sitter-typescript","tree-sitter-tsx.wasm"],["tree-sitter-html","tree-sitter-html.wasm"]],o=s.filter(([r,i])=>!He.existsSync(Ke.join(
|
|
44
|
+
`);let s=Object.fromEntries(Object.entries(process.env).filter(([r])=>!/^GIT_/i.test(r)||r.toUpperCase()==="GIT_EXEC_PATH"));s.CANOPY_HOOK="1";let o=ol(process.execPath,[rl,"sync",Le.resolve(e)],{detached:!0,stdio:["ignore",n,n],windowsHide:!0,env:s});return o.unref(),pe.closeSync(n),o.pid}function di(e){let t=Lt(e),n=vn(e),s=0,o=0;for(let r of ft){let i=Le.join(t,r);if(!pe.existsSync(i))continue;let c=pe.readFileSync(i,"utf8").replace(/\r\n/g,`
|
|
45
|
+
`);c.includes(_t)&&(s++,c.includes(n)&&o++)}return s<ft.length?"absent":o===ft.length?"current":"outdated"}import He from"node:fs";import Ke from"node:path";import{execFileSync as pi}from"node:child_process";function xn(e){let t=[],n=(s,o,r,i)=>{let c=!1,a="";try{let l=r();c=l===!0||!!(l&&l.ok),a=l&&l.detail?l.detail:""}catch(l){a=String(l.message??l).split(`
|
|
46
|
+
`)[0]}t.push({name:s,critical:o,ok:c,detail:a,fix:i})};return n("Node version >= 18",!0,()=>({ok:Number(process.versions.node.split(".")[0])>=18,detail:"v"+process.versions.node}),"install Node 18 or newer from https://nodejs.org and run canopy again"),n("tree-sitter grammars (wasm)",!0,()=>{let s=[["web-tree-sitter","web-tree-sitter.wasm"],["tree-sitter-javascript","tree-sitter-javascript.wasm"],["tree-sitter-typescript","tree-sitter-typescript.wasm"],["tree-sitter-typescript","tree-sitter-tsx.wasm"],["tree-sitter-html","tree-sitter-html.wasm"]],o=s.filter(([r,i])=>!He.existsSync(Ke.join(Ft(r),i))).map(([,r])=>r);return{ok:o.length===0,detail:o.length?"missing "+o.join(", "):s.length+" files"}},"reinstall canopy: npm install -g canopy-engine (or, in a checkout, npm install in the canopy-engine folder)"),n("query files (.scm)",!0,()=>{let s=[Ke.join(Te,"src","stage2_parse","queries"),Ke.join(Te,"dist","queries")].find(r=>He.existsSync(r))??Ke.join(Te,"dist","queries"),o=He.readdirSync(s).filter(r=>r.endsWith(".scm")).length;return{ok:o>=10,detail:o+" files"}},"reinstall canopy: the package is missing its query files (dist/queries)"),n("write access to <path>/.canopy",!0,()=>{let s=ye(e).root;He.mkdirSync(s,{recursive:!0});let o=Ke.join(s,`.doctor-${process.pid}`);return He.writeFileSync(o,"x"),He.rmSync(o),{ok:!0,detail:s}},`make ${e} writable for your user, or run canopy on a folder you own`),n("git available",!1,()=>({ok:!!pi("git",["--version"],{encoding:"utf8",stdio:["ignore","pipe","ignore"]}),detail:pi("git",["--version"],{encoding:"utf8"}).trim()}),"install git (https://git-scm.com); without it version history and the hook are limited"),n("map viewer present",!1,()=>({ok:He.existsSync(Ke.join(Te,"ui-react","index.html"))&&He.existsSync(Ke.join(Te,"ui-react","dist"))}),"canopy open needs the built viewer (ui-react/dist); reinstall from a build that includes it"),n("post-commit hook installed",!1,()=>{if(!Re(e,["rev-parse","--git-dir"]))return{ok:!1,detail:"not a git repository"};let s=Lt(e),o=ft.every(r=>He.existsSync(Ke.join(s,r))&&He.readFileSync(Ke.join(s,r),"utf8").includes(_t));return{ok:o,detail:o?"post-commit, post-merge":""}},`canopy hook install "${e}"`),t}function mi(e,t,n,s=console.log){s(`canopy ${n} doctor (${t})
|
|
47
47
|
`);for(let r of e)s(`${r.ok?"OK ":"FAIL"} ${r.name}${r.detail?" - "+r.detail:""}${r.ok?"":`
|
|
48
48
|
fix: ${r.fix}`}${!r.ok&&!r.critical?" (not critical)":""}`);let o=e.filter(r=>r.critical&&!r.ok);return s(`
|
|
49
|
-
${o.length?`${o.length} critical problem(s) - fix them and run canopy doctor again`:"all critical checks passed"}`),o.length}import
|
|
49
|
+
${o.length?`${o.length} critical problem(s) - fix them and run canopy doctor again`:"all critical checks passed"}`),o.length}import Tl from"node:readline";import me from"node:fs";import hl from"node:net";import gl from"node:os";import Xe from"node:path";import yl from"node:readline";function ao({stream:e=process.stdout,env:t=process.env,flags:n={},platform:s=process.platform}={}){let o=!!e.isTTY,r="NO_COLOR"in t&&t.NO_COLOR!==""||!!n["no-color"]||n.color===!1||t.TERM==="dumb",i=o&&!r&&!n.quiet,c=i&&t.TERM!=="linux"&&(s!=="win32"||!!(t.WT_SESSION||t.TERM_PROGRAM||t.ConEmuANSI==="ON"||t.ANSICON)||/UTF-?8/i.test(`${t.LC_ALL??""}${t.LC_CTYPE??""}${t.LANG??""}`));return{tty:o,color:i,rich:i,unicode:c,columns:Math.max(40,Math.min(e.columns||80,200)),quiet:!!n.quiet}}var co={unicode:{ok:"\u2714",fail:"\u2716",line:"\u2502",top:"\u250C",cap:"\u2514",done:"\u25CF",bad:"\u25A0",spin:["\u280B","\u2819","\u2839","\u2838","\u283C","\u2834","\u2826","\u2827","\u2807","\u280F"],full:"\u2588",empty:"\u2591",arrow:"\u2192",dot:"\xB7"},ascii:{ok:"[ok]",fail:"[x]",line:"|",top:"+",cap:"+",done:"*",bad:"x",spin:["|","/","-","\\"],full:"#",empty:"-",arrow:"->",dot:"-"}},al=(e,t,n)=>e?`\x1B[${t}m${n}\x1B[0m`:n,hi=e=>e<59500?`${(e/1e3).toFixed(1)} s`:`${Math.floor(e/6e4)} min ${String(Math.round(e%6e4/1e3)).padStart(2,"0")} s`,ll=e=>!Number.isFinite(e)||e<0?"":e<1?"< 1 s":e<60?`${Math.round(e)} s`:`${Math.floor(e/60)} min ${Math.round(e%60)} s`;function fl({done:e,total:t,unit:n="files",elapsedMs:s,width:o=24,sym:r=co.ascii}){let i=t>0?Math.min(1,e/t):0,c=Math.round(i*o),a=s>500?e/(s/1e3):0,l=a>0?(t-e)/a:NaN,f=r.full.repeat(c)+r.empty.repeat(o-c),y=String(Math.floor(i*100)).padStart(3)+"%";return`[${f}] ${y} ${e.toLocaleString("en-US")}/${t.toLocaleString("en-US")} ${n}${a?` ${Math.round(a).toLocaleString("en-US")} ${n}/s`:""}${l===l&&i<1?` ETA ${ll(l)}`:""}`}function gi({stream:e=process.stdout,caps:t=ao({stream:e}),now:n=()=>Date.now(),interval:s=80,onExitHook:o=!0}={}){let r=t.unicode?co.unicode:co.ascii,i=(R,W)=>al(t.color,R,W),c=R=>i("2",R),a=R=>i("32",R),l=R=>i("31",R),f=R=>i("1",R),y=R=>i("36",R),u=null,v=!0,p=!1,w=null,I=0,g=null,b=!1,$=!1,S=-1,m="",d=R=>{try{e.write(R)}catch{}},k=()=>{t.rich&&!$&&(d("\x1B[?25l"),$=!0)},h=()=>{$&&(d("\x1B[?25h"),$=!1)},x=()=>{b&&(d("\r\x1B[2K"),b=!1)},j=R=>R.replace(/\u001b\[[0-9;?]*[A-Za-z]/g,"").length;function E(R){let W=u.title,Z=R(W),oe=t.columns-1;j(Z)>oe&&(W=W.replace(/\s*\(.*\)\s*$/,""),Z=R(W));let re=j(Z)-oe;if(re>0){let dt=t.unicode?"\u2026":"...";W=W.slice(0,Math.max(6,W.length-re-dt.length))+dt,Z=R(W)}return Z}function M(){let R=i("36",r.spin[I%r.spin.length]);return E(w?W=>` ${R} ${W} ${fl({done:w.done,total:w.total,unit:w.unit,elapsedMs:n()-w.started,width:Math.max(8,Math.min(24,t.columns-66)),sym:r})}`:W=>` ${R} ${W}${m?c(" "+m):""} ${c(hi(n()-u.started))}`)}function T(){!t.rich||!u||(k(),d(`\r\x1B[2K${M()}`),b=!0)}let L=()=>{I++,T()},O=()=>{t.rich&&s>0&&!g&&(g=setInterval(L,s),g.unref?.())},C=()=>{g&&(clearInterval(g),g=null)};function z(R=!0){if(!u)return;C();let W=hi(n()-u.started);t.rich&&(x(),d(` ${R?a(r.done):l(r.bad)} ${u.title} ${c(W)}
|
|
50
50
|
`)),v=v&&R,u=null,w=null,m="",S=-1,h()}let K={caps:t,line(R=""){t.quiet||(t.rich&&b?(x(),d(R+`
|
|
51
51
|
`),T()):d(R+`
|
|
52
|
-
`))},say(R){if(t.quiet)return;let W=/^\[(\d+)\/(\d+)\] (.*?)\.\.\.$/.exec(R);if(!t.rich){let
|
|
53
|
-
${r.done} ${
|
|
54
|
-
`)):/^\s{6}\S/.test(
|
|
55
|
-
`):d(
|
|
52
|
+
`))},say(R){if(t.quiet)return;let W=/^\[(\d+)\/(\d+)\] (.*?)\.\.\.$/.exec(R);if(!t.rich){let Z=String(R);W?(p=!0,d(`${r.line}
|
|
53
|
+
${r.done} ${Z}
|
|
54
|
+
`)):/^\s{6}\S/.test(Z)?d(`${r.line}${Z.slice(1)}
|
|
55
|
+
`):d(Z+`
|
|
56
56
|
`);return}if(W){z(!0),p||(d(` ${a(r.top)}
|
|
57
57
|
`),p=!0),d(` ${v?a(r.line):l(r.line)}
|
|
58
58
|
`),u={n:+W[1],total:+W[2],title:W[3],started:n()},I=0,T(),O();return}if(/^\s{6}\S/.test(R)){K.line(` ${c(r.line)} ${c(String(R).trim())}`);return}K.line(String(R))},important(R){t.rich&&b?(x(),d(R+`
|
|
59
59
|
`),T()):d(String(R)+`
|
|
60
|
-
`)},banner(R,W,
|
|
60
|
+
`)},banner(R,W,Z){if(!t.quiet){if(!t.rich){d(`${R} ${W} - ${Z}
|
|
61
61
|
`);return}d(`
|
|
62
|
-
${f(y(R))} ${c("v"+W)} ${c(r.dot)} ${
|
|
62
|
+
${f(y(R))} ${c("v"+W)} ${c(r.dot)} ${Z}
|
|
63
63
|
|
|
64
|
-
`)}},progress(R,W,
|
|
64
|
+
`)}},progress(R,W,Z="files",oe="reading files"){if(t.quiet)return;if(t.rich){w=w??{started:n()},Object.assign(w,{done:R,total:W,unit:Z}),g||T();return}let re=W>0?Math.floor(R/W*10):0;re!==S&&(S=re,d(`${r.line} ${oe}: ${R} of ${W}
|
|
65
65
|
`))},endProgress(){w=null,S=-1},status(R){t.quiet||(t.rich?(w=null,m=R,T()):d(`${r.line} ${R}
|
|
66
66
|
`))},endStep:z,tick:L,close(){!p||t.quiet||(z(!0),p=!1,t.rich?d(` ${v?a(r.line):l(r.line)}
|
|
67
67
|
${v?a(r.cap):l(r.cap)}
|
|
68
68
|
`):d(`${r.line}
|
|
69
69
|
${r.cap}
|
|
70
|
-
`))},final({url:R,changes:W=null,update:
|
|
70
|
+
`))},final({url:R,changes:W=null,update:Z=null,hint:oe="press Ctrl+C to stop"}){if(z(!0),t.quiet){d(R+`
|
|
71
71
|
`);return}if(!t.rich){K.close();return}K.close(),d(`
|
|
72
72
|
${a(r.ok)} ${f("Canopy is ready")}
|
|
73
73
|
|
|
74
74
|
${c("Local:")} ${y(R)}
|
|
75
75
|
`),W&&d(` ${c("Since last visit:")} ${W}
|
|
76
|
-
`),
|
|
76
|
+
`),Z&&d(` ${c("Update:")} ${Z}
|
|
77
77
|
`),d(`
|
|
78
78
|
${c(oe)}
|
|
79
|
-
`)},restore(){C(),b&&x(),h()}};if(o&&t.rich){let R=()=>K.restore();process.once("exit",R);for(let W of["SIGINT","SIGTERM"])process.once(W,()=>{R(),process.exit(W==="SIGINT"?130:143)})}return K}import kt from"node:fs";import
|
|
79
|
+
`)},restore(){C(),b&&x(),h()}};if(o&&t.rich){let R=()=>K.restore();process.once("exit",R);for(let W of["SIGINT","SIGTERM"])process.once(W,()=>{R(),process.exit(W==="SIGINT"?130:143)})}return K}import kt from"node:fs";import ul from"node:http";import lo from"node:path";var ut=e=>lo.join(ye(e).root,"server.json"),yi=e=>lo.join(ye(e).root,"server.lock");function dl(e,{timeoutMs:t=1500}={}){return new Promise(n=>{let s=ul.get({host:"127.0.0.1",port:e,path:"/api/health",headers:{host:`127.0.0.1:${e}`},timeout:t},o=>{let r="";o.on("data",i=>{r+=i}),o.on("end",()=>{try{let i=JSON.parse(r);n(o.statusCode===200&&i.ok&&i.app==="canopy"?i:null)}catch{n(null)}})});s.on("timeout",()=>{s.destroy(),n(null)}),s.on("error",()=>n(null))})}var pl=e=>{try{return Mo(e)?.projectId??null}catch{return null}};async function ml(e){let t=null;try{t=JSON.parse(kt.readFileSync(ut(e),"utf8"))}catch{return null}let s=t&&Number.isInteger(t.pid)&&t.pid!==process.pid&&$o(t.pid)&&Number.isInteger(t.port)?await dl(t.port):null;if(!(s&&(!t.projectId||!s.projectId||t.projectId===s.projectId))){try{kt.rmSync(ut(e),{force:!0})}catch{}return null}return{...t,url:`http://127.0.0.1:${t.port}/`}}async function kn(e,t,{waitMs:n=6e3}={}){let s=Date.now()+n;for(;;){let o=await ml(e);if(o)return{ok:!1,running:o};if(Io(yi(e),{},t).ok)return{ok:!0};if(Date.now()>s)return{ok:!1,running:null,busy:!0};await new Promise(i=>setTimeout(i,150))}}function Sn(e,{port:t,version:n,navToken:s=null}){let o={pid:process.pid,port:t,startedAt:new Date().toISOString(),version:n,projectId:pl(e),...s?{navToken:s}:{}},r=ut(e)+"."+process.pid+".tmp";kt.mkdirSync(lo.dirname(ut(e)),{recursive:!0}),kt.writeFileSync(r,JSON.stringify(o,null,2),{mode:384}),kt.renameSync(r,ut(e));let i=()=>{try{No(ut(e))?.pid===process.pid&&kt.rmSync(ut(e),{force:!0})}catch{}jo(yi(e))};return process.once("exit",i),{unregister:i}}var vi=Number(process.env.CANOPY_MIN_FREE_MB)||300,vl=".js .jsx .mjs .cjs .ts .tsx .mts .cts",bn=class extends Error{constructor(t,n){super(n),this.code=t,this.line=n}},je=(e,t)=>{throw new bn(e,t)};function wl(e){let t=!!Re(e,["rev-parse","--git-dir"]),n=Xe.join(e,".gitignore"),s=me.existsSync(n);if(!t&&!s)return"skipped";let o=s?me.readFileSync(n,"utf8"):"";if(o.split(/\r?\n/).some(i=>/^\/?\.canopy\/?$/.test(i.trim())))return"already";let r=/\r\n/.test(o)?`\r
|
|
80
80
|
`:`
|
|
81
|
-
`;return
|
|
81
|
+
`;return me.appendFileSync(n,(o&&!/\r?\n$/.test(o)?r:"")+"# Canopy (code map output)"+r+".canopy/"+r),s?"added":"created"}var wi=e=>Xe.join(ye(e).root,"prefs.json"),xi=e=>{try{return JSON.parse(me.readFileSync(wi(e),"utf8"))}catch{return{}}};function $n(e,t){let n={...xi(e),...t};for(let s of Object.keys(n))n[s]===void 0&&delete n[s];me.mkdirSync(ye(e).root,{recursive:!0}),me.writeFileSync(wi(e),JSON.stringify(n,null,2))}function xl(e){return new Promise(t=>{let n=hl.createServer();n.once("error",s=>t({ok:!1,code:s.code,message:s.message})),n.listen(e,"127.0.0.1",()=>{let s=n.address().port;n.close(()=>t({ok:!0,port:s}))})})}function kl(e){try{let t=me.statfsSync(e);return Math.floor(t.bavail*t.bsize/1048576)}catch{return null}}var Sl=()=>!!(process.stdin.isTTY&&process.stdout.isTTY)||!!process.env.CANOPY_ASSUME_TTY;function bl(e,t){return new Promise(n=>{let s=yl.createInterface({input:process.stdin,output:process.stdout,terminal:!1}),o=!1,r=i=>{o||(o=!0,s.close(),n(i))};s.question(e,i=>r(i.trim())),s.once("close",()=>r(""))}).then(n=>n===""?t:n)}function $l(e){try{return JSON.parse(me.readFileSync(Xe.join(e,"meta.json"),"utf8"))}catch{return null}}function Nl(e){try{return JSON.parse(me.readFileSync(Xe.join(e,"services.js"),"utf8").replace(/^\s*const services\s*=\s*/,"").replace(/;\s*$/,""))}catch{return[]}}var Il=e=>`How did it go? ${e.canopyFeedbackUrl||"see FEEDBACK.md in the README (about 20 minutes)"}`;async function ki(e){let{startViewer:t,openBrowser:n,viewerProblem:s}=await import("./chunk-T3YCNXUR.js"),o=e.say?null:gi({caps:ao({flags:{quiet:e.quiet,"no-color":e.noColor}})}),r=e.say??(p=>o.say(p)),i=p=>o?o.important(p):r(p),{pkg:c}=e,a=null;try{return await l()}catch(p){if(o?.endStep(!1),o?.restore(),p instanceof bn){if(i(p.line),a)try{me.rmdirSync(a)}catch{}return p.code}return i(`Canopy stopped because of an unexpected problem: ${String(p.message??p).split(`
|
|
82
82
|
`)[0]}
|
|
83
83
|
Run "canopy doctor", then send its output and .canopy/sync.log to whoever gave you Canopy.`),process.env.CANOPY_DEBUG&&r(p.stack),1}async function l(){let p=Xe.resolve(e.target??process.cwd());o?o.banner("Canopy",c.version,"a map of what your JavaScript / TypeScript code does"):r(`Canopy ${c.version} - a map of what your JavaScript / TypeScript code does`),r(`Folder: ${Xe.basename(p)||p}
|
|
84
|
-
`),r("[1/6] Checking this computer..."),Number(process.versions.node.split(".")[0])<18&&je(1,`Canopy needs Node 18 or newer and this is Node ${process.versions.node}. Install the current LTS from https://nodejs.org and run canopy again.`);let w=
|
|
85
|
-
What to try next: run canopy inside the folder that holds your .js / .ts code (for a monorepo, the folder of one package), or pass it: canopy <folder>.`);let x=$&&Re(p,["rev-parse","--verify","-q","HEAD"])!==null;r(` ${h.length.toLocaleString("en-US")} JavaScript / TypeScript file${h.length===1?"":"s"}. ${$?x?"Git repository.":"Git repository with no commits yet (that is fine).":"Not a git repository (that is fine; version-aware features are limited)."}`),r("[3/6] Preparing the output folder..."),
|
|
86
|
-
`);let O=Be(p);if(e.noOpen)return r("[6/6] Not opening the map (--no-open). To view it later: canopy open"),v(),0;r("[6/6] Opening the map...");let C=await
|
|
84
|
+
`),r("[1/6] Checking this computer..."),Number(process.versions.node.split(".")[0])<18&&je(1,`Canopy needs Node 18 or newer and this is Node ${process.versions.node}. Install the current LTS from https://nodejs.org and run canopy again.`);let w=me.existsSync(p)&&me.statSync(p).isDirectory();me.existsSync(p)||je(1,`That folder does not exist: ${p}. Check the spelling, or run canopy inside your project folder.`),w||je(1,`${p} is a file, not a folder. Run canopy on the folder that contains it: canopy "${Xe.dirname(p)}"`);let I=me.existsSync(ye(p).root),g=xn(p);I||(a=ye(p).root);let b=g.find(R=>R.critical&&!R.ok);b&&je(1,`${b.name} failed${b.detail?" ("+b.detail+")":""}. ${b.fix}.`.replace(/\.\.$/,"."));let $=!!Re(p,["rev-parse","--git-dir"]),S=g.find(R=>R.name==="git available")?.ok,m=s();m&&!e.noOpen&&je(1,`Canopy cannot show the map: ${m.replace(/\n\s*/g,". ")}.`);let d=kl(p);if(d!==null&&d<vi&&je(1,`Only ${d} MB free on the disk holding ${p}; Canopy needs about ${vi} MB. Free some space and run canopy again.`),!e.noOpen){let R=await xl(e.port??0);R.ok||je(1,R.code==="EADDRINUSE"?`Port ${e.port} is already in use. Pick another with --port=NUMBER, or leave --port out and Canopy picks a free one.`:`Canopy cannot open a local port on 127.0.0.1 (${R.code||R.message}). Check your firewall or security software and run canopy again.`)}r(` Node ${process.versions.node}, ${S?"git found":"git not found (no version history or commit hook)"}, ${d===null?"disk space not checked":d+" MB free"}${e.noOpen?"":", a local port is free"}.`),r("[2/6] Looking at your project..."),me.readdirSync(p).filter(R=>R!==".git"&&R!==".canopy").length===0&&je(1,`${p} is empty. Add some JavaScript or TypeScript code and run canopy again.`);let h=Dn(p);h.length===0&&je(3,`No JavaScript or TypeScript files found in ${p}. Canopy currently supports JavaScript and TypeScript (${vl}); other languages are not read yet.
|
|
85
|
+
What to try next: run canopy inside the folder that holds your .js / .ts code (for a monorepo, the folder of one package), or pass it: canopy <folder>.`);let x=$&&Re(p,["rev-parse","--verify","-q","HEAD"])!==null;r(` ${h.length.toLocaleString("en-US")} JavaScript / TypeScript file${h.length===1?"":"s"}. ${$?x?"Git repository.":"Git repository with no commits yet (that is fine).":"Not a git repository (that is fine; version-aware features are limited)."}`),r("[3/6] Preparing the output folder..."),me.mkdirSync(ye(p).root,{recursive:!0}),Dt(p);let j=wl(p),E={added:"added .canopy/ to .gitignore",created:"created .gitignore with .canopy/ in it",already:".canopy/ is already in .gitignore",skipped:"no git repository, so no .gitignore change"}[j];r(` Map output goes to ${Xe.join(p,".canopy")} (${E}).`),r("[4/6] Commit hook..."),await f(p,$);let M=ot(p).versions.length>0;r(`[5/6] ${M?"Checking what changed since last time":"Building your map for the first time (a big project can take a few minutes)"}...`);let T=await y(p,h.length);u(p,T);let L=null;try{L=Yo(Go(p))}catch{L=null}L&&!(o&&o.caps.rich)&&r(` ${L}.
|
|
86
|
+
`);let O=Be(p);if(e.noOpen)return r("[6/6] Not opening the map (--no-open). To view it later: canopy open"),v(),0;r("[6/6] Opening the map...");let C=await kn(p,c.version);if(!C.ok&&C.running){let R=C.running.url,W=n(R);return o&&o.caps.quiet?(o.final({url:R}),0):(r(` Canopy is already running for this project (started ${C.running.startedAt?.replace("T"," ").slice(0,16)??"earlier"}): ${R}`),r(W?" Opened it in your browser. Nothing else was started.":" Open that address in your browser. Nothing else was started."),(!o||!o.caps.rich)&&v(),0)}C.ok||je(1,"Another Canopy is just starting for this project. Wait a few seconds and run canopy again, or open the address it printed.");let z;try{z=await t(O,e.port??0,{repoRoot:p}),Sn(p,{port:z.port,version:c.version,navToken:z.navToken})}catch(R){je(1,`Canopy cannot start the viewer: ${R.code||R.message}. ${R.code==="EADDRINUSE"?"Pick another port with --port=NUMBER.":"Check your firewall or security software."}`)}let K=n(z.url);return o&&o.caps.rich?o.final({url:z.url,changes:L,update:Rn(c.version),hint:K?"your browser should open now; press Ctrl+C to stop":"open that address in your browser; press Ctrl+C to stop"}):o&&o.caps.quiet?o.final({url:z.url}):(r(` ${z.url}`),r(K?" Your browser should open now. If it does not, paste that address into one.":" Open that address in your browser."),v()),e.forSeconds?(await new Promise(R=>setTimeout(R,e.forSeconds*1e3)),z.server.close(),o?.restore(),0):((!o||!o.caps.rich)&&r("Press Ctrl+C to stop."),await new Promise(()=>{}),0)}async function f(p,w){if(e.noHook){r(" Commit hook skipped (--no-hook).");return}if(!w){r(" No git repository here, so there is no commit hook to set up.");return}if(!jl()){r(" git is not installed, so the commit hook is skipped.");return}let I;try{I=di(p)}catch(b){r(" Could not look at the git hooks ("+String(b.message).split(`
|
|
87
87
|
`)[0]+"); skipping the commit hook.");return}if(I==="current"){r(" The map already updates on every commit.");return}if(I==="outdated"){try{Pt(p),r(" Refreshed the commit hook (it now matches this Canopy).")}catch(b){r(" Could not refresh the commit hook: "+String(b.message).split(`
|
|
88
|
-
`)[0])}return}if(
|
|
89
|
-
`)[0]+". Continuing without it.")}}async function y(p,w){let I=Date.now(),g=S=>{let m=String(S),d=/parsing: (\d+)\/(\d+) files/.exec(m);if(d){let k=Number(d[1]);o?o.progress(k,Number(d[2])):r(` reading files: ${d[1]} of ${d[2]}`);return}/^(linking calls|linking services|writing the map|storing the version|building the search index)/.test(m)&&(o?(o.endProgress(),o.status(m)):r(` ${m}`))};r(` Reading ${w.toLocaleString("en-US")} file${w===1?"":"s"}, linking calls, finding entry points, tracing workflows...`);let b;for(let S=0;S<2&&(b=await
|
|
88
|
+
`)[0])}return}if(xi(p).hook==="declined"&&!e.yes){r(" The commit hook is off (you chose that earlier). Turn it on with: canopy hook install");return}let g=!0;if(e.yes)r(" Update the map on every commit? [Y/n] Y (--yes)");else if(!Sl())r(" Update the map on every commit? [Y/n] Y (default; no terminal to ask)");else{let b=await bl(" Update the map on every commit? [Y/n] ","Y");g=/^y(es)?$/i.test(b)}if(!g){$n(p,{hook:"declined"}),r(" Okay, no hook. Turn it on any time with: canopy hook install");return}try{Pt(p),$n(p,{hook:void 0}),r(" Done: after every commit and merge the map updates itself in the background (it never blocks or fails a commit). Remove it with: canopy hook uninstall")}catch(b){r(" Could not install the commit hook: "+String(b.message).split(`
|
|
89
|
+
`)[0]+". Continuing without it.")}}async function y(p,w){let I=Date.now(),g=S=>{let m=String(S),d=/parsing: (\d+)\/(\d+) files/.exec(m);if(d){let k=Number(d[1]);o?o.progress(k,Number(d[2])):r(` reading files: ${d[1]} of ${d[2]}`);return}/^(linking calls|linking services|writing the map|storing the version|building the search index)/.test(m)&&(o?(o.endProgress(),o.status(m)):r(` ${m}`))};r(` Reading ${w.toLocaleString("en-US")} file${w===1?"":"s"}, linking calls, finding entry points, tracing workflows...`);let b;for(let S=0;S<2&&(b=await yn(p,{say:m=>g(m),onProgress:g,full:!!e.full}).catch(m=>je(1,`The analysis failed: ${String(m.message??m).split(`
|
|
90
90
|
`)[0]}
|
|
91
|
-
Run "canopy doctor" and send its output with ${Xe.join(p,".canopy","sync.log")} to whoever gave you Canopy.`)),b.status==="queued");S++){r(" Another update is already running; waiting for it to finish...");for(let m=0;m<1200&&
|
|
92
|
-
Your map`),r(` services: ${b.length}${b.length?" ("+b.map(S=>S.id??S.name).slice(0,8).join(", ")+(b.length>8?", ...":"")+")":""}`),r(` workflows: ${$.workflows??"?"}${$.physicalWorkflows!==void 0?` (${$.physicalWorkflows} traced from real code, ${$.workflows-$.physicalWorkflows} guessed)`:""}`),g){let S=g.analyzed?Math.round(g.inService/g.analyzed*100):0;r(` files inside a service: ${g.inService} of ${g.analyzed} (${S}%)`),r(` files with parse errors: ${g.parseErrors}${g.parseErrors?" ("+g.parseErrorFiles.slice(0,3).join(", ")+(g.parseErrorFiles.length>3?", ...":"")+")":""}`),g.notAnalyzedTotal&&r(` not read yet: ${g.notAnalyzedTotal} files in languages Canopy does not support (${Object.entries(g.notAnalyzed).map(([m,d])=>`${d} ${m}`).join(", ")})`)}b.length||r(" The map is empty: Canopy found no entry points (routes, listeners, a main file) it recognises in this project."),r("")}function v(){o&&o.close(),r("Next time just run `canopy`.");let p=Rn(c.version);p&&r(p),r(
|
|
93
|
-
`)}function uo(e,{version:t,stage:n,code:s,signal:o,memory:r,totalmem:i=
|
|
94
|
-
`);return
|
|
95
|
-
`+
|
|
91
|
+
Run "canopy doctor" and send its output with ${Xe.join(p,".canopy","sync.log")} to whoever gave you Canopy.`)),b.status==="queued");S++){r(" Another update is already running; waiting for it to finish...");for(let m=0;m<1200&&me.existsSync(ye(p).lock);m++)await new Promise(d=>setTimeout(d,500))}b.status==="queued"&&je(1,"Another Canopy update is still running. Wait for it to finish and run canopy again."),o?.endProgress();let $=((Date.now()-I)/1e3).toFixed(1);return r(b.status==="no-changes"?` Nothing changed since version ${b.version.version} (${$} s).`:` Saved version ${b.version.version} (${$} s).`),b}function u(p,w){let I=Be(p),g=w.coverage??$l(I)?.coverage,b=Nl(I),$=w.version.counts??{};if(r(`
|
|
92
|
+
Your map`),r(` services: ${b.length}${b.length?" ("+b.map(S=>S.id??S.name).slice(0,8).join(", ")+(b.length>8?", ...":"")+")":""}`),r(` workflows: ${$.workflows??"?"}${$.physicalWorkflows!==void 0?` (${$.physicalWorkflows} traced from real code, ${$.workflows-$.physicalWorkflows} guessed)`:""}`),g){let S=g.analyzed?Math.round(g.inService/g.analyzed*100):0;r(` files inside a service: ${g.inService} of ${g.analyzed} (${S}%)`),r(` files with parse errors: ${g.parseErrors}${g.parseErrors?" ("+g.parseErrorFiles.slice(0,3).join(", ")+(g.parseErrorFiles.length>3?", ...":"")+")":""}`),g.notAnalyzedTotal&&r(` not read yet: ${g.notAnalyzedTotal} files in languages Canopy does not support (${Object.entries(g.notAnalyzed).map(([m,d])=>`${d} ${m}`).join(", ")})`)}b.length||r(" The map is empty: Canopy found no entry points (routes, listeners, a main file) it recognises in this project."),r("")}function v(){o&&o.close(),r("Next time just run `canopy`.");let p=Rn(c.version);p&&r(p),r(Il(c))}}function jl(){return!!Re(gl.tmpdir(),["--version"])}import Nn from"node:fs";import Si from"node:os";import Qe from"node:path";import{spawn as El}from"node:child_process";var Mt="CANOPY_CHILD",Cl=2048,Rl=8192,bi=1024*1024;function _l({env:e=process.env,nodeOptions:t=e.NODE_OPTIONS??"",totalmem:n=Si.totalmem()}={}){let s=Number(e.CANOPY_MAX_MEMORY_MB);if(Number.isFinite(s)&&s>=256)return{mb:Math.floor(s),source:"CANOPY_MAX_MEMORY_MB"};let o=/--max-old-space-size[= ](\d+)/.exec(t);return o?{mb:null,userMb:Number(o[1]),source:"NODE_OPTIONS"}:{mb:Math.max(Cl,Math.min(Rl,Math.floor(n*.75/bi))),source:"75% of this computer's memory"}}var Ll=new Set(["version","help","update","hook","install-hook","uninstall-hook","doctor","history","diff","open","mcp","install","uninstall"]);function fo(e){if(e.some(s=>s==="--version"||s==="--help"||s==="-v"||s==="-h"))return!1;let n=e.filter(s=>!s.startsWith("-"))[0];return n===void 0?!0:Ll.has(n)?!1:n==="sync"?!e.includes("--background"):Nn.existsSync(Qe.resolve(n))||/^[.~]|[\\/]/.test(n)}function In(e,t=process.cwd()){let n=e.filter(s=>!s.startsWith("-"));return n[0]==="sync"?Qe.resolve(n[1]??t):Qe.resolve(n[0]??t)}var Pl=/heap out of memory|Allocation failed|JavaScript heap|FatalProcessOutOfMemory|out of memory/i;function Ml({code:e,signal:t,stderrTail:n="",platform:s=process.platform}){if(Pl.test(n))return{kind:"memory",why:"Node reported that it ran out of memory"};if(t==="SIGINT"||t==="SIGTERM"||t==="SIGHUP")return null;if(t==="SIGABRT")return{kind:"memory",why:"the process aborted (usually out of memory)"};if(t==="SIGKILL")return{kind:"killed",why:"the system stopped the process (usually because the computer ran out of memory)"};if(t==="SIGSEGV"||t==="SIGBUS")return{kind:"crash",why:"the process crashed"};if(e==null)return t?{kind:"crash",why:`the process ended on signal ${t}`}:{kind:"crash",why:"the process ended without an exit code"};let o=e>>>0;if(s==="win32"){if(o>=3221225472)return{kind:o===3221226505?"memory":"crash",why:`Windows reported error 0x${o.toString(16).toUpperCase()} (a fatal stop, usually out of memory)`};if(o>255)return{kind:"crash",why:`the process ended with the unusual code ${o}`}}return e===134?{kind:"memory",why:"the process aborted (exit code 134, usually out of memory)"}:e===137?{kind:"killed",why:"the system stopped the process (exit code 137, usually out of memory)"}:e===139||e===135?{kind:"crash",why:`the process crashed (exit code ${e})`}:null}function Ol(e,{projectRoot:t,stage:n,memory:s}){let o=[],r=e.kind==="memory"?"Canopy ran out of memory":e.kind==="killed"?"Canopy was stopped by the system, most likely because the computer ran out of memory":"Canopy stopped unexpectedly";return o.push(`${r}${n?` while it was working on: ${n}`:""}.`),o.push(` (${e.why}.)`),o.push(""),o.push("What to try next:"),o.push(" 1. Analyse one part of the project at a time: canopy <folder of a package or app>"),o.push(` 2. Give Canopy more memory: set CANOPY_MAX_MEMORY_MB (it used ${s?.mb??s?.userMb??"the default"} MB), for example CANOPY_MAX_MEMORY_MB=${Math.min(16384,Math.max(4096,(s?.mb??4096)*2))} canopy`),o.push(" 3. Close other programs, then run it again: the files already read are remembered, so the second run is faster."),t&&o.push("",`Details for a bug report (no code or secrets): ${Qe.join(".canopy","last-error.txt")} in the project folder.`),o.join(`
|
|
93
|
+
`)}function uo(e,{version:t,stage:n,code:s,signal:o,memory:r,totalmem:i=Si.totalmem()}){try{let c=Qe.join(e,".canopy");Nn.mkdirSync(c,{recursive:!0});let a=[`time: ${new Date().toISOString()}`,`engine version: ${t}`,`stage: ${n??"unknown"}`,`exit: ${o?"signal "+o:s}`,`memory ceiling: ${r?.mb??"left to NODE_OPTIONS"+(r?.userMb?" ("+r.userMb+" MB)":"")} MB (${r?.source??"?"}); computer memory ${Math.round(i/bi)} MB`,""].join(`
|
|
94
|
+
`);return Nn.writeFileSync(Qe.join(c,"last-error.txt"),a),Qe.join(c,"last-error.txt")}catch{return null}}function $i(e){let{args:t,scriptPath:n,version:s="?",env:o=process.env,projectRoot:r=In(t),execPath:i=process.execPath,execArgv:c=process.execArgv,spawnFn:a=El,platform:l=process.platform,err:f=process.stderr,onChild:y=null}=e,u=e.memory??_l({env:o}),v=[...u.mb?[`--max-old-space-size=${u.mb}`]:[],...c.filter(p=>!p.startsWith("--max-old-space-size")),n,...t];return new Promise(p=>{let w="",I=a(i,v,{env:{...o,[Mt]:"1"},stdio:["inherit","inherit","pipe"],windowsHide:!1});y?.(I),I.stderr?.on("data",d=>{try{f.write(d)}catch{}w=(w+d.toString("utf8")).slice(-4e3)});let g=d=>()=>{try{I.kill(d)}catch{}},b=g("SIGTERM");process.on("SIGTERM",b);let $=process.stdin.isTTY?()=>{}:g("SIGINT");process.on("SIGINT",$);let S=!1,m=(d,k)=>{if(S)return;S=!0,process.off("SIGTERM",b),process.off("SIGINT",$);let h=Ml({code:d,signal:k,stderrTail:w,platform:l});if(!h){p(d??(k?1:0));return}let x=Qr(r);uo(r,{version:s,stage:x,code:d,signal:k,memory:u});try{Nn.rmSync(Qe.join(r,".canopy","last-stage.txt"),{force:!0})}catch{}try{f.write(`
|
|
95
|
+
`+Ol(h,{projectRoot:r,stage:x,memory:u})+`
|
|
96
96
|
`)}catch{}p(1)};I.on("error",d=>{try{f.write(`Canopy could not start its worker process: ${String(d.message).split(`
|
|
97
97
|
`)[0]}
|
|
98
|
-
`)}catch{}m(1,null)}),I.on("close",(d,k)=>m(d,k))})}var
|
|
98
|
+
`)}catch{}m(1,null)}),I.on("close",(d,k)=>m(d,k))})}var ke=JSON.parse(jn.readFileSync(St.join(Te,"package.json"),"utf8")),Al={"-y":"--yes","-h":"--help","-v":"--version"},Ni=process.argv.slice(2).map(e=>Al[e]??e),X=Object.fromEntries(Ni.filter(e=>e.startsWith("--")).map(e=>{let[t,n]=e.slice(2).split("=");return[t,n??!0]})),Ee=Ni.filter(e=>!e.startsWith("--")),de=Ee.shift(),Fl=e=>/^v?\d+$/.test(e??""),Pe=()=>St.resolve(Ee[0]&&!Fl(Ee[0])?Ee.shift():process.cwd()),Ii=`canopy ${ke.version} - a map of what your JavaScript / TypeScript code does
|
|
99
99
|
|
|
100
100
|
usage: canopy [path] [-y] [--no-open] do everything in order: check this computer, look at the project, prepare .canopy/,
|
|
101
101
|
offer the commit hook, build the map, open it in your browser (default path: current folder)
|
|
@@ -111,7 +111,7 @@ usage: canopy [path] [-y] [--no-open] do everything in order: check this com
|
|
|
111
111
|
telemetry on|off|status|show anonymous, opt-in usage counts (nothing is sent unless you say yes); "show" prints exactly what would be sent
|
|
112
112
|
mcp [path] a read-only MCP server (stdio) that lets your own AI tool search and read the map; Canopy never calls an AI service
|
|
113
113
|
install [path] [--yes] connect Claude Code / Cursor / Gemini CLI to it: shows the project files it will write, then asks [Y/n]; "uninstall" removes them
|
|
114
|
-
update [--check]
|
|
114
|
+
update [--check] [--yes] look up the newest version on npm; "update" asks, then installs it with npm. A one-line notice appears when a newer version is known (CANOPY_NO_UPDATE_CHECK=1 turns it off)
|
|
115
115
|
--version, --help
|
|
116
116
|
|
|
117
117
|
options for the one-command path: -y / --yes (do not ask; install the hook), --no-hook (do not install the hook, do not ask),
|
|
@@ -119,11 +119,11 @@ options for the one-command path: -y / --yes (do not ask; install the hook), --n
|
|
|
119
119
|
--full (ignore everything remembered and analyse from scratch), --quiet (only problems and the address), --no-color (also: NO_COLOR=1)
|
|
120
120
|
Memory: a whole analysis gets about 75% of this computer's memory (2-8 GB). CANOPY_MAX_MEMORY_MB=<number> sets it; CANOPY_DEBUG_MEM=1 prints the memory at each stage.
|
|
121
121
|
Exit codes: 0 ok, 1 a problem (the message says what to do), 3 no JavaScript / TypeScript files found.
|
|
122
|
-
Node >= 18 required. Output lives in <path>/.canopy/ (kept out of git automatically).`;async function
|
|
123
|
-
fix: canopy sync "${e}"`),process.exit(1));let{startViewer:n,viewerProblem:s}=await import("./chunk-
|
|
122
|
+
Node >= 18 required. Output lives in <path>/.canopy/ (kept out of git automatically).`;async function Bl(){let e=Pe(),t=Be(e);jn.existsSync(St.join(t,"workflows.js"))||(console.error(`no map yet for ${e}
|
|
123
|
+
fix: canopy sync "${e}"`),process.exit(1));let{startViewer:n,viewerProblem:s}=await import("./chunk-T3YCNXUR.js"),o=s();o&&(console.error(o),process.exit(1));let r=await kn(e,ke.version);if(!r.ok&&r.running){console.log(`canopy map for ${e}
|
|
124
124
|
${r.running.url}
|
|
125
|
-
already running for this project (started ${r.running.startedAt??"earlier"}); nothing else was started`);return}r.ok||(console.error("another canopy is just starting for this project; wait a few seconds and try again"),process.exit(1));let{server:i,url:c,port:a,navToken:l}=await n(t,
|
|
126
|
-
${c}`),
|
|
125
|
+
already running for this project (started ${r.running.startedAt??"earlier"}); nothing else was started`);return}r.ok||(console.error("another canopy is just starting for this project; wait a few seconds and try again"),process.exit(1));let{server:i,url:c,port:a,navToken:l}=await n(t,X.port?Number(X.port):0,{repoRoot:e});if(Sn(e,{port:a,version:ke.version,navToken:l}),console.log(`canopy map for ${e}
|
|
126
|
+
${c}`),X.for){console.log(`serving for ${Number(X.for)} s`),await new Promise(f=>setTimeout(f,Number(X.for)*1e3)),i.close();return}console.log("press Ctrl+C to stop"),await new Promise(()=>{})}async function ji(e){try{let{describeClaude:t}=await import("./chunk-HDMHITMG.js");return await t(e)}catch{return"Ask AI: Claude Code could not be checked."}}async function Hl(){let e=Pe(),t=mi(xn(e),e,ke.version);console.log(await ji(e)),process.exit(t?1:0)}var bt={async sync(){let e=Pe();if(X.background){let s=ui(e);s?console.log(`sync started in the background (pid ${s}); log: .canopy/sync.log`):console.error(`not a directory, nothing to sync: ${e}`);return}let t=X.keep?Number(X.keep):Ht,n=await yn(e,{keep:t,full:!!X.full});!X.quiet&&n?.status!=="queued"&&console.log(Jo({version:ke.version})),await ze().flush()},open:Bl,async doctor(){await Hl()},async ai(){console.log(await ji(Pe()))},async telemetry(){let e=Ee.shift()??"status",t=ze({version:ke.version});if(e==="on")t.setConsent(!0),console.log(t.configured?"Anonymous usage counts are ON. Turn them off any time with: canopy telemetry off":"Saved as ON, but this build has no usage-statistics address, so nothing is sent.");else if(e==="off")t.setConsent(!1),console.log("Anonymous usage counts are OFF. The random install id was deleted.");else if(e==="show"){let n=t.show();console.log(`What would be sent for one event (the API key is not shown):
|
|
127
127
|
`+JSON.stringify(n.sample,null,2)+`
|
|
128
128
|
|
|
129
129
|
Everything that can ever be sent (any other key is dropped; values are fixed words or whole numbers):
|
|
@@ -131,15 +131,16 @@ Everything that can ever be sent (any other key is dropped; values are fixed wor
|
|
|
131
131
|
`)+`
|
|
132
132
|
|
|
133
133
|
Never sent: code, file paths, project / function / workflow names, search text, AI questions or answers, environment values, host names. No IP address is stored.`)}else if(e==="status"){let n=t.status();console.log(`Usage counts: ${n.active?"ON (sending)":n.choice==="on"?"ON, but not sending":n.choice==="off"?"OFF":"not chosen yet"}${n.hardOff?` (forced off: ${n.hardOff})`:""}${n.configured?"":" (this build has no usage-statistics address: dormant)"}
|
|
134
|
-
Choice file: ${n.file}
|
|
135
|
-
|
|
136
|
-
|
|
134
|
+
Choice file: ${n.file}${t.choice().telemetry==="on"&&t.choice().installId?`
|
|
135
|
+
Install ID: ${t.choice().installId} (give this to canopy.spillitlabs@gmail.com to have your install's statistics deleted)`:""}`)}else console.error("usage: canopy telemetry on|off|status|show"),process.exit(2)},async mcp(){let e=Pe(),{runMcp:t}=await import("./chunk-TV6NLY7O.js");await t({repoRoot:e,outDir:Be(e),version:ke.version,aiPanel:!!X["ai-panel"]})},async install(){let{installCommand:e}=await import("./chunk-U6RT2XM5.js");process.exit(await e(Pe(),{yes:!!X.yes}))},async uninstall(){let{uninstallCommand:e}=await import("./chunk-U6RT2XM5.js");process.exit(await e(Pe()))},async update(){process.exit(await Qo({check:!!X.check,yes:!!X.yes||!(process.stdin.isTTY&&process.stdout.isTTY),version:ke.version}))},async diff(){let e=Pe(),t=ot(e);if(t.versions.length<2){console.log(t.versions.length?"only one version so far - nothing to diff yet":"no versions yet - run: canopy sync");return}let n=i=>{let c=Number(String(i).replace(/^v/,"")),a=t.versions.find(l=>l.version===c);if(!a)throw new Error(`no such version: ${i} (have ${t.versions.map(l=>"v"+l.version).join(", ")})`);return a},s=Ee[1]!==void 0?n(Ee[1]):t.versions[t.versions.length-1],o=Ee[0]!==void 0?n(Ee[0]):t.versions[t.versions.indexOf(s)-1];if(!o)throw new Error("no earlier version to compare against");let r=Wo(Cn(e,o),Cn(e,s));console.log(X.json?Uo(r):qo(r,s,o))},async"install-hook"(){let e=Pe(),t=Pt(e);$n(e,{hook:void 0}),console.log("installed canopy block in: "+t.join(", "))},async"uninstall-hook"(){let e=fi(Pe());console.log(e.length?"removed canopy block from: "+e.join(", "):"no canopy hook block found")},async hook(){let e=Ee.shift();if(e==="install")return bt["install-hook"]();if(e==="uninstall")return bt["uninstall-hook"]();console.error("usage: canopy hook install|uninstall [path]"),process.exit(2)},async history(){let e=Pe(),t=ot(e);if(!t.versions.length)return console.log("no versions yet - run: canopy sync");for(let n of t.versions)console.log(`v${n.version} ${n.fingerprint.slice(0,7)} ${n.createdAt} ${n.headSha?n.headSha.slice(0,7):"-------"}${n.dirty?"*":" "} ${n.headMessage?JSON.stringify(n.headMessage):""} nodes ${n.counts.nodes} edges ${n.counts.edges} workflows ${n.counts.workflows} ${(n.bytes/1024).toFixed(0)} KB${n.gzip?" gz":""}`)}};Number(process.versions.node.split(".")[0])<18&&(console.error(`Canopy needs Node 18 or newer, and this is Node ${process.versions.node}.
|
|
136
|
+
What to try next: install the current LTS from https://nodejs.org (or run: nvm install --lts), open a new terminal, and run canopy again.`),process.exit(1));if(process.env[Mt]!=="1"&&!Vo({cmd:de,quiet:!!X.quiet})){try{let e=Ko(ke.version);e&&console.error(e)}catch{}Xo()}if(process.env[Mt]!=="1"&&!X.help&&!X.version&&(de===void 0||de==="sync"||de==="open"||!bt[de]&&(jn.existsSync(St.resolve(de))||/^[.~]|[\\/]/.test(de)))){let e=ze({version:ke.version});if(e.shouldAsk({isTTY:!!(process.stdin.isTTY&&process.stdout.isTTY),quiet:!!X.quiet,background:!!X.background})){let t=Tl.createInterface({input:process.stdin,output:process.stdout}),n=await new Promise(s=>t.question("Help improve Canopy? Share anonymous usage counts (no code, no file or project names, no questions). You can change this any time with `canopy telemetry off`. [y/N] ",s));t.close(),e.setConsent(/^\s*y(es)?\s*$/i.test(String(n)))}}process.env[Mt]!=="1"&&process.env.CANOPY_NO_RESPAWN!=="1"&&fo(process.argv.slice(2))&&process.exit(await $i({args:process.argv.slice(2),scriptPath:process.argv[1],version:ke.version}));var Ei=e=>{let t=String(e?.message??e).split(`
|
|
137
|
+
`)[0].slice(0,200),n=In(process.argv.slice(2));uo(n,{version:ke.version,stage:gn(),code:1,memory:{mb:null,source:"this run"}}),console.error(`Canopy stopped unexpectedly${gn()?" while it was working on: "+gn():""}.
|
|
137
138
|
(${t})
|
|
138
139
|
|
|
139
140
|
What to try next:
|
|
140
141
|
1. canopy doctor checks Node, the grammars and write access
|
|
141
142
|
2. canopy <folder> try one package or app at a time
|
|
142
143
|
3. run it again: the files already read are remembered
|
|
143
|
-
Details for a bug report (no code or secrets): .canopy/last-error.txt in the project folder.`);let s=ze({version:
|
|
144
|
+
Details for a bug report (no code or secrets): .canopy/last-error.txt in the project folder.`);let s=ze({version:ke.version});s.record("error",{error_code:"other"}),Promise.race([s.flush(),new Promise(o=>setTimeout(o,2200))]).finally(()=>process.exit(1))};process.on("uncaughtException",Ei);process.on("unhandledRejection",Ei);fo(process.argv.slice(2))&&Xr(In(process.argv.slice(2)));process.on("exit",()=>Zr());for(let[e,t]of[["SIGINT",130],["SIGTERM",143]])process.once(e,()=>{let n=()=>process.exit(t);try{setTimeout(n,1e3),Promise.resolve().then(()=>ze().flush()).catch(()=>{}).finally(n)}catch{n()}});(X.version||de==="version")&&(console.log(Zo(ke.version)),process.exit(0));(X.help||de==="help")&&(console.log(Ii),process.exit(0));if(de===void 0||!bt[de]&&(jn.existsSync(St.resolve(de))||/^[.~]|[\\/]/.test(de))){de!==void 0&&Ee.unshift(de);let e=await ki({target:Ee[0]?St.resolve(Ee[0]):process.cwd(),yes:!!X.yes,noOpen:!!X["no-open"],quiet:!!X.quiet,noColor:!!X["no-color"],noHook:!!X["no-hook"],full:!!X.full,port:X.port?Number(X.port):void 0,forSeconds:X.for?Number(X.for):void 0,pkg:ke});await ze().flush(),process.exit(e)}bt[de]||(console.error(`unknown command: ${de}
|
|
144
145
|
|
|
145
|
-
${
|
|
146
|
+
${Ii}`),process.exit(2));bt[de]().catch(e=>{console.error(e.stack||e.message),process.exit(1)});
|