@wtdlee/repomap 0.5.0 → 0.6.0

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.
@@ -1,5 +1,5 @@
1
- import { B as BaseAnalyzer } from '../dataflow-analyzer-mlxaq5qn.js';
2
- export { D as DataFlowAnalyzer, G as GraphQLAnalyzer, P as PagesAnalyzer } from '../dataflow-analyzer-mlxaq5qn.js';
1
+ import { B as BaseAnalyzer } from '../dataflow-analyzer-s6ufFkKC.js';
2
+ export { D as DataFlowAnalyzer, G as GraphQLAnalyzer, P as PagesAnalyzer } from '../dataflow-analyzer-s6ufFkKC.js';
3
3
  import { RepositoryConfig, AnalysisResult } from '../types.js';
4
4
 
5
5
  /**
@@ -1 +1 @@
1
- export{a as BaseAnalyzer,d as DataFlowAnalyzer,c as GraphQLAnalyzer,b as PagesAnalyzer,e as RestApiAnalyzer}from'../chunk-WJIBUCXB.js';
1
+ export{a as BaseAnalyzer,d as DataFlowAnalyzer,c as GraphQLAnalyzer,b as PagesAnalyzer,e as RestApiAnalyzer}from'../chunk-BPV4UZSW.js';
@@ -0,0 +1,2 @@
1
+ import {Project,Node,SyntaxKind}from'ts-morph';import k from'fast-glob';import*as N from'path';import*as w from'fs';import {existsSync}from'fs';import*as O from'fs/promises';import {parse}from'graphql';import {parseSync}from'@swc/core';var T=class{config;basePath;constructor(e){this.config=e,this.basePath=e.path;}resolvePath(e){return `${this.basePath}/${e}`}getSetting(e,t=""){return this.config.settings[e]??t}log(e){console.log(`[${this.getName()}] ${e}`);}warn(e){console.warn(`[${this.getName()}] \u26A0\uFE0F ${e}`);}error(e,t){console.error(`[${this.getName()}] \u274C ${e}`,t?.message||"");}};async function M(F,e,t=8){let n=new Array(F.length).fill(null),i=0;async function o(){for(;i<F.length;){let s=i++;if(s<F.length)try{n[s]=await e(F[s],s);}catch{n[s]=null;}}}let a=Array(Math.min(t,F.length)).fill(null).map(()=>o());return await Promise.all(a),n.filter(s=>s!==null)}var q=class extends T{project;codegenMap=new Map;constructor(e){super(e);let t=this.resolvePath("tsconfig.json"),n=w.existsSync(t);this.project=new Project({...n?{tsConfigFilePath:t}:{},skipAddingFilesFromTsConfig:true,compilerOptions:n?void 0:{allowJs:true,jsx:2}});}extractOperationNameFromGql(e){let t=e.match(/(?:query|mutation|subscription)\s+(\w+)/);if(t&&t[1])return t[1];let n=e.match(/`\s*(?:query|mutation|subscription)\s+(\w+)/);if(n&&n[1])return n[1];let i=e.match(/GraphQL[^`]*`\s*(?:\n\s*)?(?:query|mutation|subscription)\s+(\w+)/);return i&&i[1]?i[1]:null}findOperationNameFromVariable(e,t){let n=e.getVariableDeclaration(t);if(!n){let s=e.getExportedDeclarations().get(t);if(s&&s.length>0){let r=s[0];Node.isVariableDeclaration(r)&&(n=r);}}if(n||(n=e.getVariableDeclarations().find(s=>s.getName()===t)),!n){let a=e.getFullText(),s=[new RegExp(`(?:const|let|var)\\s+${t}\\s*=\\s*gql\\s*\\(\\s*/\\*[^*]*\\*/\\s*\`\\s*(?:query|mutation|subscription)\\s+(\\w+)`,"s"),new RegExp(`(?:const|let|var)\\s+${t}\\s*=\\s*gql\`\\s*(?:query|mutation|subscription)\\s+(\\w+)`,"s"),new RegExp(`(?:const|let|var)\\s+${t}\\s*=\\s*gql\\s*\\(\`\\s*(?:query|mutation|subscription)\\s+(\\w+)`,"s"),new RegExp(`(?:const|let|var)\\s+${t}\\s*=\\s*graphql\\s*\\(\`\\s*(?:query|mutation|subscription)\\s+(\\w+)`,"s")];for(let r of s){let c=a.match(r);if(c&&c[1])return c[1]}return null}let i=n.getInitializer();if(!i)return null;let o=i.getText();return this.extractOperationNameFromGql(o)}getName(){return "PagesAnalyzer"}async analyze(){this.log("Starting page analysis..."),await this.loadCodegenMapping(),await this.analyzeAppFile();let e=await this.findPageFiles();this.log(`Found ${e.length} page files`);for(let i of e)try{this.project.addSourceFileAtPath(i);}catch{}let n=(await M(e,async i=>{let o=this.detectPagesRoot(i);return this.analyzePageFile(i,o)},4)).filter(i=>i!==null);return this.log(`Analyzed ${n.length} pages successfully`),{pages:n}}async analyzePageFile(e,t){let n=this.project.getSourceFile(e);if(!n)return null;let i=N.relative(t,e),o=this.filePathToRoutePath(i),a=this.findPageComponent(n);if(!a)return null;let s=this.extractRouteParams(o),r=this.extractLayout(n),c=this.extractAuthRequirement(n),l=this.extractPermissions(n),f=this.extractDataFetching(n),u=this.extractNavigation(n),g=this.extractLinkedPages(n),y=this.extractSteps(n);return {path:o,filePath:i,component:a,params:s,layout:r,authentication:c,permissions:l,dataFetching:f,navigation:u,linkedPages:g,steps:y.length>0?y:void 0}}detectPagesRoot(e){let t=["/src/pages/","/pages/","/src/app/","/app/","/frontend/src/pages/","/app/javascript/pages/"];for(let n of t){let i=e.indexOf(n);if(i!==-1)return e.substring(0,i+n.length-1)}return this.basePath}filePathToRoutePath(e){return "/"+e.replace(/\.tsx?$/,"").replace(/\/index$/,"").replace(/\[\.\.\.(\w+)\]/g,"*").replace(/\[(\w+)\]/g,":$1")}extractRouteParams(e){let t=[],n=/:(\w+)/g,i;for(;(i=n.exec(e))!==null;)t.push(i[1]);return t}findPageComponent(e){let t=e.getDefaultExportSymbol();if(t){let s=t.getName();if(s!=="default")return s}let n=e.getExportAssignment(s=>!s.isExportEquals());if(n){let s=n.getExpression();if(s){let r=s.getText();if(/^[A-Z][a-zA-Z0-9]*$/.test(r))return r;if(Node.isFunctionExpression(s)||Node.isArrowFunction(s))return "default"}}let i=e.getFunctions();for(let s of i)if(s.isDefaultExport())return s.getName()||"default";if(e.getVariableDeclaration("Page"))return "Page";let a=e.getVariableDeclarations();for(let s of a){let r=s.getTypeNode();if(r){let c=r.getText();if(c.includes("NextPage")||c.includes("FC")||c.includes("React.FC"))return s.getName()}}for(let s of a){let r=s.getName();if(/^[A-Z][a-zA-Z0-9]*$/.test(r)){let c=s.getInitializer();if(c&&(Node.isArrowFunction(c)||Node.isFunctionExpression(c))){let l=c.getText();if(l.includes("return")&&(l.includes("<")||l.includes("jsx")))return r}}}return null}extractLayout(e){let t=e.getDescendantsOfKind(SyntaxKind.PropertyAccessExpression).find(n=>n.getName()==="getLayout");if(t){let n=t.getParent();if(Node.isBinaryExpression(n)){let o=n.getRight().getDescendantsOfKind(SyntaxKind.JsxOpeningElement);if(o.length>0)return o[0].getTagNameNode().getText()}}}extractAuthRequirement(e){let n=e.getFilePath().split("/").pop()||"",a={required:!["404.tsx","permission-denied.tsx","_app.tsx","_document.tsx","_error.tsx"].some(s=>n===s)};try{let s=["RequiredCondition","ProtectedRoute","AuthGuard","PrivateRoute","WithAuth","RequireAuth","Authenticated","Authorized"],r=e.getDescendantsOfKind(SyntaxKind.JsxOpeningElement).find(c=>{let l=c.getTagNameNode().getText();return s.some(f=>l.includes(f))});if(r){a.condition="Additional permissions required";let c=r.getAttributes();for(let l of c)if(l.isKind(SyntaxKind.JsxAttribute))try{let f=l.getNameNode().getText();if(["condition","roles","permissions","requiredRoles","allowedRoles"].includes(f)){let u=l.getInitializer();if(u){a.condition=u.getText();let g=this.extractRolesFromCondition(u.getText());g.length>0&&(a.roles=g);}}}catch{}}}catch{}return a}extractRolesFromCondition(e){let t=[],n=/(\w+Role|\w+Permission)\.(\w+)/g,i;for(;(i=n.exec(e))!==null;)t.push(i[2]);let o=/['"]([a-zA-Z_-]+)['"]/g;for(;(i=o.exec(e))!==null;){let s=i[1];/admin|user|owner|member|guest|manager|editor|viewer/i.test(s)&&t.push(s);}let a=/\b(ROLE_\w+|[A-Z]+_ROLE)\b/g;for(;(i=a.exec(e))!==null;)t.push(i[1]);return [...new Set(t)]}extractPermissions(e){let t=[],n=e.getDescendantsOfKind(SyntaxKind.PropertyAccessExpression).filter(i=>{let o=i.getText();return o.includes("Permission")||o.includes("Role")||o.includes("isAdmin")});for(let i of n){let o=i.getText();t.includes(o)||t.push(o);}return t}extractDataFetching(e){let t=[],n=new Map,i=["useQuery","useMutation","useLazyQuery","useSubscription"];for(let x of e.getImportDeclarations()){let p=x.getModuleSpecifierValue();if(p.includes("@apollo/client")||p.includes("apollo"))for(let m of x.getNamedImports()){let d=m.getName(),h=m.getAliasNode()?.getText()||d;i.includes(d)&&n.set(h,d);}}let o=n.size>0||e.getImportDeclarations().some(x=>{let p=x.getModuleSpecifierValue();return p.includes("@apollo/client")||p.includes("apollo")}),a=e.getDescendantsOfKind(SyntaxKind.CallExpression).filter(x=>{let p=x.getExpression().getText();return !!(n.has(p)||i.includes(p)||/^use[A-Z].*Query$/.test(p)&&!p.includes("Params")&&!p.includes("String")||/^use[A-Z].*Mutation$/.test(p))});for(let x of a){let p=x.getExpression().getText(),m;n.has(p)?m=n.get(p):p.includes("Mutation")?m="useMutation":p.includes("Lazy")?m="useLazyQuery":m="useQuery";let d=x.getArguments();if(d.length===0){if(/^use[A-Z]/.test(p)){let b=p.replace(/^use/,"").replace(/Query$|Mutation$/,"");t.push({type:m,operationName:b,variables:[]});}continue}let P=d[0].getText();if(P.startsWith("[")||P.startsWith("{")||P.startsWith("'")||P.startsWith('"')||P.startsWith("`")||!(o||P.endsWith("Document")||P.endsWith("Query")||P.endsWith("Mutation")||P.includes("gql")||/^[A-Z_]+$/.test(P)))continue;let v=P.replace(/Document$/,"").replace(/Query$|Mutation$/,""),C=[];if(d.length>1){let I=d[1].getDescendantsOfKind(SyntaxKind.PropertyAssignment).find(D=>{try{return D.getName()==="variables"}catch{return false}});if(I){let D=I.getInitializer();if(D){let Q=D.getDescendantsOfKind(SyntaxKind.PropertyAssignment);for(let H of Q)try{C.push(H.getName());}catch{}}}}t.push({type:m,operationName:v,variables:C});}let s=e.getVariableDeclaration("getServerSideProps"),r=e.getFunction("getServerSideProps"),c=s||r;if(c){let x=e.getImportDeclarations();for(let d of x){let h=d.getNamedImports();for(let P of h){let S=P.getName();if(S.endsWith("Document")&&e.getDescendantsOfKind(SyntaxKind.Identifier).filter(C=>C.getText()===S).length>0){let C=S.replace(/Document$/,"");t.push({type:"getServerSideProps",operationName:`\u2192 ${C}`});}}}let m=c.getText().match(/query:\s*(\w+)/g);if(m)for(let d of m){let h=d.replace(/query:\s*/,"");t.some(P=>P.operationName?.includes(h.replace(/Document$/,"")))||t.push({type:"getServerSideProps",operationName:`\u2192 ${h.replace(/Document$/,"")}`});}}let l=e.getVariableDeclaration("getStaticProps"),f=e.getFunction("getStaticProps");(l||f)&&t.push({type:"getStaticProps",operationName:"getStaticProps"});let u=e.getImportDeclarations(),g=e.getFilePath(),y=N.dirname(g);for(let x of u){let p=x.getModuleSpecifierValue(),m=p.startsWith(".")||p.startsWith("/"),d=!p.includes("node_modules")&&!p.startsWith("@types/")&&p.startsWith("@")===false;if(m||d){if(p.includes("__generated__")||p.includes("/generated/"))continue;let h=[],P=x.getNamedImports();for(let v of P){let C=v.getName();this.isComponentName(C)&&h.push(C);}let S=x.getDefaultImport();if(S){let v=S.getText();this.isComponentName(v)&&h.push(v);}for(let v of h){let C=this.analyzeImportedComponent(y,p,v);if(C.length>0)for(let b of C)t.push({type:b.type,operationName:b.operationName.startsWith("\u2192")?`\u2192 ${b.operationName} (${v})`:`\u2192 ${b.operationName} (${v})`,variables:b.variables});else t.push({type:"component",operationName:v,variables:[]});}}}return t}symbolTraceCache=new Map;analyzeImportedComponent(e,t,n,i=new Set,o=0){if(o>10)return [];let s=[];try{let r=N.resolve(e,t),c=`${r}:${n}`;if(i.has(c))return [];i.add(c);let l=this.symbolTraceCache.get(c);if(l!==void 0)return l;let f=[`${r}.tsx`,`${r}.ts`,`${r}/index.tsx`,`${r}/index.ts`,`${r}/${n}.tsx`,`${r}/${n}.ts`],u,g;for(let p of f)try{if(u=this.project.addSourceFileAtPath(p),u){g=p;break}}catch{}if(!u||!g)return s;if(g.endsWith("index.tsx")||g.endsWith("index.ts")){let p=this.followReExport(u,n,N.dirname(g));p&&(u=p);}let y=u.getImportDeclarations().some(p=>{let m=p.getModuleSpecifierValue();return m.includes("@apollo/client")||m.includes("apollo")||m.includes("gql")||m.includes("graphql")||m.includes("__generated__")}),x=u.getImportDeclarations().filter(p=>{let m=p.getModuleSpecifierValue();return m.startsWith("./")||m.startsWith("../")});for(let p of x){let m=p.getModuleSpecifierValue(),d=p.getNamedImports().map(h=>h.getName()).filter(h=>/^use[A-Z]/.test(h));for(let h of d){let P=this.analyzeCustomHook(N.dirname(u.getFilePath()),m,h,i,o+1);s.push(...P);}}for(let p of x){let m=p.getModuleSpecifierValue(),d=p.getNamedImports().map(S=>S.getName()),h=p.getDefaultImport()?.getText(),P=d.filter(S=>/^[A-Z]/.test(S)&&this.isComponentName(S));for(let S of P){let v=this.analyzeImportedComponent(N.dirname(u.getFilePath()),m,S,i,o+1);s.push(...v);}if(h&&/^[A-Z]/.test(h)&&this.isComponentName(h)){let S=this.analyzeImportedComponent(N.dirname(u.getFilePath()),m,h,i,o+1);s.push(...S);}}if(y){let p=u.getDescendantsOfKind(SyntaxKind.CallExpression).filter(m=>{let d=m.getExpression().getText();return ["useQuery","useMutation","useLazyQuery","useSubscription"].includes(d)});for(let m of p){let d=m.getExpression().getText(),h=m.getArguments();if(h.length===0)continue;let S=h[0].getText(),v=S,C=null,b=this.resolveDocumentName(S);if(b)v=b.operationName,C=b.operationType;else if(S.endsWith("Document"))v=S.replace(/Document$/,"");else if(/^[A-Za-z]/.test(S)){let D=this.findOperationNameFromVariable(u,S);if(D&&(v=D),v===S&&S!=="Query"&&S!=="Mutation"){let Q=S.match(/^(.+?)(Query|Mutation|Subscription)$/);Q&&(v=Q[1]);}}v!=="Query"&&v!=="Mutation"&&(v=v.replace(/Document$/,"").replace(/Query$|Mutation$/,"")||v),(v==="Query"||v==="Mutation"||v==="")&&v===""&&(v=S||"Unknown");let I=C?C==="mutation"?"useMutation":C==="subscription"?"useSubscription":d.includes("Lazy")?"useLazyQuery":"useQuery":d.includes("Mutation")?"useMutation":d.includes("Lazy")?"useLazyQuery":"useQuery";s.push({type:I,operationName:v,variables:[]});}}this.symbolTraceCache.set(c,s);}catch{}return s}analyzeCustomHook(e,t,n,i=new Set,o=0){if(o>10)return [];let s=[];try{let r=N.resolve(e,t),c=`hook:${r}:${n}`;if(i.has(c))return [];i.add(c);let l=this.symbolTraceCache.get(c);if(l!==void 0)return l;let f=[`${r}.tsx`,`${r}.ts`,`${r}/${n}.tsx`,`${r}/${n}.ts`,`${r}/index.tsx`,`${r}/index.ts`],u;for(let p of f)try{if(u=this.project.addSourceFileAtPath(p),u)break}catch{}if(!u)return s;let g=u.getImportDeclarations().some(p=>{let m=p.getModuleSpecifierValue();return m.includes("@apollo/client")||m.includes("apollo")||m.includes("graphql")||m.includes("__generated__")}),y=u.getImportDeclarations().filter(p=>{let m=p.getModuleSpecifierValue();return m.startsWith("./")||m.startsWith("../")});for(let p of y){let m=p.getModuleSpecifierValue(),d=p.getNamedImports().map(h=>h.getName()).filter(h=>/^use[A-Z]/.test(h));for(let h of d){let P=this.analyzeCustomHook(N.dirname(u.getFilePath()),m,h,i,o+1);s.push(...P);}}if(!g&&s.length===0)return s;let x=u.getDescendantsOfKind(SyntaxKind.CallExpression).filter(p=>{let m=p.getExpression().getText();return ["useQuery","useMutation","useLazyQuery","useSubscription"].includes(m)});for(let p of x){let m=p.getExpression().getText(),d=p.getArguments();if(d.length===0)continue;let h=d[0].getText(),P=h,S=null,v=this.resolveDocumentName(h);if(v)P=v.operationName,S=v.operationType;else if(h.endsWith("Document"))P=h.replace(/Document$/,"");else if(/^[A-Za-z]/.test(h)){let b=this.findOperationNameFromVariable(u,h);if(b&&(P=b),P===h&&h!=="Query"&&h!=="Mutation"){let I=h.match(/^(.+?)(Query|Mutation|Subscription)$/);I&&(P=I[1]);}}P!=="Query"&&P!=="Mutation"&&(P=P.replace(/Document$/,"").replace(/Query$|Mutation$/,"")||P),P===""&&(P=h||"Unknown");let C=S?S==="mutation"?"useMutation":S==="subscription"?"useSubscription":m.includes("Lazy")?"useLazyQuery":"useQuery":m.includes("Mutation")?"useMutation":m.includes("Lazy")?"useLazyQuery":"useQuery";s.push({type:C,operationName:`\u2192 ${P} (via ${n})`,variables:[]});}this.symbolTraceCache.set(c,s);}catch{}return s}globalContextQueries=[];async findPageFiles(){let e=this.getSetting("pagesDir","src/pages"),t=[],i=[...new Set([e,"pages","src/pages","app","src/app"])];for(let s of i){if(s==="app"||s==="src/app"){let c=["controllers","models","views","helpers"],l=this.resolvePath(s);if(c.some(u=>{try{return w.existsSync(N.join(l,u))}catch{return false}}))continue}let r=this.resolvePath(s);try{let c=await k(["**/*.tsx","**/*.ts","**/*.jsx","**/*.js"],{cwd:r,ignore:["_app.tsx","_app.ts","_app.jsx","_app.js","_document.tsx","_document.ts","_document.jsx","_document.js","_error.tsx","_error.ts","_error.jsx","_error.js","api/**","**/*.test.*","**/*.spec.*","**/node_modules/**","**/components/pages/**"],absolute:!0});t.push(...c),c.length>0&&this.log(`Found ${c.length} pages in ${s}`);}catch{}}let o=["frontend/src/**/pages","app/javascript/**/pages"];for(let s of o)try{let r=await k([`${s}/**/*.tsx`,`${s}/**/*.ts`,`${s}/**/*.jsx`,`${s}/**/*.js`],{cwd:this.basePath,ignore:["**/*.test.*","**/*.spec.*","**/node_modules/**","**/vendor/**","**/components/pages/**","**/stories/**"],absolute:!0});t.push(...r),r.length>0&&this.log(`Found ${r.length} React pages in ${s}`);}catch{}let a=["frontend/src/**/index.tsx","frontend/src/**/App.tsx","app/javascript/packs/*.tsx","app/javascript/packs/*.jsx"];for(let s of a)try{let r=await k([s],{cwd:this.basePath,ignore:["**/node_modules/**","**/vendor/**"],absolute:!0});for(let c of r)t.includes(c)||t.push(c);}catch{}if(t.length===0){let s=await this.findSPARoutes();s.length>0&&(this.log(`Found ${s.length} SPA routes from App.tsx`),t.push(...s));}return [...new Set(t)]}async findSPARoutes(){let e=[],t=["src/App.tsx","src/App.jsx","src/App.js","App.tsx","App.jsx","App.js"];for(let n of t){let i=this.resolvePath(n);if(w.existsSync(i))try{let o=w.readFileSync(i,"utf-8");if(!o.includes("react-router")&&!o.includes("Route"))continue;let a=/<(?:Route|PrivateRoute)[^>]*(?:component=\{([^}]+)\}|element=\{<([^>\s/]+)|path=["']([^"']+)["'])/g,s=/import\s+(\w+)\s+from\s+['"]([^'"]+)['"]/g,r=new Map,c;for(;(c=s.exec(o))!==null;)r.set(c[1],c[2]);let l,f=new Set;for(;(l=a.exec(o))!==null;){let u=l[1]||l[2];if(u&&!f.has(u)){f.add(u);let g=r.get(u);if(g){let y=this.resolveImportPath(N.dirname(i),g);y&&w.existsSync(y)&&e.push(y);}}}e.length>0&&e.push(i);}catch{}}return e}resolveImportPath(e,t){if(t.startsWith(".")){let n=[".tsx",".ts",".jsx",".js","/index.tsx","/index.ts","/index.jsx","/index.js"],i=N.resolve(e,t);for(let o of n){let a=i+o;if(w.existsSync(a))return a}if(w.existsSync(i)&&w.statSync(i).isDirectory())for(let o of ["/index.tsx","/index.ts","/index.jsx","/index.js"]){let a=i+o;if(w.existsSync(a))return a}}return null}async analyzeAppFile(){let e=this.getSetting("pagesDir","src/pages"),t=[this.resolvePath(`${e}/_app.tsx`),this.resolvePath(`${e}/_app.ts`)];for(let n of t)try{let i=this.project.addSourceFileAtPath(n);if(!i)continue;let o=i.getDescendantsOfKind(SyntaxKind.JsxElement),a=i.getDescendantsOfKind(SyntaxKind.JsxSelfClosingElement),s=new Set;for(let r of [...o,...a]){let c=r.getFirstDescendantByKind(SyntaxKind.Identifier)?.getText();c&&(c.includes("Provider")||c.includes("Context"))&&s.add(c);}for(let r of i.getImportDeclarations()){let c=r.getModuleSpecifierValue();if(!c.startsWith("./")&&!c.startsWith("../"))continue;let l=r.getNamedImports().map(u=>u.getName()),f=r.getDefaultImport()?.getText();for(let u of s)if(l.includes(u)||f===u){let g=this.analyzeImportedComponent(N.dirname(n),c,u,new Set,0);for(let y of g)this.globalContextQueries.push({...y,operationName:`[Global] ${y.operationName}`});}}this.globalContextQueries.length>0&&this.log(`Found ${this.globalContextQueries.length} global context queries from _app`);return}catch{}}async loadCodegenMapping(){let e=["__generated__","src/__generated__","src/__generated__/gql-graphql-gateway","generated","src/generated"];for(let t of e){let n=this.resolvePath(t);try{let i=await k(["**/*.ts","**/*.tsx"],{cwd:n,absolute:!0,onlyFiles:!0});for(let o of i)try{let a=this.project.addSourceFileAtPath(o),s=a.getVariableDeclarations();for(let c of s){let l=c.getName();if(l.endsWith("Document")){let f=c.getInitializer()?.getText()??"",u=f.match(/(?:query|mutation|subscription)\s+(\w+)/),g=f.match(/(query|mutation|subscription)\s+/);u&&this.codegenMap.set(l,{operationName:u[1],operationType:g?g[1]:"query"});}}let r=a.getTypeAliases();for(let c of r){let l=c.getName();if((l.endsWith("Query")||l.endsWith("Mutation")||l.endsWith("Subscription"))&&!l.endsWith("Variables")){let f=l+"Document";if(!this.codegenMap.has(f)){let u=l.endsWith("Mutation")?"mutation":l.endsWith("Subscription")?"subscription":"query";this.codegenMap.set(f,{operationName:l,operationType:u});}}}}catch{}if(this.codegenMap.size>0){this.log(`Loaded ${this.codegenMap.size} codegen mappings from ${t}`);return}}catch{}}}resolveDocumentName(e){if(new Set(["Query","Mutation","Subscription"]).has(e))return null;let n=this.codegenMap.get(e);if(n!==void 0)return n;let i=e.endsWith("Document")?e:e+"Document",o=this.codegenMap.get(i);return o!==void 0?o:null}followReExport(e,t,n){try{let i=e.getExportDeclarations(),o=null;for(let a of i){let s=a.getNamedExports();for(let r of s){let c=a.getModuleSpecifierValue();if(!c)continue;let l=N.resolve(n,c),f=[`${l}.tsx`,`${l}.ts`,`${l}/index.tsx`,`${l}/index.ts`],u;for(let g of f)try{if(u=this.project.addSourceFileAtPath(g),u)break}catch{}if(u&&(o||(o=u),r.getName()===t||r.getAliasNode()?.getText()===t))return u}}if(o)return o;for(let a of e.getExportDeclarations())if(a.isNamespaceExport()){let s=a.getModuleSpecifierValue();if(s){let r=N.resolve(n,s),c=[`${r}.tsx`,`${r}.ts`];for(let l of c)try{let f=this.project.addSourceFileAtPath(l);if(f&&f.getExportedDeclarations().has(t))return f}catch{}}}}catch{}return null}isComponentName(e){return !/^[A-Z]/.test(e)||e.endsWith("Query")||e.endsWith("Mutation")||e.endsWith("Subscription")||e.endsWith("Fragment")||e.endsWith("Document")||e.endsWith("Variables")||e==="Query"||e==="Mutation"||e==="Subscription"||new Set(["NextPage","NextPageContext","NextApiRequest","NextApiResponse","GetServerSideProps","GetStaticProps","GetStaticPaths","InferGetServerSidePropsType","InferGetStaticPropsType","FC","FunctionComponent","VFC","Component","PureComponent","ReactNode","ReactElement","PropsWithChildren","ComponentProps","ComponentType","ElementType","RefObject","MutableRefObject","Dispatch","SetStateAction","ChangeEvent","MouseEvent","KeyboardEvent","FormEvent","SyntheticEvent"]).has(e)?false:!!(["Container","Page","Screen","View","Form","Modal","Dialog","Panel","Root","Provider","Wrapper"].some(i=>e.endsWith(i))||/Page[A-Z]?\w*$/.test(e)||/Container[A-Z]?\w*$/.test(e)||/^[A-Z][a-z]+[A-Z][a-z]+/.test(e))}extractNavigation(e){let t={visible:true,currentNavItem:null};try{let n=e.getDescendantsOfKind(SyntaxKind.PropertyAccessExpression).find(i=>{try{return i.getName()==="globalNavigationStyle"}catch{return !1}});if(n){let i=n.getParent();if(Node.isBinaryExpression(i)){let o=i.getRight(),a=o.getDescendantsOfKind(SyntaxKind.PropertyAssignment).find(c=>{try{return c.getName()==="visible"}catch{return !1}});a&&(t.visible=a.getInitializer()?.getText()==="true");let s=o.getDescendantsOfKind(SyntaxKind.PropertyAssignment).find(c=>{try{return c.getName()==="currentNavItem"}catch{return !1}});if(s){let c=s.getInitializer()?.getText();t.currentNavItem=c&&c!=="null"?c.replace(/['"]/g,""):null;}let r=o.getDescendantsOfKind(SyntaxKind.PropertyAssignment).find(c=>{try{return c.getName()==="mini"}catch{return !1}});r&&(t.mini=r.getInitializer()?.getText()==="true");}}}catch{}return t}extractSteps(e){let t=[],n=e.getDescendantsOfKind(SyntaxKind.CallExpression).filter(a=>a.getExpression().getText()==="useState");for(let a of n){let s=a.getParent();if(!s)continue;let c=s.getText().match(/\[\s*(step|currentStep|activeStep|page|currentPage|phase|stage)\s*,/i);if(c){let l=c[1],f=e.getDescendantsOfKind(SyntaxKind.SwitchStatement);for(let g of f)g.getExpression().getText().includes(l)&&g.getClauses().forEach((p,m)=>{if(p.isKind(SyntaxKind.CaseClause)){let d=p.getExpression()?.getText()||String(m),h=p.getDescendantsOfKind(SyntaxKind.JsxOpeningElement),P=h.length>0?h[0].getTagNameNode().getText():void 0;t.push({id:d.replace(/['"]/g,""),name:`Step ${d.replace(/['"]/g,"")}`,component:P});}});let u=e.getDescendantsOfKind(SyntaxKind.ArrayLiteralExpression);for(let g of u){let y=g.getParent();y&&y.getText().match(/steps|pages|screens|views|components/i)&&g.getElements().forEach((p,m)=>{let d=p.getText();if(d.startsWith("{")){let h=d.match(/(?:name|label|title)\s*:\s*['"]([^'"]+)['"]/),P=d.match(/(?:component|content)\s*:\s*<?\s*(\w+)/);t.push({id:m+1,name:h?h[1]:`Step ${m+1}`,component:P?P[1]:void 0});}else /^[A-Z]/.test(d)&&t.push({id:m+1,name:d,component:d});});}}}let i=e.getDescendantsOfKind(SyntaxKind.JsxOpeningElement);for(let a of i)if(a.getTagNameNode().getText().match(/Stepper|Wizard|Steps|TabPanel|FormStep/i)){let r=a.getParent();r&&r.isKind(SyntaxKind.JsxElement)&&r.getJsxChildren().forEach((l,f)=>{if(l.isKind(SyntaxKind.JsxElement)||l.isKind(SyntaxKind.JsxSelfClosingElement)){let u=l.isKind(SyntaxKind.JsxElement)?l.getOpeningElement().getTagNameNode().getText():l.getTagNameNode().getText(),g=l.isKind(SyntaxKind.JsxElement)?l.getOpeningElement().getAttributes():l.getAttributes(),y=u;for(let x of g)if(x.isKind(SyntaxKind.JsxAttribute)){let p=x.getNameNode().getText();if(p==="label"||p==="title"||p==="name"){let m=x.getInitializer()?.getText();if(m){y=m.replace(/['"{}]/g,"");break}}}t.push({id:f+1,name:y,component:u});}});}let o=e.getDescendantsOfKind(SyntaxKind.ConditionalExpression);for(let a of o){let s=a.getCondition().getText();if(s.match(/step\s*===?\s*\d+|currentStep|activeStep/i)){let r=a.getWhenTrue(),c=s.match(/===?\s*(\d+)/);if(c&&t.length===0){let l=r.getDescendantsOfKind(SyntaxKind.JsxOpeningElement);l.length>0&&t.push({id:parseInt(c[1]),component:l[0].getTagNameNode().getText()});}}}return t}extractLinkedPages(e){let t=[],n=e.getDescendantsOfKind(SyntaxKind.CallExpression).filter(o=>{let a=o.getExpression().getText();return a.includes("router.push")||a.includes("router.replace")||a.includes("Link")});for(let o of n){let a=o.getArguments();if(a.length>0){let r=a[0].getText().match(/['"`]([^'"`]+)['"`]/);r&&!t.includes(r[1])&&t.push(r[1]);}}let i=e.getDescendantsOfKind(SyntaxKind.JsxOpeningElement).filter(o=>o.getTagNameNode().getText()==="Link");for(let o of i)try{let a=o.getAttributes();for(let s of a)if(s.isKind(SyntaxKind.JsxAttribute)&&s.getNameNode().getText()==="href"){let l=s.getInitializer()?.getText();if(l){let f=l.match(/['"`]([^'"`]+)['"`]/);f&&!t.includes(f[1])&&t.push(f[1]);}}}catch{}return t}};var G=class extends T{project;constructor(e){super(e);let t=this.resolvePath("tsconfig.json"),n=existsSync(t);this.project=new Project({...n?{tsConfigFilePath:t}:{},skipAddingFilesFromTsConfig:true,compilerOptions:n?void 0:{allowJs:true,jsx:2}});}getName(){return "GraphQLAnalyzer"}async analyze(){this.log("Starting GraphQL analysis...");let e=[];this.log("[GraphQLAnalyzer] Step 1: Analyzing .graphql files...");let t=await this.analyzeGraphQLFiles();e.push(...t),this.log(`[GraphQLAnalyzer] Step 1 done: ${t.length} from .graphql files`),this.log("[GraphQLAnalyzer] Step 2: Analyzing inline GraphQL...");let n=await this.analyzeInlineGraphQL();e.push(...n),this.log(`[GraphQLAnalyzer] Step 2 done: ${n.length} inline operations`),this.log("[GraphQLAnalyzer] Step 3: Analyzing codegen output...");let i=await this.analyzeCodegenGenerated();e.push(...i),this.log(`[GraphQLAnalyzer] Step 3 done: ${i.length} from codegen`);let o=this.deduplicateOperations(e);return this.log(`[GraphQLAnalyzer] Deduplicated: ${o.length} unique operations`),this.log("[GraphQLAnalyzer] Step 4: Finding operation usage..."),await this.findOperationUsage(o),this.log("[GraphQLAnalyzer] Step 4 done"),this.log(`Found ${o.length} GraphQL operations`),{graphqlOperations:o}}deduplicateOperations(e){let t=new Map;for(let n of e)if(!t.has(n.name))t.set(n.name,n);else {let i=t.get(n.name);if(i)for(let o of n.usedIn)i.usedIn.includes(o)||i.usedIn.push(o);}return Array.from(t.values())}async analyzeCodegenGenerated(){let e=[],t=await k(["**/__generated__/graphql.ts","**/__generated__/gql.ts","**/generated/graphql.ts"],{cwd:this.basePath,ignore:["**/node_modules/**","**/.next/**"],absolute:true});for(let n of t)try{let i=await O.readFile(n,"utf-8"),o=N.relative(this.basePath,n),a=i.split(`
2
+ `);for(let s of a){if(!s.includes("Document =")||!s.includes("DocumentNode"))continue;let r=s.match(/export\s+const\s+(\w+Document)\s*=\s*(\{"kind":"Document".+\})\s*as\s+unknown\s+as\s+DocumentNode/);if(!r)continue;let c=r[1],l=r[2];try{let f=JSON.parse(l);if(f.kind==="Document"&&f.definitions){let u=f.definitions[0];if(u?.kind==="OperationDefinition"){let g=u.name?.value||c.replace(/Document$/,""),y=u.operation,x=(u.variableDefinitions||[]).map(p=>({name:p.variable?.name?.value||"unknown",type:this.extractTypeFromAst(p.type),required:p.type?.kind==="NonNullType"}));e.push({name:g,type:y,filePath:o,usedIn:[],variables:x,returnType:this.inferReturnTypeFromAst(u),fragments:this.extractFragmentReferencesFromAst(u),fields:this.extractFieldsFromAst(u.selectionSet)});}}}catch{}}this.log(`Found ${e.length} operations in codegen output: ${o}`);}catch(i){this.warn(`Failed to analyze codegen file ${n}: ${i.message}`);}return e}extractTypeFromAst(e){return e?e.kind==="NonNullType"?`${this.extractTypeFromAst(e.type)}!`:e.kind==="ListType"?`[${this.extractTypeFromAst(e.type)}]`:e.kind==="NamedType"&&e.name?.value||"unknown":"unknown"}extractFieldsFromAst(e,t=0){if(!e?.selections||t>5)return [];let n=[];for(let i of e.selections)if(i.kind==="Field"){let o={name:i.name?.value||"unknown"};if(i.arguments?.length>0){let a=i.arguments.map(s=>s.name?.value).join(", ");o.type=`(${a})`;}i.selectionSet&&(o.fields=this.extractFieldsFromAst(i.selectionSet,t+1)),n.push(o);}else if(i.kind==="FragmentSpread")n.push({name:`...${i.name?.value}`,type:"fragment"});else if(i.kind==="InlineFragment"){let o=i.typeCondition?.name?.value||"inline";n.push({name:`... on ${o}`,type:"inline-fragment",fields:this.extractFieldsFromAst(i.selectionSet,t+1)});}return n}extractFragmentReferencesFromAst(e){let t=[],n=i=>{if(i&&(i.kind==="FragmentSpread"&&t.push(i.name?.value),i.selectionSet?.selections))for(let o of i.selectionSet.selections)n(o);};return n(e),t.filter(Boolean)}inferReturnTypeFromAst(e){if(e.selectionSet?.selections?.length>0){let t=e.selectionSet.selections[0];if(t.kind==="Field")return t.name?.value||"unknown"}return "unknown"}async analyzeGraphQLFiles(){let e=await k(["**/*.graphql"],{cwd:this.basePath,ignore:["**/node_modules/**","**/.next/**"],absolute:true});return (await M(e,async n=>{let i=await O.readFile(n,"utf-8"),o=parse(i);return this.extractOperationsFromDocument(o,N.relative(this.basePath,n))})).flat()}async analyzeInlineGraphQL(){let e=[],t=await k(["**/*.ts","**/*.tsx"],{cwd:this.basePath,ignore:["**/node_modules/**","**/.next/**","**/__tests__/**","**/*.test.*","**/*.spec.*"],absolute:true});for(let n of t)try{let i=this.project.addSourceFileAtPath(n),o=N.relative(this.basePath,n),a=i.getImportDeclarations().some(c=>{let l=c.getModuleSpecifierValue(),f=c.getNamedImports().map(g=>g.getName()),u=c.getDefaultImport()?.getText();return (f.includes("gql")||f.includes("graphql")||u==="gql")&&(l.includes("graphql")||l.includes("apollo")||l.includes("gql")||l.includes("__generated__"))}),s=i.getDescendantsOfKind(SyntaxKind.TaggedTemplateExpression);for(let c of s){let l=c.getTag().getText();if(l==="gql"||l==="graphql")try{let f=c.getTemplate(),u="";if(f.isKind(SyntaxKind.NoSubstitutionTemplateLiteral)?u=f.getLiteralValue():f.isKind(SyntaxKind.TemplateExpression)&&(u=f.getText().slice(1,-1).replace(/\$\{[^}]*\}/g,"")),u&&u.trim())try{let g=parse(u),y=this.extractOperationsFromDocument(g,o);e.push(...y);}catch{}}catch{}}let r=i.getDescendantsOfKind(SyntaxKind.CallExpression);for(let c of r)try{let f=c.getExpression().getText();if(f==="gql"||f==="graphql"){let u=c.getArguments();if(u.length>0){let g=u[0],y="";if(g.isKind(SyntaxKind.NoSubstitutionTemplateLiteral))y=g.getLiteralValue();else if(g.isKind(SyntaxKind.TemplateExpression))y=g.getText().slice(1,-1).replace(/\$\{[^}]*\}/g,"");else {let x=g.getText();if(x.includes("`")){let p=x.match(/\/\*\s*GraphQL\s*\*\/\s*`([^`]*)`/);if(p)y=p[1];else {let m=x.match(/`([^`]*)`/);m&&(y=m[1]);}}}if(y&&y.trim())try{let x=parse(y),p=this.extractOperationsFromDocument(x,o),m=this.extractVariableNameFromCall(c);if(m)for(let d of p)d.variableNames=d.variableNames||[],d.variableNames.push(m),d.variableNames.push(`${d.name}Document`);e.push(...p);}catch{}}}}catch{}if(a){let c=i.getVariableDeclarations();for(let l of c){let f=l.getName();if(f.includes("QUERY")||f.includes("MUTATION")||f.includes("FRAGMENT")||f.includes("Query")||f.includes("Mutation")||f.includes("Subscription")||/^[A-Z_]+_(QUERY|MUTATION|FRAGMENT|SUBSCRIPTION)$/.test(f)||/Query$|Mutation$|Fragment$|Subscription$/.test(f)){let g=l.getInitializer();g&&g.isKind(SyntaxKind.CallExpression);}}}}catch(i){this.warn(`Failed to analyze ${n}: ${i.message}`);}return e}extractVariableNameFromCall(e){try{let t=e.getParent();for(;t;){if(t.isKind?.(SyntaxKind.VariableDeclaration))return t.getName?.()||null;t=t.getParent?.();}}catch{}return null}extractOperationsFromDocument(e,t){let n=[];for(let i of e.definitions){let o=this.extractOperation(i,t);o&&n.push(o);}return n}extractOperation(e,t){if(e.kind==="OperationDefinition"){let n=e.name?.value||"anonymous",i=e.operation,o=this.extractVariables(e),a=this.extractFragmentReferences(e),s=this.extractFields(e);return {name:n,type:i,filePath:t,usedIn:[],variables:o,returnType:this.inferReturnType(e),fragments:a,fields:s}}return e.kind==="FragmentDefinition"?{name:e.name.value,type:"fragment",filePath:t,usedIn:[],variables:[],returnType:e.typeCondition.name.value,fragments:this.extractFragmentReferences(e),fields:this.extractFields(e)}:null}extractFields(e){let t=[],n=(i,o=0)=>{if(!i||!i.selections||o>5)return [];let a=[];for(let s of i.selections)if(s.kind==="Field"){let r={name:s.name.value};if(s.arguments&&s.arguments.length>0){let c=s.arguments.map(l=>l.name.value).join(", ");r.type=`(${c})`;}s.selectionSet&&(r.fields=n(s.selectionSet,o+1)),a.push(r);}else if(s.kind==="FragmentSpread")a.push({name:`...${s.name.value}`,type:"fragment"});else if(s.kind==="InlineFragment"&&s.selectionSet){let r=s.typeCondition?.name?.value||"inline";a.push({name:`... on ${r}`,type:"inline-fragment",fields:n(s.selectionSet,o+1)});}return a};return e.selectionSet?n(e.selectionSet):t}extractVariables(e){let t=[];if(e.variableDefinitions)for(let n of e.variableDefinitions){let i=n.variable.name.value,o=this.typeNodeToString(n.type),a=n.type.kind==="NonNullType";t.push({name:i,type:o,required:a});}return t}typeNodeToString(e){return e.kind==="NonNullType"?`${this.typeNodeToString(e.type)}!`:e.kind==="ListType"?`[${this.typeNodeToString(e.type)}]`:e.kind==="NamedType"?e.name.value:"unknown"}extractFragmentReferences(e){let t=[],n=i=>{if(i&&(i.kind==="FragmentSpread"&&t.push(i.name.value),i.selectionSet))for(let o of i.selectionSet.selections)n(o);};return n(e),t}inferReturnType(e){if(e.selectionSet&&e.selectionSet.selections.length>0){let t=e.selectionSet.selections[0];if(t.kind==="Field")return t.name.value}return "unknown"}async findOperationUsage(e){if(e.length===0)return;let t=await k(["**/*.ts","**/*.tsx"],{cwd:this.basePath,ignore:["**/node_modules/**","**/.next/**","**/__generated__/**"],absolute:true}),n=new Map,i=new Map,o=new Map;for(let l of e)if(n.set(l.name,l),i.set(`${l.name}Document`,l),l.variableNames)for(let f of l.variableNames)o.set(f,l);let a=new Set;for(let l of e)if(a.add(`${l.name}Document`),l.variableNames)for(let f of l.variableNames)a.add(f);let s=null,r=Array.from(a);if(r.length>0&&r.length<2e3){let l=r.sort((f,u)=>u.length-f.length).map(f=>f.replace(/[.*+?^${}()|[\]\\]/g,"\\$&"));s=new RegExp(`\\b(${l.join("|")})\\b`,"g");}let c=50;for(let l=0;l<t.length;l+=c){let f=t.slice(l,l+c);await Promise.all(f.map(async u=>{try{let g=await O.readFile(u,"utf-8"),y=N.relative(this.basePath,u);if(!g.includes("Document")&&!g.includes("useQuery")&&!g.includes("useMutation")&&!g.includes("Query")&&!g.includes("Mutation")&&!g.includes("GET_")&&!g.includes("SEARCH_")&&!g.includes("CREATE_")&&!g.includes("UPDATE_")&&!g.includes("DELETE_"))return;if(s){let x=new Set,p;for(;(p=s.exec(g))!==null;)x.add(p[1]);s.lastIndex=0;for(let m of x){let d=i.get(m)||o.get(m);d&&y!==d.filePath&&(d.usedIn.includes(y)||d.usedIn.push(y));}}for(let[x,p]of n)y!==p.filePath&&(p.usedIn.includes(y)||(g.includes(`useQuery<${x}`)||g.includes(`useMutation<${x}`)||g.includes(`useLazyQuery<${x}`)||g.includes(`useSubscription<${x}`)||g.includes(`${x}Query`)||g.includes(`${x}Mutation`))&&p.usedIn.push(y));}catch{}}));}}};var W=class extends T{componentCache=new Map;constructor(e){super(e);}getName(){return "DataFlowAnalyzer"}async analyze(){this.log("Starting data flow analysis...");let e=await this.analyzeComponents(),t=await this.analyzeDataFlows(e);return this.log(`Analyzed ${e.length} components and ${t.length} data flows`),{components:e,dataFlows:t}}async analyzeComponents(){let e=[],t=[this.getSetting("featuresDir",""),this.getSetting("componentsDir",""),this.getSetting("pagesDir","")].filter(Boolean),n=["src/features","src/components","src/common/components","src/common","src/pages","src/app","src/modules","src/views","src/screens","components","pages","app"],o=[...new Set([...t,...n])].map(r=>`${r}/**/*.tsx`),a=await k(o,{cwd:this.basePath,ignore:["**/*.test.*","**/*.spec.*","**/*.stories.*","**/node_modules/**","**/__generated__/**"],absolute:true,onlyFiles:true,unique:true});this.log(`[DataFlowAnalyzer] Found ${a.length} component files to analyze`);let s=100;for(let r=0;r<a.length;r+=s){let c=a.slice(r,r+s),l=await Promise.all(c.map(async f=>{try{let u=await O.readFile(f,"utf-8");return {filePath:f,content:u}}catch{return null}}));for(let f of l)if(f)try{let u=parseSync(f.content,{syntax:"typescript",tsx:!0,comments:!1}),g=N.relative(this.basePath,f.filePath),y=this.analyzeComponentFile(u,g,f.content);e.push(...y);}catch{}}return this.log(`[DataFlowAnalyzer] Extracted ${e.length} components`),this.buildDependencyGraph(e),e}analyzeComponentFile(e,t,n){let i=[],o=this.extractImports(e);for(let a of e.body){if(a.type==="ExportDeclaration"&&a.declaration?.type==="FunctionDeclaration"){let s=a.declaration.identifier?.value;if(s&&this.isComponentName(s)){let r=this.extractComponentInfo(s,t,n,o);i.push(r),this.componentCache.set(s,r);}}if(a.type==="FunctionDeclaration"){let s=a.identifier?.value;if(s&&this.isComponentName(s)){let r=this.extractComponentInfo(s,t,n,o);i.push(r),this.componentCache.set(s,r);}}if(a.type==="ExportDefaultDeclaration"&&a.decl?.type==="FunctionExpression"){let s=a.decl.identifier?.value;if(s&&this.isComponentName(s)){let r=this.extractComponentInfo(s,t,n,o);i.push(r),this.componentCache.set(s,r);}}if(a.type==="VariableDeclaration"){for(let s of a.declarations)if(s.id?.type==="Identifier"){let r=s.id.value;if(r&&(this.isComponentName(r)||r.startsWith("use"))&&s.init&&(s.init.type==="ArrowFunctionExpression"||s.init.type==="FunctionExpression")){let c=this.extractComponentInfo(r,t,n,o);i.push(c),this.componentCache.set(r,c);}}}if(a.type==="ExportDeclaration"&&a.declaration?.type==="VariableDeclaration"){for(let s of a.declaration.declarations)if(s.id?.type==="Identifier"){let r=s.id.value;if(r&&(this.isComponentName(r)||r.startsWith("use"))&&s.init&&(s.init.type==="ArrowFunctionExpression"||s.init.type==="FunctionExpression")){let c=this.extractComponentInfo(r,t,n,o);i.push(c),this.componentCache.set(r,c);}}}}return i}extractImports(e){let t=new Map;for(let n of e.body)if(n.type==="ImportDeclaration"){let i=n.source?.value||"";if(i.startsWith(".")||i.startsWith("@/"))for(let o of n.specifiers||[])o.type==="ImportSpecifier"&&o.local?.value&&t.set(o.local.value,i),o.type==="ImportDefaultSpecifier"&&o.local?.value&&t.set(o.local.value,i);}return t}isComponentName(e){return /^[A-Z][a-zA-Z0-9]*$/.test(e)}extractComponentInfo(e,t,n,i){let o="presentational";["/pages/","/app/","/routes/","/views/","/screens/"].some(l=>t.includes(l))?o="page":e.includes("Container")||e.includes("Provider")?o="container":e.includes("Layout")||e.includes("Shell")||e.includes("Wrapper")||e.includes("Frame")||e.includes("Scaffold")||t.includes("/layouts/")||t.includes("/layout/")?o="layout":e.startsWith("use")&&(o="hook");let s=this.extractHooksUsed(n),r=Array.from(i.keys()).filter(l=>this.isComponentName(l)||l.startsWith("use")),c=this.extractStateManagement(n);return {name:e,filePath:t,type:o,props:[],dependencies:r,dependents:[],hooks:s,stateManagement:c}}extractHooksUsed(e){let t=[],n=/\b(useQuery|useMutation|useLazyQuery)(?:<[^>]*>)?\s*\(\s*([A-Z_][A-Za-z0-9_]*)/g,i;for(;(i=n.exec(e))!==null;){let s=i[1],r=i[2];if(/^(Query|Mutation|QUERY|MUTATION)$/i.test(r))continue;let c=this.extractOperationName(r);if(s==="useQuery"||s==="useLazyQuery"){let l=c?`Query: ${c}`:`Query: ${r}`;t.includes(l)||t.push(l);}else if(s==="useMutation"){let l=c?`Mutation: ${c}`:`Mutation: ${r}`;t.includes(l)||t.push(l);}}let o=/\b(use[A-Z][a-zA-Z0-9]*)\s*\(/g,a;for(;(a=o.exec(e))!==null;){let s=a[1];if(!(s==="useQuery"||s==="useMutation"||s==="useLazyQuery"))if(s==="useContext"){let r=e.slice(a.index).match(/useContext\s*\(\s*([A-Z][A-Za-z0-9]*)/);if(r){let l=`\u{1F504} Context: ${r[1].replace(/Context$/,"")}`;t.includes(l)||t.push(l);}}else t.includes(s)||t.push(s);}return t}extractOperationName(e){if(!e)return null;let t=e.split(",")[0].trim();if(/^[{[\'"` ]/.test(t))return null;let n=t.replace(/^(GET_|FETCH_|CREATE_|UPDATE_|DELETE_)/,"").replace(/_QUERY$|_MUTATION$/,"").replace(/Document$/,"").replace(/Query$|Mutation$/,"");return !n||n.trim()===""||/^(QUERY|MUTATION)$/i.test(n.trim())?null:n}extractStateManagement(e){let t=[];return e.includes("useState")&&t.push("useState"),e.includes("useReducer")&&t.push("useReducer"),e.includes("useContext")&&t.push("useContext"),e.includes("useQuery")&&t.push("Apollo Query"),e.includes("useMutation")&&t.push("Apollo Mutation"),e.includes("useRecoil")&&t.push("Recoil"),(e.includes("useSelector")||e.includes("useDispatch"))&&t.push("Redux"),t}buildDependencyGraph(e){let t=new Map;for(let n of e)t.set(n.name,n);for(let n of e)for(let i of n.dependencies){let o=t.get(i);o&&!o.dependents.includes(n.name)&&o.dependents.push(n.name);}}async analyzeDataFlows(e){let t=[],n=1,i=this.analyzeContextFlows(e);t.push(...i.map(s=>({...s,id:`flow-${n++}`})));let o=this.analyzeApolloFlows(e);t.push(...o.map(s=>({...s,id:`flow-${n++}`})));let a=this.analyzePropDrilling(e);return t.push(...a.map(s=>({...s,id:`flow-${n++}`}))),t}analyzeContextFlows(e){let t=[],n=e.filter(o=>o.name.includes("Provider")||o.name.includes("Context")),i=e.filter(o=>o.hooks.some(a=>a.includes("Context")));for(let o of n){let a=o.name.replace("Provider","").replace("Context","");for(let s of i){let r=s.hooks.find(c=>c.includes("Context")&&c.includes(a));(r||s.hooks.some(c=>c.includes(a)))&&t.push({name:`\u{1F504} ${a} Context`,description:`Data flows from ${o.name} to ${s.name} via Context`,source:{type:"context",name:o.name},target:{type:"component",name:s.name},via:[],operations:[r||`useContext(${a})`]});}}return t}analyzeApolloFlows(e){let t=[];for(let n of e){let i=n.hooks.filter(a=>a.includes("Query:")||a==="useQuery"||a==="useLazyQuery");for(let a of i){let s=a.includes(":")?a.split(":")[1].trim():n.name;t.push({name:`Query: ${s}`,description:`${n.name} fetches ${s} via Apollo`,source:{type:"api",name:`GraphQL: ${s}`},target:{type:"component",name:n.name},via:[{type:"cache",name:"Apollo Cache"}],operations:[a]});}let o=n.hooks.filter(a=>a.includes("Mutation:")||a==="useMutation");for(let a of o){let s=a.includes(":")?a.split(":")[1].trim():n.name;t.push({name:`Mutation: ${s}`,description:`${n.name} mutates ${s} via Apollo`,source:{type:"component",name:n.name},target:{type:"api",name:`GraphQL: ${s}`},via:[],operations:[a]});}}return t}analyzePropDrilling(e){let t=[];for(let n of e)n.props.length>5&&n.dependents.length>0&&t.push({name:`Prop Drilling through ${n.name}`,description:`${n.name} passes ${n.props.length} props to children`,source:{type:"component",name:n.name},target:{type:"component",name:n.dependents[0]},via:[],operations:["props"]});return t}};var Z=class extends T{project;apiCallCounter=0;constructor(e){super(e);let t=this.resolvePath("tsconfig.json"),n=existsSync(t);this.project=new Project({...n?{tsConfigFilePath:t}:{},skipAddingFilesFromTsConfig:true,compilerOptions:n?void 0:{allowJs:true,jsx:2}});}getName(){return "RestApiAnalyzer"}async analyze(){this.log("Starting REST API analysis...");let e=await k(["**/*.ts","**/*.tsx"],{cwd:this.basePath,ignore:["**/node_modules/**","**/.next/**","**/__tests__/**","**/*.test.*","**/*.spec.*","**/*.stories.*","**/__generated__/**","**/dist/**","**/build/**"],absolute:true}),t=new Map;for(let o of e)try{t.set(o,this.project.addSourceFileAtPath(o));}catch{}let i=(await M(Array.from(t.entries()),async([o,a])=>{let s=N.relative(this.basePath,o),r=[];return r.push(...this.findFetchCalls(a,s)),r.push(...this.findAxiosCalls(a,s)),r.push(...this.findSwrCalls(a,s)),r},8)).flat();return this.log(`Found ${i.length} REST API calls`),{apiCalls:i}}findFetchCalls(e,t){let n=[],i=e.getDescendantsOfKind(SyntaxKind.CallExpression);for(let o of i)try{let s=o.getExpression().getText();if(s==="fetch"||s==="window.fetch"){let r=this.extractFetchCall(o,t);r&&n.push(r);}}catch{}return n}findAxiosCalls(e,t){let n=[],i=e.getDescendantsOfKind(SyntaxKind.CallExpression);for(let o of i)try{let s=o.getExpression().getText(),r=s.match(/^axios\.(get|post|put|delete|patch)$/i);if(r){let c=this.extractAxiosCall(o,t,r[1].toUpperCase());c&&n.push(c);}if(s==="axios"){let c=this.extractAxiosDirectCall(o,t);c&&n.push(c);}}catch{}return n}findSwrCalls(e,t){let n=[],i=e.getDescendantsOfKind(SyntaxKind.CallExpression);for(let o of i)try{let s=o.getExpression().getText();if(s==="useSWR"||s==="useSWRImmutable"){let r=this.extractSwrCall(o,t);r&&n.push(r);}}catch{}return n}extractFetchCall(e,t){let n=e.getArguments();if(n.length===0)return null;let i=n[0].getText(),o=this.extractUrlFromArg(i);if(!o.url||!o.isPlaceholder&&!this.isApiUrl(o.url))return null;let a="GET",s=false;if(n.length>1){let l=n[1].getText(),f=l.match(/method:\s*["'](\w+)["']/i);f&&(a=this.normalizeMethod(f[1])),s=l.includes("credentials")||l.includes("Authorization")||l.includes("withCredentials");}let r=this.getContainingFunctionName(e),c=e.getStartLineNumber();return {id:`api-${++this.apiCallCounter}`,method:a,url:o.url,callType:"fetch",filePath:t,line:c,containingFunction:r,usedIn:[],requiresAuth:s,category:this.categorizeApi(o.url)}}extractAxiosCall(e,t,n){let i=e.getArguments();if(i.length===0)return null;let o=i[0].getText(),a=this.extractUrlFromArg(o);if(!a.url)return null;let s=false;if(i.length>1){let l=i[i.length-1].getText();s=l.includes("withCredentials")||l.includes("Authorization");}let r=this.getContainingFunctionName(e),c=e.getStartLineNumber();return {id:`api-${++this.apiCallCounter}`,method:this.normalizeMethod(n),url:a.url,callType:"axios",filePath:t,line:c,containingFunction:r,usedIn:[],requiresAuth:s,category:this.categorizeApi(a.url)}}extractAxiosDirectCall(e,t){let n=e.getArguments();if(n.length===0)return null;let i=n[0].getText(),o=i.match(/url:\s*["'`]([^"'`]+)["'`]/),a=i.match(/method:\s*["'](\w+)["']/i);if(!o)return null;let s=o[1],r=a?this.normalizeMethod(a[1]):"GET",c=i.includes("withCredentials")||i.includes("Authorization"),l=this.getContainingFunctionName(e),f=e.getStartLineNumber();return {id:`api-${++this.apiCallCounter}`,method:r,url:s,callType:"axios",filePath:t,line:f,containingFunction:l,usedIn:[],requiresAuth:c,category:this.categorizeApi(s)}}extractSwrCall(e,t){let n=e.getArguments();if(n.length===0)return null;let i=n[0].getText(),o=null;if(i.startsWith('"')||i.startsWith("'")||i.startsWith("`"))o=this.cleanStringLiteral(i);else if(i.includes("?")&&i.includes(":")){let r=i.match(/\?\s*["'`]([^"'`]+)["'`]/);r?o=r[1]:(r=i.match(/:\s*["'`]([^"'`]+)["'`]/),r&&(o=r[1])),o||(r=i.match(/\?\s*`([^`]+)`/),r&&(o=r[1].replace(/\$\{[^}]+\}/g,":param")));}else {let r=this.extractUrlFromArg(i);r.url&&!i.includes("null")&&!i.includes("undefined")&&(o=r.url);}if(!o)return null;let a=this.getContainingFunctionName(e),s=e.getStartLineNumber();return {id:`api-${++this.apiCallCounter}`,method:"GET",url:o,callType:"useSWR",filePath:t,line:s,containingFunction:a,usedIn:[],requiresAuth:false,category:this.categorizeApi(o)}}getContainingFunctionName(e){let t=e;for(;t;){if(Node.isFunctionDeclaration(t))return t.getName()||"anonymous";if(Node.isVariableDeclaration(t)||Node.isMethodDeclaration(t))return t.getName();if(Node.isArrowFunction(t)){let n=t.getParent();if(n&&Node.isVariableDeclaration(n))return n.getName()}t=t.getParent();}return "unknown"}extractUrlFromArg(e){if(/^["'`]/.test(e))return {url:this.cleanStringLiteral(e),isPlaceholder:false};let t=e.match(/^(\w+)\s*\(\s*["'`]([^"'`]+)["'`]/);if(t)return {url:`[${t[1]}] ${t[2]}`,isPlaceholder:true};let n=e.match(/^(\w+)\s*\(\s*`([^`]+)`/);if(n){let i=n[2].replace(/\$\{[^}]+\}/g,":param");return {url:`[${n[1]}] ${i}`,isPlaceholder:true}}return /^\w+(\.\w+)*$/.test(e)?{url:`[${e}]`,isPlaceholder:true}:e.includes(".")?{url:`[${e}]`,isPlaceholder:true}:{url:null,isPlaceholder:false}}cleanStringLiteral(e){let t=e.replace(/^["'`]|["'`]$/g,"").trim();return t.includes("${")?t.replace(/\$\{[^}]+\}/g,":param"):t||null}isApiUrl(e){return e.startsWith("data:")||e.startsWith("blob:")||/\.(css|js|png|jpg|jpeg|gif|svg|ico|woff|woff2|ttf|eot|html)$/i.test(e)?false:e.startsWith("/")||e.startsWith("http")||e.includes("/api/")||e.includes(".json")||e.includes("api.")||e.includes("github.io")||e.includes("hsforms.com")||e.includes("hubspot")||e.includes("amazonaws.com")||e.includes("s3.")||e.includes("googleapis.com")||e.includes("stripe.com")||e.includes("graph.facebook.com")||e.includes("api.twitter.com")||e.includes("slack.com")||e.includes("discord.com")||e.includes("sendgrid.com")||e.includes("twilio.com")||e.includes("firebase")||e.includes("supabase")||e.includes("auth0.com")||e.includes("okta.com")||e.includes("cloudflare.com")||e.includes("vercel.com")||e.includes("netlify.com")}categorizeApi(e){if(e.includes("hsforms.com")||e.includes("hubspot"))return "HubSpot";if(e.includes("amazonaws.com")||e.includes("s3."))return "AWS S3";if(e.includes("googleapis.com"))return "Google API";if(e.includes("stripe.com"))return "Stripe";if(e.includes("graph.facebook.com"))return "Facebook";if(e.includes("api.twitter.com"))return "Twitter";if(e.includes("slack.com"))return "Slack";if(e.includes("discord.com"))return "Discord";if(e.includes("sendgrid.com"))return "SendGrid";if(e.includes("twilio.com"))return "Twilio";if(e.includes("firebase"))return "Firebase";if(e.includes("supabase"))return "Supabase";if(e.includes("auth0.com"))return "Auth0";if(e.includes("okta.com"))return "Okta";if(e.includes("github.io"))return "GitHub Pages API";if(e.startsWith("/api/"))return "Internal API";if(e.startsWith("/"))return "Internal Route";if(e.startsWith("["))return "Dynamic URL"}normalizeMethod(e){let t=e.toUpperCase();return ["GET","POST","PUT","DELETE","PATCH"].includes(t)?t:"unknown"}};export{T as a,q as b,G as c,W as d,Z as e};
@@ -1,4 +1,4 @@
1
- import {a as a$2}from'./chunk-H4YGP3GL.js';import {a as a$3}from'./chunk-VV3A3UE3.js';import {e,d as d$1,c,b as b$2}from'./chunk-WJIBUCXB.js';import {a,b as b$1}from'./chunk-XWZH2RDG.js';import {a as a$1}from'./chunk-QZWPOG5B.js';import {k}from'./chunk-PTR5IROV.js';import {simpleGit}from'simple-git';import*as d from'fs/promises';import*as m from'path';import H from'fast-glob';import*as w from'crypto';import F from'express';import {Server}from'socket.io';import*as z from'http';import {marked}from'marked';import*as P from'net';var C="1.1",x=class{cacheDir;manifest;manifestPath;dirty=false;constructor(a){this.cacheDir=m.join(a,".repomap-cache"),this.manifestPath=m.join(this.cacheDir,"manifest.json"),this.manifest={version:C,entries:{}};}async init(){try{await d.mkdir(this.cacheDir,{recursive:!0});}catch(a){console.warn(` Warning: Could not create cache directory: ${a.message}`);return}try{let a=await d.readFile(this.manifestPath,"utf-8"),t=JSON.parse(a);t.version===C?this.manifest=t:(console.log(" Cache version mismatch, clearing cache..."),await this.clear());}catch{}}async computeFileHash(a){try{let t=await d.readFile(a,"utf-8");return w.createHash("md5").update(t).digest("hex")}catch{return ""}}async computeFilesHash(a){let t=[...a].sort(),e=50,o;t.length<=e*2?o=t:o=[...t.slice(0,e),...t.slice(-e)];let s=await Promise.all(o.map(i=>this.computeFileHash(i))),n=w.createHash("md5").update(String(t.length)).digest("hex");return w.createHash("md5").update(s.join("")+n).digest("hex")}get(a,t){let e=this.manifest.entries[a];return e&&e.hash===t?e.data:null}set(a,t,e){this.manifest.entries[a]={hash:t,timestamp:Date.now(),data:e},this.dirty=true;}async save(){if(this.dirty)try{await d.mkdir(this.cacheDir,{recursive:!0}),await d.writeFile(this.manifestPath,JSON.stringify(this.manifest,null,2)),this.dirty=!1;}catch(a){console.warn(" Warning: Failed to save cache:",a.message);}}async clear(){this.manifest={version:C,entries:{}},this.dirty=true;try{await d.rm(this.cacheDir,{recursive:!0,force:!0}),await d.mkdir(this.cacheDir,{recursive:!0});}catch{}}getStats(){let a=Object.keys(this.manifest.entries).length,t=JSON.stringify(this.manifest).length;return {entries:a,size:t>1024*1024?`${(t/1024/1024).toFixed(1)}MB`:`${(t/1024).toFixed(1)}KB`}}};var b=class{config;mermaidGenerator;markdownGenerator;noCache;constructor(a$1,t){this.config=a$1,this.mermaidGenerator=new a,this.markdownGenerator=new b$1,this.noCache=t?.noCache??false;}async generate(){console.log(`\u{1F680} Starting documentation generation...
1
+ import {a as a$2}from'./chunk-H4YGP3GL.js';import {a as a$3}from'./chunk-VV3A3UE3.js';import {e,d as d$1,c,b as b$2}from'./chunk-BPV4UZSW.js';import {a,b as b$1}from'./chunk-XWZH2RDG.js';import {a as a$1}from'./chunk-QZWPOG5B.js';import {k}from'./chunk-PTR5IROV.js';import {simpleGit}from'simple-git';import*as d from'fs/promises';import*as m from'path';import H from'fast-glob';import*as w from'crypto';import F from'express';import {Server}from'socket.io';import*as z from'http';import {marked}from'marked';import*as P from'net';var C="1.1",x=class{cacheDir;manifest;manifestPath;dirty=false;constructor(a){this.cacheDir=m.join(a,".repomap-cache"),this.manifestPath=m.join(this.cacheDir,"manifest.json"),this.manifest={version:C,entries:{}};}async init(){try{await d.mkdir(this.cacheDir,{recursive:!0});}catch(a){console.warn(` Warning: Could not create cache directory: ${a.message}`);return}try{let a=await d.readFile(this.manifestPath,"utf-8"),t=JSON.parse(a);t.version===C?this.manifest=t:(console.log(" Cache version mismatch, clearing cache..."),await this.clear());}catch{}}async computeFileHash(a){try{let t=await d.readFile(a,"utf-8");return w.createHash("md5").update(t).digest("hex")}catch{return ""}}async computeFilesHash(a){let t=[...a].sort(),e=50,o;t.length<=e*2?o=t:o=[...t.slice(0,e),...t.slice(-e)];let s=await Promise.all(o.map(i=>this.computeFileHash(i))),n=w.createHash("md5").update(String(t.length)).digest("hex");return w.createHash("md5").update(s.join("")+n).digest("hex")}get(a,t){let e=this.manifest.entries[a];return e&&e.hash===t?e.data:null}set(a,t,e){this.manifest.entries[a]={hash:t,timestamp:Date.now(),data:e},this.dirty=true;}async save(){if(this.dirty)try{await d.mkdir(this.cacheDir,{recursive:!0}),await d.writeFile(this.manifestPath,JSON.stringify(this.manifest,null,2)),this.dirty=!1;}catch(a){console.warn(" Warning: Failed to save cache:",a.message);}}async clear(){this.manifest={version:C,entries:{}},this.dirty=true;try{await d.rm(this.cacheDir,{recursive:!0,force:!0}),await d.mkdir(this.cacheDir,{recursive:!0});}catch{}}getStats(){let a=Object.keys(this.manifest.entries).length,t=JSON.stringify(this.manifest).length;return {entries:a,size:t>1024*1024?`${(t/1024/1024).toFixed(1)}MB`:`${(t/1024).toFixed(1)}KB`}}};var b=class{config;mermaidGenerator;markdownGenerator;noCache;constructor(a$1,t){this.config=a$1,this.mermaidGenerator=new a,this.markdownGenerator=new b$1,this.noCache=t?.noCache??false;}async generate(){console.log(`\u{1F680} Starting documentation generation...
2
2
  `);let a=[];for(let i of this.config.repositories)try{console.log(`
3
3
  \u{1F4E6} Analyzing ${i.displayName}...`);let r=await this.analyzeRepository(i);a.push(r),console.log(`\u2705 Completed ${i.displayName}`);}catch(r){console.error(`\u274C Failed to analyze ${i.name}:`,r.message);}console.log(`
4
4
  \u{1F517} Running cross-repository analysis...`);let t=this.analyzeCrossRepo(a);console.log(`
package/dist/cli.js CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import {a,b}from'./chunk-UR7HVBHH.js';import'./chunk-H4YGP3GL.js';import'./chunk-VV3A3UE3.js';import'./chunk-WJIBUCXB.js';import'./chunk-XWZH2RDG.js';import'./chunk-QZWPOG5B.js';import'./chunk-PTR5IROV.js';import {Command}from'commander';import n from'chalk';import*as p from'path';import*as s from'fs/promises';var d=new Command;d.name("repomap").description("Interactive documentation generator for code repositories").version("0.1.0");async function $(e){let o=p.basename(e),a=false,t=p.join(e,"Gemfile"),c=p.join(e,"config","routes.rb");try{await s.access(t),await s.access(c);let u=await s.readFile(t,"utf-8");a=u.includes("gem 'rails'")||u.includes('gem "rails"');}catch{}let r=p.join(e,"package.json"),i=false,l=false,m={};try{let u=JSON.parse(await s.readFile(r,"utf-8")),w={...u.dependencies,...u.devDependencies};i=!!w.react,l=!!w.next;let f=["src/pages","pages","app","src/app","frontend/src"];for(let g of f)try{await s.access(p.join(e,g)),m.pagesDir=g;break}catch{}let b=["src/features","features","src/modules","modules","frontend/src"];for(let g of b)try{await s.access(p.join(e,g)),m.featuresDir=g;break}catch{}let D=["src/components","components","src/common/components","frontend/src"];for(let g of D)try{await s.access(p.join(e,g)),m.componentsDir=g;break}catch{}}catch{}let h=[];(i||l)&&h.push("pages","graphql","dataflow","rest-api");let y="generic";return l?y="nextjs":a&&(y="rails"),!a&&!i&&!l?null:{name:o,displayName:o,description:a&&i?"Rails + React application":a?"Rails application":"",path:e,branch:"main",type:y,analyzers:h,settings:m}}async function x(e){let o=await $(e);if(!o)throw new Error("Could not detect project. Please create a repomap.config.ts file or run 'repomap init'.");return {outputDir:"./.repomap",site:{title:`${o.displayName} Documentation`,description:"Auto-generated documentation",baseUrl:"/docs"},repositories:[o],analysis:{include:["**/*.tsx","**/*.ts"],exclude:["**/node_modules/**","**/__tests__/**","**/*.test.*","**/*.spec.*","**/dist/**","**/.next/**"],maxDepth:5},diagrams:{enabled:true,types:["flowchart","sequence"],theme:"default"},watch:{enabled:false,debounce:1e3},integrations:{github:{enabled:false,organization:""},slack:{enabled:false}}}}async function P(e,o){let a=e?[e]:["repomap.config.ts","repomap.config.js","repomap.config.mjs"];for(let t of a){let c=p.resolve(o,t);try{await s.access(c),console.log(n.gray(`Loading config from: ${c}`));let r=await import(c);return r.config||r.default}catch{}}return console.log(n.gray("No config file found, auto-detecting project...")),x(o)}d.command("generate").description("Generate documentation from source code").option("-c, --config <path>","Path to config file").option("-o, --output <path>","Output directory").option("--repo <name>","Analyze specific repository only").option("--watch","Watch for changes and regenerate").option("--no-cache","Disable caching (always analyze from scratch)").option("--format <type>","Output format: json, html, markdown (default: all)","all").option("--ci","CI mode: minimal output, exit codes for errors").option("--static","Generate standalone HTML files (for GitHub Pages)").action(async e=>{let o=e.ci||process.env.CI==="true";o||console.log(n.blue.bold(`
2
+ import {a,b}from'./chunk-WQANJ7IA.js';import'./chunk-H4YGP3GL.js';import'./chunk-VV3A3UE3.js';import'./chunk-BPV4UZSW.js';import'./chunk-XWZH2RDG.js';import'./chunk-QZWPOG5B.js';import'./chunk-PTR5IROV.js';import {Command}from'commander';import n from'chalk';import*as p from'path';import*as s from'fs/promises';var d=new Command;d.name("repomap").description("Interactive documentation generator for code repositories").version("0.1.0");async function $(e){let o=p.basename(e),a=false,t=p.join(e,"Gemfile"),c=p.join(e,"config","routes.rb");try{await s.access(t),await s.access(c);let u=await s.readFile(t,"utf-8");a=u.includes("gem 'rails'")||u.includes('gem "rails"');}catch{}let r=p.join(e,"package.json"),i=false,l=false,m={};try{let u=JSON.parse(await s.readFile(r,"utf-8")),w={...u.dependencies,...u.devDependencies};i=!!w.react,l=!!w.next;let f=["src/pages","pages","app","src/app","frontend/src"];for(let g of f)try{await s.access(p.join(e,g)),m.pagesDir=g;break}catch{}let b=["src/features","features","src/modules","modules","frontend/src"];for(let g of b)try{await s.access(p.join(e,g)),m.featuresDir=g;break}catch{}let D=["src/components","components","src/common/components","frontend/src"];for(let g of D)try{await s.access(p.join(e,g)),m.componentsDir=g;break}catch{}}catch{}let h=[];(i||l)&&h.push("pages","graphql","dataflow","rest-api");let y="generic";return l?y="nextjs":a&&(y="rails"),!a&&!i&&!l?null:{name:o,displayName:o,description:a&&i?"Rails + React application":a?"Rails application":"",path:e,branch:"main",type:y,analyzers:h,settings:m}}async function x(e){let o=await $(e);if(!o)throw new Error("Could not detect project. Please create a repomap.config.ts file or run 'repomap init'.");return {outputDir:"./.repomap",site:{title:`${o.displayName} Documentation`,description:"Auto-generated documentation",baseUrl:"/docs"},repositories:[o],analysis:{include:["**/*.tsx","**/*.ts"],exclude:["**/node_modules/**","**/__tests__/**","**/*.test.*","**/*.spec.*","**/dist/**","**/.next/**"],maxDepth:5},diagrams:{enabled:true,types:["flowchart","sequence"],theme:"default"},watch:{enabled:false,debounce:1e3},integrations:{github:{enabled:false,organization:""},slack:{enabled:false}}}}async function P(e,o){let a=e?[e]:["repomap.config.ts","repomap.config.js","repomap.config.mjs"];for(let t of a){let c=p.resolve(o,t);try{await s.access(c),console.log(n.gray(`Loading config from: ${c}`));let r=await import(c);return r.config||r.default}catch{}}return console.log(n.gray("No config file found, auto-detecting project...")),x(o)}d.command("generate").description("Generate documentation from source code").option("-c, --config <path>","Path to config file").option("-o, --output <path>","Output directory").option("--repo <name>","Analyze specific repository only").option("--watch","Watch for changes and regenerate").option("--no-cache","Disable caching (always analyze from scratch)").option("--format <type>","Output format: json, html, markdown (default: all)","all").option("--ci","CI mode: minimal output, exit codes for errors").option("--static","Generate standalone HTML files (for GitHub Pages)").action(async e=>{let o=e.ci||process.env.CI==="true";o||console.log(n.blue.bold(`
3
3
  \u{1F4DA} Repomap - Documentation Generator
4
4
  `));try{let a$1=process.cwd(),t=await P(e.config,a$1);e.output&&(t.outputDir=e.output),e.repo&&(t.repositories=t.repositories.filter(r=>r.name===e.repo),t.repositories.length===0&&(console.error(n.red(`Repository "${e.repo}" not found in config`)),process.exit(1)));let c=new a(t,{noCache:!e.cache});if(e.watch)console.log(n.yellow(`
5
5
  \u{1F440} Watch mode enabled. Press Ctrl+C to stop.
@@ -98,6 +98,15 @@ declare class PagesAnalyzer extends BaseAnalyzer {
98
98
  * Next.js, React, Rails+React 구조 모두 지원
99
99
  */
100
100
  private findPageFiles;
101
+ /**
102
+ * Find routes from SPA (react-router-dom) based projects
103
+ * App.tsx에서 react-router-dom의 Route 컴포넌트를 파싱하여 페이지 찾기
104
+ */
105
+ private findSPARoutes;
106
+ /**
107
+ * Resolve import path to absolute file path
108
+ */
109
+ private resolveImportPath;
101
110
  /**
102
111
  * Analyze _app.tsx for global providers that use GraphQL
103
112
  * _app.tsx에서 전역 Context Provider의 GraphQL 분석
package/dist/index.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import { DocGeneratorConfig, DocumentationReport } from './types.js';
2
2
  export { APICall, APIConnection, APIEndpoint, AnalysisConfig, AnalysisResult, AnalyzerType, AssociationInfo, AttributeInfo, AuthRequirement, ComponentInfo, CrossRepoAnalysis, CrossRepoLink, DataFetchingInfo, DataFlow, DataFlowNode, DiagramConfig, DiagramType, GraphQLField, GraphQLOperation, IntegrationsConfig, MermaidDiagram, ModelInfo, NavigationFlow, NavigationInfo, PageInfo, ParameterInfo, PropInfo, RepositoryConfig, RepositoryReport, RepositorySummary, ResponseInfo, SiteConfig, StepInfo, VariableInfo, WatchConfig } from './types.js';
3
- export { B as BaseAnalyzer, D as DataFlowAnalyzer, G as GraphQLAnalyzer, P as PagesAnalyzer } from './dataflow-analyzer-mlxaq5qn.js';
3
+ export { B as BaseAnalyzer, D as DataFlowAnalyzer, G as GraphQLAnalyzer, P as PagesAnalyzer } from './dataflow-analyzer-s6ufFkKC.js';
4
4
  export { MarkdownGenerator, MermaidGenerator, PageMapGenerator, PageMapOptions } from './generators/index.js';
5
5
  export { DocServer, DocServerOptions } from './server/index.js';
6
6
 
package/dist/index.js CHANGED
@@ -1 +1 @@
1
- import'./chunk-6F4PWJZI.js';export{a as DocGeneratorEngine,b as DocServer}from'./chunk-UR7HVBHH.js';import'./chunk-H4YGP3GL.js';import'./chunk-VV3A3UE3.js';export{a as BaseAnalyzer,d as DataFlowAnalyzer,c as GraphQLAnalyzer,b as PagesAnalyzer}from'./chunk-WJIBUCXB.js';export{b as MarkdownGenerator,a as MermaidGenerator}from'./chunk-XWZH2RDG.js';export{a as PageMapGenerator}from'./chunk-QZWPOG5B.js';import'./chunk-PTR5IROV.js';
1
+ import'./chunk-6F4PWJZI.js';export{a as DocGeneratorEngine,b as DocServer}from'./chunk-WQANJ7IA.js';import'./chunk-H4YGP3GL.js';import'./chunk-VV3A3UE3.js';export{a as BaseAnalyzer,d as DataFlowAnalyzer,c as GraphQLAnalyzer,b as PagesAnalyzer}from'./chunk-BPV4UZSW.js';export{b as MarkdownGenerator,a as MermaidGenerator}from'./chunk-XWZH2RDG.js';export{a as PageMapGenerator}from'./chunk-QZWPOG5B.js';import'./chunk-PTR5IROV.js';
@@ -1 +1 @@
1
- export{b as DocServer}from'../chunk-UR7HVBHH.js';import'../chunk-H4YGP3GL.js';import'../chunk-VV3A3UE3.js';import'../chunk-WJIBUCXB.js';import'../chunk-XWZH2RDG.js';import'../chunk-QZWPOG5B.js';import'../chunk-PTR5IROV.js';
1
+ export{b as DocServer}from'../chunk-WQANJ7IA.js';import'../chunk-H4YGP3GL.js';import'../chunk-VV3A3UE3.js';import'../chunk-BPV4UZSW.js';import'../chunk-XWZH2RDG.js';import'../chunk-QZWPOG5B.js';import'../chunk-PTR5IROV.js';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wtdlee/repomap",
3
- "version": "0.5.0",
3
+ "version": "0.6.0",
4
4
  "description": "Interactive documentation generator for code repositories - visualize pages, components, GraphQL operations, and data flows",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -1,2 +0,0 @@
1
- import {Project,Node,SyntaxKind}from'ts-morph';import Q from'fast-glob';import*as b from'path';import*as G from'fs';import*as _ from'fs/promises';import {parse}from'graphql';import {parseSync}from'@swc/core';var w=class{config;basePath;constructor(e){this.config=e,this.basePath=e.path;}resolvePath(e){return `${this.basePath}/${e}`}getSetting(e,t=""){return this.config.settings[e]??t}log(e){console.log(`[${this.getName()}] ${e}`);}warn(e){console.warn(`[${this.getName()}] \u26A0\uFE0F ${e}`);}error(e,t){console.error(`[${this.getName()}] \u274C ${e}`,t?.message||"");}};async function E(F,e,t=8){let s=new Array(F.length).fill(null),i=0;async function o(){for(;i<F.length;){let n=i++;if(n<F.length)try{s[n]=await e(F[n],n);}catch{s[n]=null;}}}let a=Array(Math.min(t,F.length)).fill(null).map(()=>o());return await Promise.all(a),s.filter(n=>n!==null)}var q=class extends w{project;codegenMap=new Map;constructor(e){super(e),this.project=new Project({tsConfigFilePath:this.resolvePath("tsconfig.json"),skipAddingFilesFromTsConfig:true});}extractOperationNameFromGql(e){let t=e.match(/(?:query|mutation|subscription)\s+(\w+)/);if(t&&t[1])return t[1];let s=e.match(/`\s*(?:query|mutation|subscription)\s+(\w+)/);if(s&&s[1])return s[1];let i=e.match(/GraphQL[^`]*`\s*(?:\n\s*)?(?:query|mutation|subscription)\s+(\w+)/);return i&&i[1]?i[1]:null}findOperationNameFromVariable(e,t){let s=e.getVariableDeclaration(t);if(!s){let n=e.getExportedDeclarations().get(t);if(n&&n.length>0){let r=n[0];Node.isVariableDeclaration(r)&&(s=r);}}if(s||(s=e.getVariableDeclarations().find(n=>n.getName()===t)),!s){let a=e.getFullText(),n=[new RegExp(`(?:const|let|var)\\s+${t}\\s*=\\s*gql\\s*\\(\\s*/\\*[^*]*\\*/\\s*\`\\s*(?:query|mutation|subscription)\\s+(\\w+)`,"s"),new RegExp(`(?:const|let|var)\\s+${t}\\s*=\\s*gql\`\\s*(?:query|mutation|subscription)\\s+(\\w+)`,"s"),new RegExp(`(?:const|let|var)\\s+${t}\\s*=\\s*gql\\s*\\(\`\\s*(?:query|mutation|subscription)\\s+(\\w+)`,"s"),new RegExp(`(?:const|let|var)\\s+${t}\\s*=\\s*graphql\\s*\\(\`\\s*(?:query|mutation|subscription)\\s+(\\w+)`,"s")];for(let r of n){let c=a.match(r);if(c&&c[1])return c[1]}return null}let i=s.getInitializer();if(!i)return null;let o=i.getText();return this.extractOperationNameFromGql(o)}getName(){return "PagesAnalyzer"}async analyze(){this.log("Starting page analysis..."),await this.loadCodegenMapping(),await this.analyzeAppFile();let e=await this.findPageFiles();this.log(`Found ${e.length} page files`);for(let i of e)try{this.project.addSourceFileAtPath(i);}catch{}let s=(await E(e,async i=>{let o=this.detectPagesRoot(i);return this.analyzePageFile(i,o)},4)).filter(i=>i!==null);return this.log(`Analyzed ${s.length} pages successfully`),{pages:s}}async analyzePageFile(e,t){let s=this.project.getSourceFile(e);if(!s)return null;let i=b.relative(t,e),o=this.filePathToRoutePath(i),a=this.findPageComponent(s);if(!a)return null;let n=this.extractRouteParams(o),r=this.extractLayout(s),c=this.extractAuthRequirement(s),l=this.extractPermissions(s),g=this.extractDataFetching(s),u=this.extractNavigation(s),m=this.extractLinkedPages(s),P=this.extractSteps(s);return {path:o,filePath:i,component:a,params:n,layout:r,authentication:c,permissions:l,dataFetching:g,navigation:u,linkedPages:m,steps:P.length>0?P:void 0}}detectPagesRoot(e){let t=["/src/pages/","/pages/","/src/app/","/app/","/frontend/src/pages/","/app/javascript/pages/"];for(let s of t){let i=e.indexOf(s);if(i!==-1)return e.substring(0,i+s.length-1)}return this.basePath}filePathToRoutePath(e){return "/"+e.replace(/\.tsx?$/,"").replace(/\/index$/,"").replace(/\[\.\.\.(\w+)\]/g,"*").replace(/\[(\w+)\]/g,":$1")}extractRouteParams(e){let t=[],s=/:(\w+)/g,i;for(;(i=s.exec(e))!==null;)t.push(i[1]);return t}findPageComponent(e){let t=e.getDefaultExportSymbol();if(t){let n=t.getName();if(n!=="default")return n}let s=e.getExportAssignment(n=>!n.isExportEquals());if(s){let n=s.getExpression();if(n){let r=n.getText();if(/^[A-Z][a-zA-Z0-9]*$/.test(r))return r;if(Node.isFunctionExpression(n)||Node.isArrowFunction(n))return "default"}}let i=e.getFunctions();for(let n of i)if(n.isDefaultExport())return n.getName()||"default";if(e.getVariableDeclaration("Page"))return "Page";let a=e.getVariableDeclarations();for(let n of a){let r=n.getTypeNode();if(r){let c=r.getText();if(c.includes("NextPage")||c.includes("FC")||c.includes("React.FC"))return n.getName()}}for(let n of a){let r=n.getName();if(/^[A-Z][a-zA-Z0-9]*$/.test(r)){let c=n.getInitializer();if(c&&(Node.isArrowFunction(c)||Node.isFunctionExpression(c))){let l=c.getText();if(l.includes("return")&&(l.includes("<")||l.includes("jsx")))return r}}}return null}extractLayout(e){let t=e.getDescendantsOfKind(SyntaxKind.PropertyAccessExpression).find(s=>s.getName()==="getLayout");if(t){let s=t.getParent();if(Node.isBinaryExpression(s)){let o=s.getRight().getDescendantsOfKind(SyntaxKind.JsxOpeningElement);if(o.length>0)return o[0].getTagNameNode().getText()}}}extractAuthRequirement(e){let s=e.getFilePath().split("/").pop()||"",a={required:!["404.tsx","permission-denied.tsx","_app.tsx","_document.tsx","_error.tsx"].some(n=>s===n)};try{let n=["RequiredCondition","ProtectedRoute","AuthGuard","PrivateRoute","WithAuth","RequireAuth","Authenticated","Authorized"],r=e.getDescendantsOfKind(SyntaxKind.JsxOpeningElement).find(c=>{let l=c.getTagNameNode().getText();return n.some(g=>l.includes(g))});if(r){a.condition="Additional permissions required";let c=r.getAttributes();for(let l of c)if(l.isKind(SyntaxKind.JsxAttribute))try{let g=l.getNameNode().getText();if(["condition","roles","permissions","requiredRoles","allowedRoles"].includes(g)){let u=l.getInitializer();if(u){a.condition=u.getText();let m=this.extractRolesFromCondition(u.getText());m.length>0&&(a.roles=m);}}}catch{}}}catch{}return a}extractRolesFromCondition(e){let t=[],s=/(\w+Role|\w+Permission)\.(\w+)/g,i;for(;(i=s.exec(e))!==null;)t.push(i[2]);let o=/['"]([a-zA-Z_-]+)['"]/g;for(;(i=o.exec(e))!==null;){let n=i[1];/admin|user|owner|member|guest|manager|editor|viewer/i.test(n)&&t.push(n);}let a=/\b(ROLE_\w+|[A-Z]+_ROLE)\b/g;for(;(i=a.exec(e))!==null;)t.push(i[1]);return [...new Set(t)]}extractPermissions(e){let t=[],s=e.getDescendantsOfKind(SyntaxKind.PropertyAccessExpression).filter(i=>{let o=i.getText();return o.includes("Permission")||o.includes("Role")||o.includes("isAdmin")});for(let i of s){let o=i.getText();t.includes(o)||t.push(o);}return t}extractDataFetching(e){let t=[],s=new Map,i=["useQuery","useMutation","useLazyQuery","useSubscription"];for(let y of e.getImportDeclarations()){let p=y.getModuleSpecifierValue();if(p.includes("@apollo/client")||p.includes("apollo"))for(let f of y.getNamedImports()){let d=f.getName(),h=f.getAliasNode()?.getText()||d;i.includes(d)&&s.set(h,d);}}let o=s.size>0||e.getImportDeclarations().some(y=>{let p=y.getModuleSpecifierValue();return p.includes("@apollo/client")||p.includes("apollo")}),a=e.getDescendantsOfKind(SyntaxKind.CallExpression).filter(y=>{let p=y.getExpression().getText();return !!(s.has(p)||i.includes(p)||/^use[A-Z].*Query$/.test(p)&&!p.includes("Params")&&!p.includes("String")||/^use[A-Z].*Mutation$/.test(p))});for(let y of a){let p=y.getExpression().getText(),f;s.has(p)?f=s.get(p):p.includes("Mutation")?f="useMutation":p.includes("Lazy")?f="useLazyQuery":f="useQuery";let d=y.getArguments();if(d.length===0){if(/^use[A-Z]/.test(p)){let C=p.replace(/^use/,"").replace(/Query$|Mutation$/,"");t.push({type:f,operationName:C,variables:[]});}continue}let x=d[0].getText();if(x.startsWith("[")||x.startsWith("{")||x.startsWith("'")||x.startsWith('"')||x.startsWith("`")||!(o||x.endsWith("Document")||x.endsWith("Query")||x.endsWith("Mutation")||x.includes("gql")||/^[A-Z_]+$/.test(x)))continue;let v=x.replace(/Document$/,"").replace(/Query$|Mutation$/,""),N=[];if(d.length>1){let $=d[1].getDescendantsOfKind(SyntaxKind.PropertyAssignment).find(T=>{try{return T.getName()==="variables"}catch{return false}});if($){let T=$.getInitializer();if(T){let z=T.getDescendantsOfKind(SyntaxKind.PropertyAssignment);for(let H of z)try{N.push(H.getName());}catch{}}}}t.push({type:f,operationName:v,variables:N});}let n=e.getVariableDeclaration("getServerSideProps"),r=e.getFunction("getServerSideProps"),c=n||r;if(c){let y=e.getImportDeclarations();for(let d of y){let h=d.getNamedImports();for(let x of h){let S=x.getName();if(S.endsWith("Document")&&e.getDescendantsOfKind(SyntaxKind.Identifier).filter(N=>N.getText()===S).length>0){let N=S.replace(/Document$/,"");t.push({type:"getServerSideProps",operationName:`\u2192 ${N}`});}}}let f=c.getText().match(/query:\s*(\w+)/g);if(f)for(let d of f){let h=d.replace(/query:\s*/,"");t.some(x=>x.operationName?.includes(h.replace(/Document$/,"")))||t.push({type:"getServerSideProps",operationName:`\u2192 ${h.replace(/Document$/,"")}`});}}let l=e.getVariableDeclaration("getStaticProps"),g=e.getFunction("getStaticProps");(l||g)&&t.push({type:"getStaticProps",operationName:"getStaticProps"});let u=e.getImportDeclarations(),m=e.getFilePath(),P=b.dirname(m);for(let y of u){let p=y.getModuleSpecifierValue(),f=p.startsWith(".")||p.startsWith("/"),d=!p.includes("node_modules")&&!p.startsWith("@types/")&&p.startsWith("@")===false;if(f||d){if(p.includes("__generated__")||p.includes("/generated/"))continue;let h=[],x=y.getNamedImports();for(let v of x){let N=v.getName();this.isComponentName(N)&&h.push(N);}let S=y.getDefaultImport();if(S){let v=S.getText();this.isComponentName(v)&&h.push(v);}for(let v of h){let N=this.analyzeImportedComponent(P,p,v);if(N.length>0)for(let C of N)t.push({type:C.type,operationName:C.operationName.startsWith("\u2192")?`\u2192 ${C.operationName} (${v})`:`\u2192 ${C.operationName} (${v})`,variables:C.variables});else t.push({type:"component",operationName:v,variables:[]});}}}return t}symbolTraceCache=new Map;analyzeImportedComponent(e,t,s,i=new Set,o=0){if(o>10)return [];let n=[];try{let r=b.resolve(e,t),c=`${r}:${s}`;if(i.has(c))return [];i.add(c);let l=this.symbolTraceCache.get(c);if(l!==void 0)return l;let g=[`${r}.tsx`,`${r}.ts`,`${r}/index.tsx`,`${r}/index.ts`,`${r}/${s}.tsx`,`${r}/${s}.ts`],u,m;for(let p of g)try{if(u=this.project.addSourceFileAtPath(p),u){m=p;break}}catch{}if(!u||!m)return n;if(m.endsWith("index.tsx")||m.endsWith("index.ts")){let p=this.followReExport(u,s,b.dirname(m));p&&(u=p);}let P=u.getImportDeclarations().some(p=>{let f=p.getModuleSpecifierValue();return f.includes("@apollo/client")||f.includes("apollo")||f.includes("gql")||f.includes("graphql")||f.includes("__generated__")}),y=u.getImportDeclarations().filter(p=>{let f=p.getModuleSpecifierValue();return f.startsWith("./")||f.startsWith("../")});for(let p of y){let f=p.getModuleSpecifierValue(),d=p.getNamedImports().map(h=>h.getName()).filter(h=>/^use[A-Z]/.test(h));for(let h of d){let x=this.analyzeCustomHook(b.dirname(u.getFilePath()),f,h,i,o+1);n.push(...x);}}for(let p of y){let f=p.getModuleSpecifierValue(),d=p.getNamedImports().map(S=>S.getName()),h=p.getDefaultImport()?.getText(),x=d.filter(S=>/^[A-Z]/.test(S)&&this.isComponentName(S));for(let S of x){let v=this.analyzeImportedComponent(b.dirname(u.getFilePath()),f,S,i,o+1);n.push(...v);}if(h&&/^[A-Z]/.test(h)&&this.isComponentName(h)){let S=this.analyzeImportedComponent(b.dirname(u.getFilePath()),f,h,i,o+1);n.push(...S);}}if(P){let p=u.getDescendantsOfKind(SyntaxKind.CallExpression).filter(f=>{let d=f.getExpression().getText();return ["useQuery","useMutation","useLazyQuery","useSubscription"].includes(d)});for(let f of p){let d=f.getExpression().getText(),h=f.getArguments();if(h.length===0)continue;let S=h[0].getText(),v=S,N=null,C=this.resolveDocumentName(S);if(C)v=C.operationName,N=C.operationType;else if(S.endsWith("Document"))v=S.replace(/Document$/,"");else if(/^[A-Za-z]/.test(S)){let T=this.findOperationNameFromVariable(u,S);if(T&&(v=T),v===S&&S!=="Query"&&S!=="Mutation"){let z=S.match(/^(.+?)(Query|Mutation|Subscription)$/);z&&(v=z[1]);}}v!=="Query"&&v!=="Mutation"&&(v=v.replace(/Document$/,"").replace(/Query$|Mutation$/,"")||v),(v==="Query"||v==="Mutation"||v==="")&&v===""&&(v=S||"Unknown");let $=N?N==="mutation"?"useMutation":N==="subscription"?"useSubscription":d.includes("Lazy")?"useLazyQuery":"useQuery":d.includes("Mutation")?"useMutation":d.includes("Lazy")?"useLazyQuery":"useQuery";n.push({type:$,operationName:v,variables:[]});}}this.symbolTraceCache.set(c,n);}catch{}return n}analyzeCustomHook(e,t,s,i=new Set,o=0){if(o>10)return [];let n=[];try{let r=b.resolve(e,t),c=`hook:${r}:${s}`;if(i.has(c))return [];i.add(c);let l=this.symbolTraceCache.get(c);if(l!==void 0)return l;let g=[`${r}.tsx`,`${r}.ts`,`${r}/${s}.tsx`,`${r}/${s}.ts`,`${r}/index.tsx`,`${r}/index.ts`],u;for(let p of g)try{if(u=this.project.addSourceFileAtPath(p),u)break}catch{}if(!u)return n;let m=u.getImportDeclarations().some(p=>{let f=p.getModuleSpecifierValue();return f.includes("@apollo/client")||f.includes("apollo")||f.includes("graphql")||f.includes("__generated__")}),P=u.getImportDeclarations().filter(p=>{let f=p.getModuleSpecifierValue();return f.startsWith("./")||f.startsWith("../")});for(let p of P){let f=p.getModuleSpecifierValue(),d=p.getNamedImports().map(h=>h.getName()).filter(h=>/^use[A-Z]/.test(h));for(let h of d){let x=this.analyzeCustomHook(b.dirname(u.getFilePath()),f,h,i,o+1);n.push(...x);}}if(!m&&n.length===0)return n;let y=u.getDescendantsOfKind(SyntaxKind.CallExpression).filter(p=>{let f=p.getExpression().getText();return ["useQuery","useMutation","useLazyQuery","useSubscription"].includes(f)});for(let p of y){let f=p.getExpression().getText(),d=p.getArguments();if(d.length===0)continue;let h=d[0].getText(),x=h,S=null,v=this.resolveDocumentName(h);if(v)x=v.operationName,S=v.operationType;else if(h.endsWith("Document"))x=h.replace(/Document$/,"");else if(/^[A-Za-z]/.test(h)){let C=this.findOperationNameFromVariable(u,h);if(C&&(x=C),x===h&&h!=="Query"&&h!=="Mutation"){let $=h.match(/^(.+?)(Query|Mutation|Subscription)$/);$&&(x=$[1]);}}x!=="Query"&&x!=="Mutation"&&(x=x.replace(/Document$/,"").replace(/Query$|Mutation$/,"")||x),x===""&&(x=h||"Unknown");let N=S?S==="mutation"?"useMutation":S==="subscription"?"useSubscription":f.includes("Lazy")?"useLazyQuery":"useQuery":f.includes("Mutation")?"useMutation":f.includes("Lazy")?"useLazyQuery":"useQuery";n.push({type:N,operationName:`\u2192 ${x} (via ${s})`,variables:[]});}this.symbolTraceCache.set(c,n);}catch{}return n}globalContextQueries=[];async findPageFiles(){let e=this.getSetting("pagesDir","src/pages"),t=[],i=[...new Set([e,"pages","src/pages","app","src/app"])];for(let n of i){if(n==="app"||n==="src/app"){let c=["controllers","models","views","helpers"],l=this.resolvePath(n);if(c.some(u=>{try{return G.existsSync(b.join(l,u))}catch{return false}}))continue}let r=this.resolvePath(n);try{let c=await Q(["**/*.tsx","**/*.ts","**/*.jsx","**/*.js"],{cwd:r,ignore:["_app.tsx","_app.ts","_app.jsx","_app.js","_document.tsx","_document.ts","_document.jsx","_document.js","_error.tsx","_error.ts","_error.jsx","_error.js","api/**","**/*.test.*","**/*.spec.*","**/node_modules/**","**/components/pages/**"],absolute:!0});t.push(...c),c.length>0&&this.log(`Found ${c.length} pages in ${n}`);}catch{}}let o=["frontend/src/**/pages","app/javascript/**/pages"];for(let n of o)try{let r=await Q([`${n}/**/*.tsx`,`${n}/**/*.ts`,`${n}/**/*.jsx`,`${n}/**/*.js`],{cwd:this.basePath,ignore:["**/*.test.*","**/*.spec.*","**/node_modules/**","**/vendor/**","**/components/pages/**","**/stories/**"],absolute:!0});t.push(...r),r.length>0&&this.log(`Found ${r.length} React pages in ${n}`);}catch{}let a=["frontend/src/**/index.tsx","frontend/src/**/App.tsx","app/javascript/packs/*.tsx","app/javascript/packs/*.jsx"];for(let n of a)try{let r=await Q([n],{cwd:this.basePath,ignore:["**/node_modules/**","**/vendor/**"],absolute:!0});for(let c of r)t.includes(c)||t.push(c);}catch{}return [...new Set(t)]}async analyzeAppFile(){let e=this.getSetting("pagesDir","src/pages"),t=[this.resolvePath(`${e}/_app.tsx`),this.resolvePath(`${e}/_app.ts`)];for(let s of t)try{let i=this.project.addSourceFileAtPath(s);if(!i)continue;let o=i.getDescendantsOfKind(SyntaxKind.JsxElement),a=i.getDescendantsOfKind(SyntaxKind.JsxSelfClosingElement),n=new Set;for(let r of [...o,...a]){let c=r.getFirstDescendantByKind(SyntaxKind.Identifier)?.getText();c&&(c.includes("Provider")||c.includes("Context"))&&n.add(c);}for(let r of i.getImportDeclarations()){let c=r.getModuleSpecifierValue();if(!c.startsWith("./")&&!c.startsWith("../"))continue;let l=r.getNamedImports().map(u=>u.getName()),g=r.getDefaultImport()?.getText();for(let u of n)if(l.includes(u)||g===u){let m=this.analyzeImportedComponent(b.dirname(s),c,u,new Set,0);for(let P of m)this.globalContextQueries.push({...P,operationName:`[Global] ${P.operationName}`});}}this.globalContextQueries.length>0&&this.log(`Found ${this.globalContextQueries.length} global context queries from _app`);return}catch{}}async loadCodegenMapping(){let e=["__generated__","src/__generated__","src/__generated__/gql-graphql-gateway","generated","src/generated"];for(let t of e){let s=this.resolvePath(t);try{let i=await Q(["**/*.ts","**/*.tsx"],{cwd:s,absolute:!0,onlyFiles:!0});for(let o of i)try{let a=this.project.addSourceFileAtPath(o),n=a.getVariableDeclarations();for(let c of n){let l=c.getName();if(l.endsWith("Document")){let g=c.getInitializer()?.getText()??"",u=g.match(/(?:query|mutation|subscription)\s+(\w+)/),m=g.match(/(query|mutation|subscription)\s+/);u&&this.codegenMap.set(l,{operationName:u[1],operationType:m?m[1]:"query"});}}let r=a.getTypeAliases();for(let c of r){let l=c.getName();if((l.endsWith("Query")||l.endsWith("Mutation")||l.endsWith("Subscription"))&&!l.endsWith("Variables")){let g=l+"Document";if(!this.codegenMap.has(g)){let u=l.endsWith("Mutation")?"mutation":l.endsWith("Subscription")?"subscription":"query";this.codegenMap.set(g,{operationName:l,operationType:u});}}}}catch{}if(this.codegenMap.size>0){this.log(`Loaded ${this.codegenMap.size} codegen mappings from ${t}`);return}}catch{}}}resolveDocumentName(e){if(new Set(["Query","Mutation","Subscription"]).has(e))return null;let s=this.codegenMap.get(e);if(s!==void 0)return s;let i=e.endsWith("Document")?e:e+"Document",o=this.codegenMap.get(i);return o!==void 0?o:null}followReExport(e,t,s){try{let i=e.getExportDeclarations(),o=null;for(let a of i){let n=a.getNamedExports();for(let r of n){let c=a.getModuleSpecifierValue();if(!c)continue;let l=b.resolve(s,c),g=[`${l}.tsx`,`${l}.ts`,`${l}/index.tsx`,`${l}/index.ts`],u;for(let m of g)try{if(u=this.project.addSourceFileAtPath(m),u)break}catch{}if(u&&(o||(o=u),r.getName()===t||r.getAliasNode()?.getText()===t))return u}}if(o)return o;for(let a of e.getExportDeclarations())if(a.isNamespaceExport()){let n=a.getModuleSpecifierValue();if(n){let r=b.resolve(s,n),c=[`${r}.tsx`,`${r}.ts`];for(let l of c)try{let g=this.project.addSourceFileAtPath(l);if(g&&g.getExportedDeclarations().has(t))return g}catch{}}}}catch{}return null}isComponentName(e){return !/^[A-Z]/.test(e)||e.endsWith("Query")||e.endsWith("Mutation")||e.endsWith("Subscription")||e.endsWith("Fragment")||e.endsWith("Document")||e.endsWith("Variables")||e==="Query"||e==="Mutation"||e==="Subscription"||new Set(["NextPage","NextPageContext","NextApiRequest","NextApiResponse","GetServerSideProps","GetStaticProps","GetStaticPaths","InferGetServerSidePropsType","InferGetStaticPropsType","FC","FunctionComponent","VFC","Component","PureComponent","ReactNode","ReactElement","PropsWithChildren","ComponentProps","ComponentType","ElementType","RefObject","MutableRefObject","Dispatch","SetStateAction","ChangeEvent","MouseEvent","KeyboardEvent","FormEvent","SyntheticEvent"]).has(e)?false:!!(["Container","Page","Screen","View","Form","Modal","Dialog","Panel","Root","Provider","Wrapper"].some(i=>e.endsWith(i))||/Page[A-Z]?\w*$/.test(e)||/Container[A-Z]?\w*$/.test(e)||/^[A-Z][a-z]+[A-Z][a-z]+/.test(e))}extractNavigation(e){let t={visible:true,currentNavItem:null};try{let s=e.getDescendantsOfKind(SyntaxKind.PropertyAccessExpression).find(i=>{try{return i.getName()==="globalNavigationStyle"}catch{return !1}});if(s){let i=s.getParent();if(Node.isBinaryExpression(i)){let o=i.getRight(),a=o.getDescendantsOfKind(SyntaxKind.PropertyAssignment).find(c=>{try{return c.getName()==="visible"}catch{return !1}});a&&(t.visible=a.getInitializer()?.getText()==="true");let n=o.getDescendantsOfKind(SyntaxKind.PropertyAssignment).find(c=>{try{return c.getName()==="currentNavItem"}catch{return !1}});if(n){let c=n.getInitializer()?.getText();t.currentNavItem=c&&c!=="null"?c.replace(/['"]/g,""):null;}let r=o.getDescendantsOfKind(SyntaxKind.PropertyAssignment).find(c=>{try{return c.getName()==="mini"}catch{return !1}});r&&(t.mini=r.getInitializer()?.getText()==="true");}}}catch{}return t}extractSteps(e){let t=[],s=e.getDescendantsOfKind(SyntaxKind.CallExpression).filter(a=>a.getExpression().getText()==="useState");for(let a of s){let n=a.getParent();if(!n)continue;let c=n.getText().match(/\[\s*(step|currentStep|activeStep|page|currentPage|phase|stage)\s*,/i);if(c){let l=c[1],g=e.getDescendantsOfKind(SyntaxKind.SwitchStatement);for(let m of g)m.getExpression().getText().includes(l)&&m.getClauses().forEach((p,f)=>{if(p.isKind(SyntaxKind.CaseClause)){let d=p.getExpression()?.getText()||String(f),h=p.getDescendantsOfKind(SyntaxKind.JsxOpeningElement),x=h.length>0?h[0].getTagNameNode().getText():void 0;t.push({id:d.replace(/['"]/g,""),name:`Step ${d.replace(/['"]/g,"")}`,component:x});}});let u=e.getDescendantsOfKind(SyntaxKind.ArrayLiteralExpression);for(let m of u){let P=m.getParent();P&&P.getText().match(/steps|pages|screens|views|components/i)&&m.getElements().forEach((p,f)=>{let d=p.getText();if(d.startsWith("{")){let h=d.match(/(?:name|label|title)\s*:\s*['"]([^'"]+)['"]/),x=d.match(/(?:component|content)\s*:\s*<?\s*(\w+)/);t.push({id:f+1,name:h?h[1]:`Step ${f+1}`,component:x?x[1]:void 0});}else /^[A-Z]/.test(d)&&t.push({id:f+1,name:d,component:d});});}}}let i=e.getDescendantsOfKind(SyntaxKind.JsxOpeningElement);for(let a of i)if(a.getTagNameNode().getText().match(/Stepper|Wizard|Steps|TabPanel|FormStep/i)){let r=a.getParent();r&&r.isKind(SyntaxKind.JsxElement)&&r.getJsxChildren().forEach((l,g)=>{if(l.isKind(SyntaxKind.JsxElement)||l.isKind(SyntaxKind.JsxSelfClosingElement)){let u=l.isKind(SyntaxKind.JsxElement)?l.getOpeningElement().getTagNameNode().getText():l.getTagNameNode().getText(),m=l.isKind(SyntaxKind.JsxElement)?l.getOpeningElement().getAttributes():l.getAttributes(),P=u;for(let y of m)if(y.isKind(SyntaxKind.JsxAttribute)){let p=y.getNameNode().getText();if(p==="label"||p==="title"||p==="name"){let f=y.getInitializer()?.getText();if(f){P=f.replace(/['"{}]/g,"");break}}}t.push({id:g+1,name:P,component:u});}});}let o=e.getDescendantsOfKind(SyntaxKind.ConditionalExpression);for(let a of o){let n=a.getCondition().getText();if(n.match(/step\s*===?\s*\d+|currentStep|activeStep/i)){let r=a.getWhenTrue(),c=n.match(/===?\s*(\d+)/);if(c&&t.length===0){let l=r.getDescendantsOfKind(SyntaxKind.JsxOpeningElement);l.length>0&&t.push({id:parseInt(c[1]),component:l[0].getTagNameNode().getText()});}}}return t}extractLinkedPages(e){let t=[],s=e.getDescendantsOfKind(SyntaxKind.CallExpression).filter(o=>{let a=o.getExpression().getText();return a.includes("router.push")||a.includes("router.replace")||a.includes("Link")});for(let o of s){let a=o.getArguments();if(a.length>0){let r=a[0].getText().match(/['"`]([^'"`]+)['"`]/);r&&!t.includes(r[1])&&t.push(r[1]);}}let i=e.getDescendantsOfKind(SyntaxKind.JsxOpeningElement).filter(o=>o.getTagNameNode().getText()==="Link");for(let o of i)try{let a=o.getAttributes();for(let n of a)if(n.isKind(SyntaxKind.JsxAttribute)&&n.getNameNode().getText()==="href"){let l=n.getInitializer()?.getText();if(l){let g=l.match(/['"`]([^'"`]+)['"`]/);g&&!t.includes(g[1])&&t.push(g[1]);}}}catch{}return t}};var j=class extends w{project;constructor(e){super(e),this.project=new Project({tsConfigFilePath:this.resolvePath("tsconfig.json"),skipAddingFilesFromTsConfig:true});}getName(){return "GraphQLAnalyzer"}async analyze(){this.log("Starting GraphQL analysis...");let e=[];this.log("[GraphQLAnalyzer] Step 1: Analyzing .graphql files...");let t=await this.analyzeGraphQLFiles();e.push(...t),this.log(`[GraphQLAnalyzer] Step 1 done: ${t.length} from .graphql files`),this.log("[GraphQLAnalyzer] Step 2: Analyzing inline GraphQL...");let s=await this.analyzeInlineGraphQL();e.push(...s),this.log(`[GraphQLAnalyzer] Step 2 done: ${s.length} inline operations`),this.log("[GraphQLAnalyzer] Step 3: Analyzing codegen output...");let i=await this.analyzeCodegenGenerated();e.push(...i),this.log(`[GraphQLAnalyzer] Step 3 done: ${i.length} from codegen`);let o=this.deduplicateOperations(e);return this.log(`[GraphQLAnalyzer] Deduplicated: ${o.length} unique operations`),this.log("[GraphQLAnalyzer] Step 4: Finding operation usage..."),await this.findOperationUsage(o),this.log("[GraphQLAnalyzer] Step 4 done"),this.log(`Found ${o.length} GraphQL operations`),{graphqlOperations:o}}deduplicateOperations(e){let t=new Map;for(let s of e)if(!t.has(s.name))t.set(s.name,s);else {let i=t.get(s.name);if(i)for(let o of s.usedIn)i.usedIn.includes(o)||i.usedIn.push(o);}return Array.from(t.values())}async analyzeCodegenGenerated(){let e=[],t=await Q(["**/__generated__/graphql.ts","**/__generated__/gql.ts","**/generated/graphql.ts"],{cwd:this.basePath,ignore:["**/node_modules/**","**/.next/**"],absolute:true});for(let s of t)try{let i=await _.readFile(s,"utf-8"),o=b.relative(this.basePath,s),a=i.split(`
2
- `);for(let n of a){if(!n.includes("Document =")||!n.includes("DocumentNode"))continue;let r=n.match(/export\s+const\s+(\w+Document)\s*=\s*(\{"kind":"Document".+\})\s*as\s+unknown\s+as\s+DocumentNode/);if(!r)continue;let c=r[1],l=r[2];try{let g=JSON.parse(l);if(g.kind==="Document"&&g.definitions){let u=g.definitions[0];if(u?.kind==="OperationDefinition"){let m=u.name?.value||c.replace(/Document$/,""),P=u.operation,y=(u.variableDefinitions||[]).map(p=>({name:p.variable?.name?.value||"unknown",type:this.extractTypeFromAst(p.type),required:p.type?.kind==="NonNullType"}));e.push({name:m,type:P,filePath:o,usedIn:[],variables:y,returnType:this.inferReturnTypeFromAst(u),fragments:this.extractFragmentReferencesFromAst(u),fields:this.extractFieldsFromAst(u.selectionSet)});}}}catch{}}this.log(`Found ${e.length} operations in codegen output: ${o}`);}catch(i){this.warn(`Failed to analyze codegen file ${s}: ${i.message}`);}return e}extractTypeFromAst(e){return e?e.kind==="NonNullType"?`${this.extractTypeFromAst(e.type)}!`:e.kind==="ListType"?`[${this.extractTypeFromAst(e.type)}]`:e.kind==="NamedType"&&e.name?.value||"unknown":"unknown"}extractFieldsFromAst(e,t=0){if(!e?.selections||t>5)return [];let s=[];for(let i of e.selections)if(i.kind==="Field"){let o={name:i.name?.value||"unknown"};if(i.arguments?.length>0){let a=i.arguments.map(n=>n.name?.value).join(", ");o.type=`(${a})`;}i.selectionSet&&(o.fields=this.extractFieldsFromAst(i.selectionSet,t+1)),s.push(o);}else if(i.kind==="FragmentSpread")s.push({name:`...${i.name?.value}`,type:"fragment"});else if(i.kind==="InlineFragment"){let o=i.typeCondition?.name?.value||"inline";s.push({name:`... on ${o}`,type:"inline-fragment",fields:this.extractFieldsFromAst(i.selectionSet,t+1)});}return s}extractFragmentReferencesFromAst(e){let t=[],s=i=>{if(i&&(i.kind==="FragmentSpread"&&t.push(i.name?.value),i.selectionSet?.selections))for(let o of i.selectionSet.selections)s(o);};return s(e),t.filter(Boolean)}inferReturnTypeFromAst(e){if(e.selectionSet?.selections?.length>0){let t=e.selectionSet.selections[0];if(t.kind==="Field")return t.name?.value||"unknown"}return "unknown"}async analyzeGraphQLFiles(){let e=await Q(["**/*.graphql"],{cwd:this.basePath,ignore:["**/node_modules/**","**/.next/**"],absolute:true});return (await E(e,async s=>{let i=await _.readFile(s,"utf-8"),o=parse(i);return this.extractOperationsFromDocument(o,b.relative(this.basePath,s))})).flat()}async analyzeInlineGraphQL(){let e=[],t=await Q(["**/*.ts","**/*.tsx"],{cwd:this.basePath,ignore:["**/node_modules/**","**/.next/**","**/__tests__/**","**/*.test.*","**/*.spec.*"],absolute:true});for(let s of t)try{let i=this.project.addSourceFileAtPath(s),o=b.relative(this.basePath,s),a=i.getImportDeclarations().some(c=>{let l=c.getModuleSpecifierValue(),g=c.getNamedImports().map(m=>m.getName()),u=c.getDefaultImport()?.getText();return (g.includes("gql")||g.includes("graphql")||u==="gql")&&(l.includes("graphql")||l.includes("apollo")||l.includes("gql")||l.includes("__generated__"))}),n=i.getDescendantsOfKind(SyntaxKind.TaggedTemplateExpression);for(let c of n){let l=c.getTag().getText();if(l==="gql"||l==="graphql")try{let g=c.getTemplate(),u="";if(g.isKind(SyntaxKind.NoSubstitutionTemplateLiteral)?u=g.getLiteralValue():g.isKind(SyntaxKind.TemplateExpression)&&(u=g.getText().slice(1,-1).replace(/\$\{[^}]*\}/g,"")),u&&u.trim())try{let m=parse(u),P=this.extractOperationsFromDocument(m,o);e.push(...P);}catch{}}catch{}}let r=i.getDescendantsOfKind(SyntaxKind.CallExpression);for(let c of r)try{let g=c.getExpression().getText();if(g==="gql"||g==="graphql"){let u=c.getArguments();if(u.length>0){let m=u[0],P="";if(m.isKind(SyntaxKind.NoSubstitutionTemplateLiteral))P=m.getLiteralValue();else if(m.isKind(SyntaxKind.TemplateExpression))P=m.getText().slice(1,-1).replace(/\$\{[^}]*\}/g,"");else {let y=m.getText();if(y.includes("`")){let p=y.match(/\/\*\s*GraphQL\s*\*\/\s*`([^`]*)`/);if(p)P=p[1];else {let f=y.match(/`([^`]*)`/);f&&(P=f[1]);}}}if(P&&P.trim())try{let y=parse(P),p=this.extractOperationsFromDocument(y,o),f=this.extractVariableNameFromCall(c);if(f)for(let d of p)d.variableNames=d.variableNames||[],d.variableNames.push(f),d.variableNames.push(`${d.name}Document`);e.push(...p);}catch{}}}}catch{}if(a){let c=i.getVariableDeclarations();for(let l of c){let g=l.getName();if(g.includes("QUERY")||g.includes("MUTATION")||g.includes("FRAGMENT")||g.includes("Query")||g.includes("Mutation")||g.includes("Subscription")||/^[A-Z_]+_(QUERY|MUTATION|FRAGMENT|SUBSCRIPTION)$/.test(g)||/Query$|Mutation$|Fragment$|Subscription$/.test(g)){let m=l.getInitializer();m&&m.isKind(SyntaxKind.CallExpression);}}}}catch(i){this.warn(`Failed to analyze ${s}: ${i.message}`);}return e}extractVariableNameFromCall(e){try{let t=e.getParent();for(;t;){if(t.isKind?.(SyntaxKind.VariableDeclaration))return t.getName?.()||null;t=t.getParent?.();}}catch{}return null}extractOperationsFromDocument(e,t){let s=[];for(let i of e.definitions){let o=this.extractOperation(i,t);o&&s.push(o);}return s}extractOperation(e,t){if(e.kind==="OperationDefinition"){let s=e.name?.value||"anonymous",i=e.operation,o=this.extractVariables(e),a=this.extractFragmentReferences(e),n=this.extractFields(e);return {name:s,type:i,filePath:t,usedIn:[],variables:o,returnType:this.inferReturnType(e),fragments:a,fields:n}}return e.kind==="FragmentDefinition"?{name:e.name.value,type:"fragment",filePath:t,usedIn:[],variables:[],returnType:e.typeCondition.name.value,fragments:this.extractFragmentReferences(e),fields:this.extractFields(e)}:null}extractFields(e){let t=[],s=(i,o=0)=>{if(!i||!i.selections||o>5)return [];let a=[];for(let n of i.selections)if(n.kind==="Field"){let r={name:n.name.value};if(n.arguments&&n.arguments.length>0){let c=n.arguments.map(l=>l.name.value).join(", ");r.type=`(${c})`;}n.selectionSet&&(r.fields=s(n.selectionSet,o+1)),a.push(r);}else if(n.kind==="FragmentSpread")a.push({name:`...${n.name.value}`,type:"fragment"});else if(n.kind==="InlineFragment"&&n.selectionSet){let r=n.typeCondition?.name?.value||"inline";a.push({name:`... on ${r}`,type:"inline-fragment",fields:s(n.selectionSet,o+1)});}return a};return e.selectionSet?s(e.selectionSet):t}extractVariables(e){let t=[];if(e.variableDefinitions)for(let s of e.variableDefinitions){let i=s.variable.name.value,o=this.typeNodeToString(s.type),a=s.type.kind==="NonNullType";t.push({name:i,type:o,required:a});}return t}typeNodeToString(e){return e.kind==="NonNullType"?`${this.typeNodeToString(e.type)}!`:e.kind==="ListType"?`[${this.typeNodeToString(e.type)}]`:e.kind==="NamedType"?e.name.value:"unknown"}extractFragmentReferences(e){let t=[],s=i=>{if(i&&(i.kind==="FragmentSpread"&&t.push(i.name.value),i.selectionSet))for(let o of i.selectionSet.selections)s(o);};return s(e),t}inferReturnType(e){if(e.selectionSet&&e.selectionSet.selections.length>0){let t=e.selectionSet.selections[0];if(t.kind==="Field")return t.name.value}return "unknown"}async findOperationUsage(e){if(e.length===0)return;let t=await Q(["**/*.ts","**/*.tsx"],{cwd:this.basePath,ignore:["**/node_modules/**","**/.next/**","**/__generated__/**"],absolute:true}),s=new Map,i=new Map,o=new Map;for(let l of e)if(s.set(l.name,l),i.set(`${l.name}Document`,l),l.variableNames)for(let g of l.variableNames)o.set(g,l);let a=new Set;for(let l of e)if(a.add(`${l.name}Document`),l.variableNames)for(let g of l.variableNames)a.add(g);let n=null,r=Array.from(a);if(r.length>0&&r.length<2e3){let l=r.sort((g,u)=>u.length-g.length).map(g=>g.replace(/[.*+?^${}()|[\]\\]/g,"\\$&"));n=new RegExp(`\\b(${l.join("|")})\\b`,"g");}let c=50;for(let l=0;l<t.length;l+=c){let g=t.slice(l,l+c);await Promise.all(g.map(async u=>{try{let m=await _.readFile(u,"utf-8"),P=b.relative(this.basePath,u);if(!m.includes("Document")&&!m.includes("useQuery")&&!m.includes("useMutation")&&!m.includes("Query")&&!m.includes("Mutation")&&!m.includes("GET_")&&!m.includes("SEARCH_")&&!m.includes("CREATE_")&&!m.includes("UPDATE_")&&!m.includes("DELETE_"))return;if(n){let y=new Set,p;for(;(p=n.exec(m))!==null;)y.add(p[1]);n.lastIndex=0;for(let f of y){let d=i.get(f)||o.get(f);d&&P!==d.filePath&&(d.usedIn.includes(P)||d.usedIn.push(P));}}for(let[y,p]of s)P!==p.filePath&&(p.usedIn.includes(P)||(m.includes(`useQuery<${y}`)||m.includes(`useMutation<${y}`)||m.includes(`useLazyQuery<${y}`)||m.includes(`useSubscription<${y}`)||m.includes(`${y}Query`)||m.includes(`${y}Mutation`))&&p.usedIn.push(P));}catch{}}));}}};var W=class extends w{componentCache=new Map;constructor(e){super(e);}getName(){return "DataFlowAnalyzer"}async analyze(){this.log("Starting data flow analysis...");let e=await this.analyzeComponents(),t=await this.analyzeDataFlows(e);return this.log(`Analyzed ${e.length} components and ${t.length} data flows`),{components:e,dataFlows:t}}async analyzeComponents(){let e=[],t=[this.getSetting("featuresDir",""),this.getSetting("componentsDir",""),this.getSetting("pagesDir","")].filter(Boolean),s=["src/features","src/components","src/common/components","src/common","src/pages","src/app","src/modules","src/views","src/screens","components","pages","app"],o=[...new Set([...t,...s])].map(r=>`${r}/**/*.tsx`),a=await Q(o,{cwd:this.basePath,ignore:["**/*.test.*","**/*.spec.*","**/*.stories.*","**/node_modules/**","**/__generated__/**"],absolute:true,onlyFiles:true,unique:true});this.log(`[DataFlowAnalyzer] Found ${a.length} component files to analyze`);let n=100;for(let r=0;r<a.length;r+=n){let c=a.slice(r,r+n),l=await Promise.all(c.map(async g=>{try{let u=await _.readFile(g,"utf-8");return {filePath:g,content:u}}catch{return null}}));for(let g of l)if(g)try{let u=parseSync(g.content,{syntax:"typescript",tsx:!0,comments:!1}),m=b.relative(this.basePath,g.filePath),P=this.analyzeComponentFile(u,m,g.content);e.push(...P);}catch{}}return this.log(`[DataFlowAnalyzer] Extracted ${e.length} components`),this.buildDependencyGraph(e),e}analyzeComponentFile(e,t,s){let i=[],o=this.extractImports(e);for(let a of e.body){if(a.type==="ExportDeclaration"&&a.declaration?.type==="FunctionDeclaration"){let n=a.declaration.identifier?.value;if(n&&this.isComponentName(n)){let r=this.extractComponentInfo(n,t,s,o);i.push(r),this.componentCache.set(n,r);}}if(a.type==="FunctionDeclaration"){let n=a.identifier?.value;if(n&&this.isComponentName(n)){let r=this.extractComponentInfo(n,t,s,o);i.push(r),this.componentCache.set(n,r);}}if(a.type==="ExportDefaultDeclaration"&&a.decl?.type==="FunctionExpression"){let n=a.decl.identifier?.value;if(n&&this.isComponentName(n)){let r=this.extractComponentInfo(n,t,s,o);i.push(r),this.componentCache.set(n,r);}}if(a.type==="VariableDeclaration"){for(let n of a.declarations)if(n.id?.type==="Identifier"){let r=n.id.value;if(r&&(this.isComponentName(r)||r.startsWith("use"))&&n.init&&(n.init.type==="ArrowFunctionExpression"||n.init.type==="FunctionExpression")){let c=this.extractComponentInfo(r,t,s,o);i.push(c),this.componentCache.set(r,c);}}}if(a.type==="ExportDeclaration"&&a.declaration?.type==="VariableDeclaration"){for(let n of a.declaration.declarations)if(n.id?.type==="Identifier"){let r=n.id.value;if(r&&(this.isComponentName(r)||r.startsWith("use"))&&n.init&&(n.init.type==="ArrowFunctionExpression"||n.init.type==="FunctionExpression")){let c=this.extractComponentInfo(r,t,s,o);i.push(c),this.componentCache.set(r,c);}}}}return i}extractImports(e){let t=new Map;for(let s of e.body)if(s.type==="ImportDeclaration"){let i=s.source?.value||"";if(i.startsWith(".")||i.startsWith("@/"))for(let o of s.specifiers||[])o.type==="ImportSpecifier"&&o.local?.value&&t.set(o.local.value,i),o.type==="ImportDefaultSpecifier"&&o.local?.value&&t.set(o.local.value,i);}return t}isComponentName(e){return /^[A-Z][a-zA-Z0-9]*$/.test(e)}extractComponentInfo(e,t,s,i){let o="presentational";["/pages/","/app/","/routes/","/views/","/screens/"].some(l=>t.includes(l))?o="page":e.includes("Container")||e.includes("Provider")?o="container":e.includes("Layout")||e.includes("Shell")||e.includes("Wrapper")||e.includes("Frame")||e.includes("Scaffold")||t.includes("/layouts/")||t.includes("/layout/")?o="layout":e.startsWith("use")&&(o="hook");let n=this.extractHooksUsed(s),r=Array.from(i.keys()).filter(l=>this.isComponentName(l)||l.startsWith("use")),c=this.extractStateManagement(s);return {name:e,filePath:t,type:o,props:[],dependencies:r,dependents:[],hooks:n,stateManagement:c}}extractHooksUsed(e){let t=[],s=/\b(useQuery|useMutation|useLazyQuery)(?:<[^>]*>)?\s*\(\s*([A-Z_][A-Za-z0-9_]*)/g,i;for(;(i=s.exec(e))!==null;){let n=i[1],r=i[2];if(/^(Query|Mutation|QUERY|MUTATION)$/i.test(r))continue;let c=this.extractOperationName(r);if(n==="useQuery"||n==="useLazyQuery"){let l=c?`Query: ${c}`:`Query: ${r}`;t.includes(l)||t.push(l);}else if(n==="useMutation"){let l=c?`Mutation: ${c}`:`Mutation: ${r}`;t.includes(l)||t.push(l);}}let o=/\b(use[A-Z][a-zA-Z0-9]*)\s*\(/g,a;for(;(a=o.exec(e))!==null;){let n=a[1];if(!(n==="useQuery"||n==="useMutation"||n==="useLazyQuery"))if(n==="useContext"){let r=e.slice(a.index).match(/useContext\s*\(\s*([A-Z][A-Za-z0-9]*)/);if(r){let l=`\u{1F504} Context: ${r[1].replace(/Context$/,"")}`;t.includes(l)||t.push(l);}}else t.includes(n)||t.push(n);}return t}extractOperationName(e){if(!e)return null;let t=e.split(",")[0].trim();if(/^[{[\'"` ]/.test(t))return null;let s=t.replace(/^(GET_|FETCH_|CREATE_|UPDATE_|DELETE_)/,"").replace(/_QUERY$|_MUTATION$/,"").replace(/Document$/,"").replace(/Query$|Mutation$/,"");return !s||s.trim()===""||/^(QUERY|MUTATION)$/i.test(s.trim())?null:s}extractStateManagement(e){let t=[];return e.includes("useState")&&t.push("useState"),e.includes("useReducer")&&t.push("useReducer"),e.includes("useContext")&&t.push("useContext"),e.includes("useQuery")&&t.push("Apollo Query"),e.includes("useMutation")&&t.push("Apollo Mutation"),e.includes("useRecoil")&&t.push("Recoil"),(e.includes("useSelector")||e.includes("useDispatch"))&&t.push("Redux"),t}buildDependencyGraph(e){let t=new Map;for(let s of e)t.set(s.name,s);for(let s of e)for(let i of s.dependencies){let o=t.get(i);o&&!o.dependents.includes(s.name)&&o.dependents.push(s.name);}}async analyzeDataFlows(e){let t=[],s=1,i=this.analyzeContextFlows(e);t.push(...i.map(n=>({...n,id:`flow-${s++}`})));let o=this.analyzeApolloFlows(e);t.push(...o.map(n=>({...n,id:`flow-${s++}`})));let a=this.analyzePropDrilling(e);return t.push(...a.map(n=>({...n,id:`flow-${s++}`}))),t}analyzeContextFlows(e){let t=[],s=e.filter(o=>o.name.includes("Provider")||o.name.includes("Context")),i=e.filter(o=>o.hooks.some(a=>a.includes("Context")));for(let o of s){let a=o.name.replace("Provider","").replace("Context","");for(let n of i){let r=n.hooks.find(c=>c.includes("Context")&&c.includes(a));(r||n.hooks.some(c=>c.includes(a)))&&t.push({name:`\u{1F504} ${a} Context`,description:`Data flows from ${o.name} to ${n.name} via Context`,source:{type:"context",name:o.name},target:{type:"component",name:n.name},via:[],operations:[r||`useContext(${a})`]});}}return t}analyzeApolloFlows(e){let t=[];for(let s of e){let i=s.hooks.filter(a=>a.includes("Query:")||a==="useQuery"||a==="useLazyQuery");for(let a of i){let n=a.includes(":")?a.split(":")[1].trim():s.name;t.push({name:`Query: ${n}`,description:`${s.name} fetches ${n} via Apollo`,source:{type:"api",name:`GraphQL: ${n}`},target:{type:"component",name:s.name},via:[{type:"cache",name:"Apollo Cache"}],operations:[a]});}let o=s.hooks.filter(a=>a.includes("Mutation:")||a==="useMutation");for(let a of o){let n=a.includes(":")?a.split(":")[1].trim():s.name;t.push({name:`Mutation: ${n}`,description:`${s.name} mutates ${n} via Apollo`,source:{type:"component",name:s.name},target:{type:"api",name:`GraphQL: ${n}`},via:[],operations:[a]});}}return t}analyzePropDrilling(e){let t=[];for(let s of e)s.props.length>5&&s.dependents.length>0&&t.push({name:`Prop Drilling through ${s.name}`,description:`${s.name} passes ${s.props.length} props to children`,source:{type:"component",name:s.name},target:{type:"component",name:s.dependents[0]},via:[],operations:["props"]});return t}};var Z=class extends w{project;apiCallCounter=0;constructor(e){super(e),this.project=new Project({tsConfigFilePath:this.resolvePath("tsconfig.json"),skipAddingFilesFromTsConfig:true});}getName(){return "RestApiAnalyzer"}async analyze(){this.log("Starting REST API analysis...");let e=await Q(["**/*.ts","**/*.tsx"],{cwd:this.basePath,ignore:["**/node_modules/**","**/.next/**","**/__tests__/**","**/*.test.*","**/*.spec.*","**/*.stories.*","**/__generated__/**","**/dist/**","**/build/**"],absolute:true}),t=new Map;for(let o of e)try{t.set(o,this.project.addSourceFileAtPath(o));}catch{}let i=(await E(Array.from(t.entries()),async([o,a])=>{let n=b.relative(this.basePath,o),r=[];return r.push(...this.findFetchCalls(a,n)),r.push(...this.findAxiosCalls(a,n)),r.push(...this.findSwrCalls(a,n)),r},8)).flat();return this.log(`Found ${i.length} REST API calls`),{apiCalls:i}}findFetchCalls(e,t){let s=[],i=e.getDescendantsOfKind(SyntaxKind.CallExpression);for(let o of i)try{let n=o.getExpression().getText();if(n==="fetch"||n==="window.fetch"){let r=this.extractFetchCall(o,t);r&&s.push(r);}}catch{}return s}findAxiosCalls(e,t){let s=[],i=e.getDescendantsOfKind(SyntaxKind.CallExpression);for(let o of i)try{let n=o.getExpression().getText(),r=n.match(/^axios\.(get|post|put|delete|patch)$/i);if(r){let c=this.extractAxiosCall(o,t,r[1].toUpperCase());c&&s.push(c);}if(n==="axios"){let c=this.extractAxiosDirectCall(o,t);c&&s.push(c);}}catch{}return s}findSwrCalls(e,t){let s=[],i=e.getDescendantsOfKind(SyntaxKind.CallExpression);for(let o of i)try{let n=o.getExpression().getText();if(n==="useSWR"||n==="useSWRImmutable"){let r=this.extractSwrCall(o,t);r&&s.push(r);}}catch{}return s}extractFetchCall(e,t){let s=e.getArguments();if(s.length===0)return null;let i=s[0].getText(),o=this.extractUrlFromArg(i);if(!o.url||!o.isPlaceholder&&!this.isApiUrl(o.url))return null;let a="GET",n=false;if(s.length>1){let l=s[1].getText(),g=l.match(/method:\s*["'](\w+)["']/i);g&&(a=this.normalizeMethod(g[1])),n=l.includes("credentials")||l.includes("Authorization")||l.includes("withCredentials");}let r=this.getContainingFunctionName(e),c=e.getStartLineNumber();return {id:`api-${++this.apiCallCounter}`,method:a,url:o.url,callType:"fetch",filePath:t,line:c,containingFunction:r,usedIn:[],requiresAuth:n,category:this.categorizeApi(o.url)}}extractAxiosCall(e,t,s){let i=e.getArguments();if(i.length===0)return null;let o=i[0].getText(),a=this.extractUrlFromArg(o);if(!a.url)return null;let n=false;if(i.length>1){let l=i[i.length-1].getText();n=l.includes("withCredentials")||l.includes("Authorization");}let r=this.getContainingFunctionName(e),c=e.getStartLineNumber();return {id:`api-${++this.apiCallCounter}`,method:this.normalizeMethod(s),url:a.url,callType:"axios",filePath:t,line:c,containingFunction:r,usedIn:[],requiresAuth:n,category:this.categorizeApi(a.url)}}extractAxiosDirectCall(e,t){let s=e.getArguments();if(s.length===0)return null;let i=s[0].getText(),o=i.match(/url:\s*["'`]([^"'`]+)["'`]/),a=i.match(/method:\s*["'](\w+)["']/i);if(!o)return null;let n=o[1],r=a?this.normalizeMethod(a[1]):"GET",c=i.includes("withCredentials")||i.includes("Authorization"),l=this.getContainingFunctionName(e),g=e.getStartLineNumber();return {id:`api-${++this.apiCallCounter}`,method:r,url:n,callType:"axios",filePath:t,line:g,containingFunction:l,usedIn:[],requiresAuth:c,category:this.categorizeApi(n)}}extractSwrCall(e,t){let s=e.getArguments();if(s.length===0)return null;let i=s[0].getText(),o=null;if(i.startsWith('"')||i.startsWith("'")||i.startsWith("`"))o=this.cleanStringLiteral(i);else if(i.includes("?")&&i.includes(":")){let r=i.match(/\?\s*["'`]([^"'`]+)["'`]/);r?o=r[1]:(r=i.match(/:\s*["'`]([^"'`]+)["'`]/),r&&(o=r[1])),o||(r=i.match(/\?\s*`([^`]+)`/),r&&(o=r[1].replace(/\$\{[^}]+\}/g,":param")));}else {let r=this.extractUrlFromArg(i);r.url&&!i.includes("null")&&!i.includes("undefined")&&(o=r.url);}if(!o)return null;let a=this.getContainingFunctionName(e),n=e.getStartLineNumber();return {id:`api-${++this.apiCallCounter}`,method:"GET",url:o,callType:"useSWR",filePath:t,line:n,containingFunction:a,usedIn:[],requiresAuth:false,category:this.categorizeApi(o)}}getContainingFunctionName(e){let t=e;for(;t;){if(Node.isFunctionDeclaration(t))return t.getName()||"anonymous";if(Node.isVariableDeclaration(t)||Node.isMethodDeclaration(t))return t.getName();if(Node.isArrowFunction(t)){let s=t.getParent();if(s&&Node.isVariableDeclaration(s))return s.getName()}t=t.getParent();}return "unknown"}extractUrlFromArg(e){if(/^["'`]/.test(e))return {url:this.cleanStringLiteral(e),isPlaceholder:false};let t=e.match(/^(\w+)\s*\(\s*["'`]([^"'`]+)["'`]/);if(t)return {url:`[${t[1]}] ${t[2]}`,isPlaceholder:true};let s=e.match(/^(\w+)\s*\(\s*`([^`]+)`/);if(s){let i=s[2].replace(/\$\{[^}]+\}/g,":param");return {url:`[${s[1]}] ${i}`,isPlaceholder:true}}return /^\w+(\.\w+)*$/.test(e)?{url:`[${e}]`,isPlaceholder:true}:e.includes(".")?{url:`[${e}]`,isPlaceholder:true}:{url:null,isPlaceholder:false}}cleanStringLiteral(e){let t=e.replace(/^["'`]|["'`]$/g,"").trim();return t.includes("${")?t.replace(/\$\{[^}]+\}/g,":param"):t||null}isApiUrl(e){return e.startsWith("data:")||e.startsWith("blob:")||/\.(css|js|png|jpg|jpeg|gif|svg|ico|woff|woff2|ttf|eot|html)$/i.test(e)?false:e.startsWith("/")||e.startsWith("http")||e.includes("/api/")||e.includes(".json")||e.includes("api.")||e.includes("github.io")||e.includes("hsforms.com")||e.includes("hubspot")||e.includes("amazonaws.com")||e.includes("s3.")||e.includes("googleapis.com")||e.includes("stripe.com")||e.includes("graph.facebook.com")||e.includes("api.twitter.com")||e.includes("slack.com")||e.includes("discord.com")||e.includes("sendgrid.com")||e.includes("twilio.com")||e.includes("firebase")||e.includes("supabase")||e.includes("auth0.com")||e.includes("okta.com")||e.includes("cloudflare.com")||e.includes("vercel.com")||e.includes("netlify.com")}categorizeApi(e){if(e.includes("hsforms.com")||e.includes("hubspot"))return "HubSpot";if(e.includes("amazonaws.com")||e.includes("s3."))return "AWS S3";if(e.includes("googleapis.com"))return "Google API";if(e.includes("stripe.com"))return "Stripe";if(e.includes("graph.facebook.com"))return "Facebook";if(e.includes("api.twitter.com"))return "Twitter";if(e.includes("slack.com"))return "Slack";if(e.includes("discord.com"))return "Discord";if(e.includes("sendgrid.com"))return "SendGrid";if(e.includes("twilio.com"))return "Twilio";if(e.includes("firebase"))return "Firebase";if(e.includes("supabase"))return "Supabase";if(e.includes("auth0.com"))return "Auth0";if(e.includes("okta.com"))return "Okta";if(e.includes("github.io"))return "GitHub Pages API";if(e.startsWith("/api/"))return "Internal API";if(e.startsWith("/"))return "Internal Route";if(e.startsWith("["))return "Dynamic URL"}normalizeMethod(e){let t=e.toUpperCase();return ["GET","POST","PUT","DELETE","PATCH"].includes(t)?t:"unknown"}};export{w as a,q as b,j as c,W as d,Z as e};