@wtdlee/repomap 0.3.1 → 0.3.3

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 +0,0 @@
1
-
@@ -1,43 +1,15 @@
1
- import { analyzeRailsApp } from './chunk-OWM6WNLE.js';
2
- import * as fs from 'fs';
3
- import * as path from 'path';
4
-
5
- var RailsMapGenerator = class {
6
- constructor(rootPath) {
7
- this.rootPath = rootPath;
8
- }
9
- result = null;
10
- async generate(options = {}) {
11
- if (!this.rootPath) throw new Error("Root path required for analysis");
12
- const { title = "Rails Application Map" } = options;
13
- this.result = await analyzeRailsApp(this.rootPath);
14
- const html = this.generateHTML(title);
15
- if (options.outputPath) {
16
- fs.writeFileSync(options.outputPath, html);
17
- console.log(`
18
- \u{1F4C4} Generated: ${options.outputPath}`);
19
- }
20
- return html;
21
- }
22
- // Generate from existing analysis result (for doc-server)
23
- generateFromResult(analysisResult, title = "Rails Application Map") {
24
- this.result = analysisResult;
25
- return this.generateHTML(title);
26
- }
27
- generateHTML(title) {
28
- if (!this.result) throw new Error("Analysis not run");
29
- const { routes, controllers, models, grpc, summary } = this.result;
30
- return `<!DOCTYPE html>
1
+ import {k}from'./chunk-PTR5IROV.js';import*as r from'fs';import*as c from'path';var o=class{constructor(t){this.rootPath=t;}result=null;async generate(t={}){if(!this.rootPath)throw new Error("Root path required for analysis");let{title:e="Rails Application Map"}=t;this.result=await k(this.rootPath);let a=this.generateHTML(e);return t.outputPath&&(r.writeFileSync(t.outputPath,a),console.log(`
2
+ \u{1F4C4} Generated: ${t.outputPath}`)),a}generateFromResult(t,e="Rails Application Map"){return this.result=t,this.generateHTML(e)}generateHTML(t){if(!this.result)throw new Error("Analysis not run");let{routes:e,controllers:a,models:s,grpc:i,summary:l}=this.result;return `<!DOCTYPE html>
31
3
  <html lang="en">
32
4
  <head>
33
5
  <meta charset="UTF-8">
34
6
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
35
- <title>${title}</title>
7
+ <title>${t}</title>
36
8
  <link rel="stylesheet" href="/rails-map.css">
37
9
  </head>
38
10
  <body>
39
11
  <header>
40
- <h1>\u{1F6E4}\uFE0F ${title}</h1>
12
+ <h1>\u{1F6E4}\uFE0F ${t}</h1>
41
13
  <nav class="header-nav">
42
14
  <a href="/page-map" class="nav-link">Page Map</a>
43
15
  <a href="/rails-map" class="nav-link active">Rails Map</a>
@@ -46,25 +18,25 @@ var RailsMapGenerator = class {
46
18
  <div class="stats-bar">
47
19
  <div class="stat active" data-view="routes">
48
20
  <div>
49
- <div class="stat-value">${summary.totalRoutes.toLocaleString()}</div>
21
+ <div class="stat-value">${l.totalRoutes.toLocaleString()}</div>
50
22
  <div class="stat-label">Routes</div>
51
23
  </div>
52
24
  </div>
53
25
  <div class="stat" data-view="controllers">
54
26
  <div>
55
- <div class="stat-value">${summary.totalControllers}</div>
27
+ <div class="stat-value">${l.totalControllers}</div>
56
28
  <div class="stat-label">Controllers</div>
57
29
  </div>
58
30
  </div>
59
31
  <div class="stat" data-view="models">
60
32
  <div>
61
- <div class="stat-value">${summary.totalModels}</div>
33
+ <div class="stat-value">${l.totalModels}</div>
62
34
  <div class="stat-label">Models</div>
63
35
  </div>
64
36
  </div>
65
37
  <div class="stat" data-view="grpc">
66
38
  <div>
67
- <div class="stat-value">${summary.totalGrpcServices}</div>
39
+ <div class="stat-value">${l.totalGrpcServices}</div>
68
40
  <div class="stat-label">gRPC</div>
69
41
  </div>
70
42
  </div>
@@ -85,26 +57,26 @@ var RailsMapGenerator = class {
85
57
  </div>
86
58
 
87
59
  <div class="sidebar-section namespaces" id="namespaceFilter">
88
- <div class="sidebar-title">Namespaces (${summary.namespaces.length})</div>
60
+ <div class="sidebar-title">Namespaces (${l.namespaces.length})</div>
89
61
  <div class="namespace-list">
90
62
  <div class="namespace-item active" data-namespace="all">
91
63
  <span>All</span>
92
- <span class="namespace-count">${routes.routes.length}</span>
64
+ <span class="namespace-count">${e.routes.length}</span>
93
65
  </div>
94
- ${this.generateNamespaceList(routes.routes)}
66
+ ${this.generateNamespaceList(e.routes)}
95
67
  </div>
96
68
  </div>
97
69
 
98
70
  <div class="sidebar-section" id="methodFilter">
99
71
  <div class="sidebar-title">HTTP Methods</div>
100
72
  <div class="namespace-list methods-list">
101
- ${this.generateMethodFilters(routes.routes)}
73
+ ${this.generateMethodFilters(e.routes)}
102
74
  </div>
103
75
  </div>
104
76
  </aside>
105
77
 
106
78
  <main class="main-panel" id="mainPanel">
107
- ${this.generateRoutesView(routes.routes)}
79
+ ${this.generateRoutesView(e.routes)}
108
80
  </main>
109
81
 
110
82
  <aside class="detail-panel" id="detailPanel">
@@ -117,10 +89,10 @@ var RailsMapGenerator = class {
117
89
 
118
90
  <script>
119
91
  // Data
120
- const routes = ${JSON.stringify(routes.routes)};
121
- const controllers = ${JSON.stringify(controllers.controllers)};
122
- const models = ${JSON.stringify(models.models)};
123
- const grpcServices = ${JSON.stringify(grpc.services)};
92
+ const routes = ${JSON.stringify(e.routes)};
93
+ const controllers = ${JSON.stringify(a.controllers)};
94
+ const models = ${JSON.stringify(s.models)};
95
+ const grpcServices = ${JSON.stringify(i.services)};
124
96
 
125
97
  // State
126
98
  let currentView = 'routes';
@@ -819,43 +791,19 @@ var RailsMapGenerator = class {
819
791
  renderMainPanel();
820
792
  </script>
821
793
  </body>
822
- </html>`;
823
- }
824
- generateNamespaceList(routes) {
825
- const namespaces = /* @__PURE__ */ new Map();
826
- for (const route of routes) {
827
- const ns = route.namespace || "root";
828
- namespaces.set(ns, (namespaces.get(ns) || 0) + 1);
829
- }
830
- const sorted = [...namespaces.entries()].sort((a, b) => b[1] - a[1]);
831
- return sorted.map(
832
- ([ns, count]) => `
833
- <div class="namespace-item" data-namespace="${ns === "root" ? "" : ns}">
834
- <span>${ns}</span>
835
- <span class="namespace-count">${count}</span>
794
+ </html>`}generateNamespaceList(t){let e=new Map;for(let s of t){let i=s.namespace||"root";e.set(i,(e.get(i)||0)+1);}return [...e.entries()].sort((s,i)=>i[1]-s[1]).map(([s,i])=>`
795
+ <div class="namespace-item" data-namespace="${s==="root"?"":s}">
796
+ <span>${s}</span>
797
+ <span class="namespace-count">${i}</span>
836
798
  </div>
837
- `
838
- ).join("");
839
- }
840
- generateMethodFilters(routes) {
841
- const methods = ["GET", "POST", "PUT", "PATCH", "DELETE"];
842
- const counts = /* @__PURE__ */ new Map();
843
- for (const route of routes) {
844
- counts.set(route.method, (counts.get(route.method) || 0) + 1);
845
- }
846
- return methods.map(
847
- (method) => `
848
- <div class="namespace-item" data-method="${method}">
849
- <span class="method-badge method-${method}">${method}</span>
850
- <span class="namespace-count">${counts.get(method) || 0}</span>
799
+ `).join("")}generateMethodFilters(t){let e=["GET","POST","PUT","PATCH","DELETE"],a=new Map;for(let s of t)a.set(s.method,(a.get(s.method)||0)+1);return e.map(s=>`
800
+ <div class="namespace-item" data-method="${s}">
801
+ <span class="method-badge method-${s}">${s}</span>
802
+ <span class="namespace-count">${a.get(s)||0}</span>
851
803
  </div>
852
- `
853
- ).join("");
854
- }
855
- generateRoutesView(routes) {
856
- return `
804
+ `).join("")}generateRoutesView(t){return `
857
805
  <div class="panel-header">
858
- <div class="panel-title">Routes (${routes.length})</div>
806
+ <div class="panel-title">Routes (${t.length})</div>
859
807
  </div>
860
808
  <table class="routes-table">
861
809
  <thead>
@@ -866,35 +814,14 @@ var RailsMapGenerator = class {
866
814
  </tr>
867
815
  </thead>
868
816
  <tbody>
869
- ${routes.slice(0, 200).map(
870
- (route, idx) => `
871
- <tr data-type="route" data-index="${idx}">
872
- <td><span class="method-badge method-${route.method}">${route.method}</span></td>
873
- <td class="path-text">${this.highlightParams(route.path)}</td>
874
- <td class="controller-text">${route.controller}#${route.action}</td>
817
+ ${t.slice(0,200).map((e,a)=>`
818
+ <tr data-type="route" data-index="${a}">
819
+ <td><span class="method-badge method-${e.method}">${e.method}</span></td>
820
+ <td class="path-text">${this.highlightParams(e.path)}</td>
821
+ <td class="controller-text">${e.controller}#${e.action}</td>
875
822
  </tr>
876
- `
877
- ).join("")}
823
+ `).join("")}
878
824
  </tbody>
879
825
  </table>
880
- `;
881
- }
882
- highlightParams(path2) {
883
- return path2.replace(/:([a-zA-Z_]+)/g, '<span class="param">:$1</span>');
884
- }
885
- };
886
- async function main() {
887
- const targetPath = process.argv[2] || process.cwd();
888
- const outputPath = process.argv[3] || path.join(targetPath, "rails-map.html");
889
- const generator = new RailsMapGenerator(targetPath);
890
- await generator.generate({
891
- title: "Rails Application Map",
892
- outputPath
893
- });
894
- }
895
- var isMainModule = import.meta.url === `file://${process.argv[1]}`;
896
- if (isMainModule) {
897
- main().catch(console.error);
898
- }
899
-
900
- export { RailsMapGenerator };
826
+ `}highlightParams(t){return t.replace(/:([a-zA-Z_]+)/g,'<span class="param">:$1</span>')}};async function m(){let n=process.argv[2]||process.cwd(),t=process.argv[3]||c.join(n,"rails-map.html");await new o(n).generate({title:"Rails Application Map",outputPath:t});}var p=import.meta.url===`file://${process.argv[1]}`;p&&m().catch(console.error);
827
+ export{o as a};
@@ -0,0 +1 @@
1
+ import {Project,Node,SyntaxKind}from'ts-morph';import z from'fast-glob';import*as N from'path';import*as W from'fs';import*as L from'fs/promises';import {parse}from'graphql';var F=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(D,e,t=8){let n=new Array(D.length).fill(null),o=0;async function i(){for(;o<D.length;){let s=o++;if(s<D.length)try{n[s]=await e(D[s],s);}catch{n[s]=null;}}}let a=Array(Math.min(t,D.length)).fill(null).map(()=>i());return await Promise.all(a),n.filter(s=>s!==null)}var q=class extends F{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 n=e.match(/`\s*(?:query|mutation|subscription)\s+(\w+)/);if(n&&n[1])return n[1];let o=e.match(/GraphQL[^`]*`\s*(?:\n\s*)?(?:query|mutation|subscription)\s+(\w+)/);return o&&o[1]?o[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 o=n.getInitializer();if(!o)return null;let i=o.getText();return this.extractOperationNameFromGql(i)}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 o of e)try{this.project.addSourceFileAtPath(o);}catch{}let n=(await E(e,async o=>{let i=this.detectPagesRoot(o);return this.analyzePageFile(o,i)},4)).filter(o=>o!==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 o=N.relative(t,e),i=this.filePathToRoutePath(o),a=this.findPageComponent(n);if(!a)return null;let s=this.extractRouteParams(i),r=this.extractLayout(n),c=this.extractAuthRequirement(n),l=this.extractPermissions(n),g=this.extractDataFetching(n),u=this.extractNavigation(n),d=this.extractLinkedPages(n),C=this.extractSteps(n);return {path:i,filePath:o,component:a,params:s,layout:r,authentication:c,permissions:l,dataFetching:g,navigation:u,linkedPages:d,steps:C.length>0?C:void 0}}detectPagesRoot(e){let t=["/src/pages/","/pages/","/src/app/","/app/","/frontend/src/pages/","/app/javascript/pages/"];for(let n of t){let o=e.indexOf(n);if(o!==-1)return e.substring(0,o+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,o;for(;(o=n.exec(e))!==null;)t.push(o[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 o=e.getFunctions();for(let s of o)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 i=n.getRight().getDescendantsOfKind(SyntaxKind.JsxOpeningElement);if(i.length>0)return i[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(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 d=this.extractRolesFromCondition(u.getText());d.length>0&&(a.roles=d);}}}catch{}}}catch{}return a}extractRolesFromCondition(e){let t=[],n=/(\w+Role|\w+Permission)\.(\w+)/g,o;for(;(o=n.exec(e))!==null;)t.push(o[2]);let i=/['"]([a-zA-Z_-]+)['"]/g;for(;(o=i.exec(e))!==null;){let s=o[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(;(o=a.exec(e))!==null;)t.push(o[1]);return [...new Set(t)]}extractPermissions(e){let t=[],n=e.getDescendantsOfKind(SyntaxKind.PropertyAccessExpression).filter(o=>{let i=o.getText();return i.includes("Permission")||i.includes("Role")||i.includes("isAdmin")});for(let o of n){let i=o.getText();t.includes(i)||t.push(i);}return t}extractDataFetching(e){let t=[],n=new Map,o=["useQuery","useMutation","useLazyQuery","useSubscription"];for(let S of e.getImportDeclarations()){let p=S.getModuleSpecifierValue();if(p.includes("@apollo/client")||p.includes("apollo"))for(let f of S.getNamedImports()){let x=f.getName(),m=f.getAliasNode()?.getText()||x;o.includes(x)&&n.set(m,x);}}let i=n.size>0||e.getImportDeclarations().some(S=>{let p=S.getModuleSpecifierValue();return p.includes("@apollo/client")||p.includes("apollo")}),a=e.getDescendantsOfKind(SyntaxKind.CallExpression).filter(S=>{let p=S.getExpression().getText();return !!(n.has(p)||o.includes(p)||/^use[A-Z].*Query$/.test(p)&&!p.includes("Params")&&!p.includes("String")||/^use[A-Z].*Mutation$/.test(p))});for(let S of a){let p=S.getExpression().getText(),f;n.has(p)?f=n.get(p):p.includes("Mutation")?f="useMutation":p.includes("Lazy")?f="useLazyQuery":f="useQuery";let x=S.getArguments();if(x.length===0){if(/^use[A-Z]/.test(p)){let T=p.replace(/^use/,"").replace(/Query$|Mutation$/,"");t.push({type:f,operationName:T,variables:[]});}continue}let h=x[0].getText();if(h.startsWith("[")||h.startsWith("{")||h.startsWith("'")||h.startsWith('"')||h.startsWith("`")||!(i||h.endsWith("Document")||h.endsWith("Query")||h.endsWith("Mutation")||h.includes("gql")||/^[A-Z_]+$/.test(h)))continue;let y=h.replace(/Document$/,"").replace(/Query$|Mutation$/,""),A=[];if(x.length>1){let w=x[1].getDescendantsOfKind(SyntaxKind.PropertyAssignment).find(b=>{try{return b.getName()==="variables"}catch{return false}});if(w){let b=w.getInitializer();if(b){let R=b.getDescendantsOfKind(SyntaxKind.PropertyAssignment);for(let Z of R)try{A.push(Z.getName());}catch{}}}}t.push({type:f,operationName:y,variables:A});}let s=e.getVariableDeclaration("getServerSideProps"),r=e.getFunction("getServerSideProps"),c=s||r;if(c){let S=e.getImportDeclarations();for(let x of S){let m=x.getNamedImports();for(let h of m){let v=h.getName();if(v.endsWith("Document")&&e.getDescendantsOfKind(SyntaxKind.Identifier).filter(A=>A.getText()===v).length>0){let A=v.replace(/Document$/,"");t.push({type:"getServerSideProps",operationName:`\u2192 ${A}`});}}}let f=c.getText().match(/query:\s*(\w+)/g);if(f)for(let x of f){let m=x.replace(/query:\s*/,"");t.some(h=>h.operationName?.includes(m.replace(/Document$/,"")))||t.push({type:"getServerSideProps",operationName:`\u2192 ${m.replace(/Document$/,"")}`});}}let l=e.getVariableDeclaration("getStaticProps"),g=e.getFunction("getStaticProps");(l||g)&&t.push({type:"getStaticProps",operationName:"getStaticProps"});let u=e.getImportDeclarations(),d=e.getFilePath(),C=N.dirname(d);for(let S of u){let p=S.getModuleSpecifierValue(),f=p.startsWith(".")||p.startsWith("/"),x=!p.includes("node_modules")&&!p.startsWith("@types/")&&p.startsWith("@")===false;if(f||x){if(p.includes("__generated__")||p.includes("/generated/"))continue;let m=[],h=S.getNamedImports();for(let y of h){let A=y.getName();this.isComponentName(A)&&m.push(A);}let v=S.getDefaultImport();if(v){let y=v.getText();this.isComponentName(y)&&m.push(y);}for(let y of m){let A=this.analyzeImportedComponent(C,p,y);if(A.length>0)for(let T of A)t.push({type:T.type,operationName:T.operationName.startsWith("\u2192")?`\u2192 ${T.operationName} (${y})`:`\u2192 ${T.operationName} (${y})`,variables:T.variables});else t.push({type:"component",operationName:y,variables:[]});}}}return t}symbolTraceCache=new Map;analyzeImportedComponent(e,t,n,o=new Set,i=0){if(i>10)return [];let s=[];try{let r=N.resolve(e,t),c=`${r}:${n}`;if(o.has(c))return [];o.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}/${n}.tsx`,`${r}/${n}.ts`],u,d;for(let p of g)try{if(u=this.project.addSourceFileAtPath(p),u){d=p;break}}catch{}if(!u||!d)return s;if(d.endsWith("index.tsx")||d.endsWith("index.ts")){let p=this.followReExport(u,n,N.dirname(d));p&&(u=p);}let C=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__")}),S=u.getImportDeclarations().filter(p=>{let f=p.getModuleSpecifierValue();return f.startsWith("./")||f.startsWith("../")});for(let p of S){let f=p.getModuleSpecifierValue(),x=p.getNamedImports().map(m=>m.getName()).filter(m=>/^use[A-Z]/.test(m));for(let m of x){let h=this.analyzeCustomHook(N.dirname(u.getFilePath()),f,m,o,i+1);s.push(...h);}}for(let p of S){let f=p.getModuleSpecifierValue(),x=p.getNamedImports().map(v=>v.getName()),m=p.getDefaultImport()?.getText(),h=x.filter(v=>/^[A-Z]/.test(v)&&this.isComponentName(v));for(let v of h){let y=this.analyzeImportedComponent(N.dirname(u.getFilePath()),f,v,o,i+1);s.push(...y);}if(m&&/^[A-Z]/.test(m)&&this.isComponentName(m)){let v=this.analyzeImportedComponent(N.dirname(u.getFilePath()),f,m,o,i+1);s.push(...v);}}if(C){let p=u.getDescendantsOfKind(SyntaxKind.CallExpression).filter(f=>{let x=f.getExpression().getText();return ["useQuery","useMutation","useLazyQuery","useSubscription"].includes(x)});for(let f of p){let x=f.getExpression().getText(),m=f.getArguments();if(m.length===0)continue;let v=m[0].getText(),y=v,A=null,T=this.resolveDocumentName(v);if(T)y=T.operationName,A=T.operationType;else if(v.endsWith("Document"))y=v.replace(/Document$/,"");else if(/^[A-Za-z]/.test(v)){let b=this.findOperationNameFromVariable(u,v);if(b&&(y=b),y===v&&v!=="Query"&&v!=="Mutation"){let R=v.match(/^(.+?)(Query|Mutation|Subscription)$/);R&&(y=R[1]);}}y!=="Query"&&y!=="Mutation"&&(y=y.replace(/Document$/,"").replace(/Query$|Mutation$/,"")||y),(y==="Query"||y==="Mutation"||y==="")&&y===""&&(y=v||"Unknown");let w=A?A==="mutation"?"useMutation":A==="subscription"?"useSubscription":x.includes("Lazy")?"useLazyQuery":"useQuery":x.includes("Mutation")?"useMutation":x.includes("Lazy")?"useLazyQuery":"useQuery";s.push({type:w,operationName:y,variables:[]});}}this.symbolTraceCache.set(c,s);}catch{}return s}analyzeCustomHook(e,t,n,o=new Set,i=0){if(i>10)return [];let s=[];try{let r=N.resolve(e,t),c=`hook:${r}:${n}`;if(o.has(c))return [];o.add(c);let l=this.symbolTraceCache.get(c);if(l!==void 0)return l;let g=[`${r}.tsx`,`${r}.ts`,`${r}/${n}.tsx`,`${r}/${n}.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 s;let d=u.getImportDeclarations().some(p=>{let f=p.getModuleSpecifierValue();return f.includes("@apollo/client")||f.includes("apollo")||f.includes("graphql")||f.includes("__generated__")}),C=u.getImportDeclarations().filter(p=>{let f=p.getModuleSpecifierValue();return f.startsWith("./")||f.startsWith("../")});for(let p of C){let f=p.getModuleSpecifierValue(),x=p.getNamedImports().map(m=>m.getName()).filter(m=>/^use[A-Z]/.test(m));for(let m of x){let h=this.analyzeCustomHook(N.dirname(u.getFilePath()),f,m,o,i+1);s.push(...h);}}if(!d&&s.length===0)return s;let S=u.getDescendantsOfKind(SyntaxKind.CallExpression).filter(p=>{let f=p.getExpression().getText();return ["useQuery","useMutation","useLazyQuery","useSubscription"].includes(f)});for(let p of S){let f=p.getExpression().getText(),x=p.getArguments();if(x.length===0)continue;let m=x[0].getText(),h=m,v=null,y=this.resolveDocumentName(m);if(y)h=y.operationName,v=y.operationType;else if(m.endsWith("Document"))h=m.replace(/Document$/,"");else if(/^[A-Za-z]/.test(m)){let T=this.findOperationNameFromVariable(u,m);if(T&&(h=T),h===m&&m!=="Query"&&m!=="Mutation"){let w=m.match(/^(.+?)(Query|Mutation|Subscription)$/);w&&(h=w[1]);}}h!=="Query"&&h!=="Mutation"&&(h=h.replace(/Document$/,"").replace(/Query$|Mutation$/,"")||h),h===""&&(h=m||"Unknown");let A=v?v==="mutation"?"useMutation":v==="subscription"?"useSubscription":f.includes("Lazy")?"useLazyQuery":"useQuery":f.includes("Mutation")?"useMutation":f.includes("Lazy")?"useLazyQuery":"useQuery";s.push({type:A,operationName:`\u2192 ${h} (via ${n})`,variables:[]});}this.symbolTraceCache.set(c,s);}catch{}return s}globalContextQueries=[];async findPageFiles(){let e=this.getSetting("pagesDir","src/pages"),t=[],o=[...new Set([e,"pages","src/pages","app","src/app"])];for(let s of o){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 z(["**/*.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 i=["frontend/src/**/pages","app/javascript/**/pages"];for(let s of i)try{let r=await z([`${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 z([s],{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 n of t)try{let o=this.project.addSourceFileAtPath(n);if(!o)continue;let i=o.getDescendantsOfKind(SyntaxKind.JsxElement),a=o.getDescendantsOfKind(SyntaxKind.JsxSelfClosingElement),s=new Set;for(let r of [...i,...a]){let c=r.getFirstDescendantByKind(SyntaxKind.Identifier)?.getText();c&&(c.includes("Provider")||c.includes("Context"))&&s.add(c);}for(let r of o.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 s)if(l.includes(u)||g===u){let d=this.analyzeImportedComponent(N.dirname(n),c,u,new Set,0);for(let C of d)this.globalContextQueries.push({...C,operationName:`[Global] ${C.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 o=await z(["**/*.ts","**/*.tsx"],{cwd:n,absolute:!0,onlyFiles:!0});for(let i of o)try{let a=this.project.addSourceFileAtPath(i),s=a.getVariableDeclarations();for(let c of s){let l=c.getName();if(l.endsWith("Document")){let g=c.getInitializer()?.getText()??"",u=g.match(/(?:query|mutation|subscription)\s+(\w+)/),d=g.match(/(query|mutation|subscription)\s+/);u&&this.codegenMap.set(l,{operationName:u[1],operationType:d?d[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 n=this.codegenMap.get(e);if(n!==void 0)return n;let o=e.endsWith("Document")?e:e+"Document",i=this.codegenMap.get(o);return i!==void 0?i:null}followReExport(e,t,n){try{let o=e.getExportDeclarations(),i=null;for(let a of o){let s=a.getNamedExports();for(let r of s){let c=a.getModuleSpecifierValue();if(!c)continue;let l=N.resolve(n,c),g=[`${l}.tsx`,`${l}.ts`,`${l}/index.tsx`,`${l}/index.ts`],u;for(let d of g)try{if(u=this.project.addSourceFileAtPath(d),u)break}catch{}if(u&&(i||(i=u),r.getName()===t||r.getAliasNode()?.getText()===t))return u}}if(i)return i;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 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(o=>e.endsWith(o))||/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(o=>{try{return o.getName()==="globalNavigationStyle"}catch{return !1}});if(n){let o=n.getParent();if(Node.isBinaryExpression(o)){let i=o.getRight(),a=i.getDescendantsOfKind(SyntaxKind.PropertyAssignment).find(c=>{try{return c.getName()==="visible"}catch{return !1}});a&&(t.visible=a.getInitializer()?.getText()==="true");let s=i.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=i.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],g=e.getDescendantsOfKind(SyntaxKind.SwitchStatement);for(let d of g)d.getExpression().getText().includes(l)&&d.getClauses().forEach((p,f)=>{if(p.isKind(SyntaxKind.CaseClause)){let x=p.getExpression()?.getText()||String(f),m=p.getDescendantsOfKind(SyntaxKind.JsxOpeningElement),h=m.length>0?m[0].getTagNameNode().getText():void 0;t.push({id:x.replace(/['"]/g,""),name:`Step ${x.replace(/['"]/g,"")}`,component:h});}});let u=e.getDescendantsOfKind(SyntaxKind.ArrayLiteralExpression);for(let d of u){let C=d.getParent();C&&C.getText().match(/steps|pages|screens|views|components/i)&&d.getElements().forEach((p,f)=>{let x=p.getText();if(x.startsWith("{")){let m=x.match(/(?:name|label|title)\s*:\s*['"]([^'"]+)['"]/),h=x.match(/(?:component|content)\s*:\s*<?\s*(\w+)/);t.push({id:f+1,name:m?m[1]:`Step ${f+1}`,component:h?h[1]:void 0});}else /^[A-Z]/.test(x)&&t.push({id:f+1,name:x,component:x});});}}}let o=e.getDescendantsOfKind(SyntaxKind.JsxOpeningElement);for(let a of o)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(),d=l.isKind(SyntaxKind.JsxElement)?l.getOpeningElement().getAttributes():l.getAttributes(),C=u;for(let S of d)if(S.isKind(SyntaxKind.JsxAttribute)){let p=S.getNameNode().getText();if(p==="label"||p==="title"||p==="name"){let f=S.getInitializer()?.getText();if(f){C=f.replace(/['"{}]/g,"");break}}}t.push({id:g+1,name:C,component:u});}});}let i=e.getDescendantsOfKind(SyntaxKind.ConditionalExpression);for(let a of i){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(i=>{let a=i.getExpression().getText();return a.includes("router.push")||a.includes("router.replace")||a.includes("Link")});for(let i of n){let a=i.getArguments();if(a.length>0){let r=a[0].getText().match(/['"`]([^'"`]+)['"`]/);r&&!t.includes(r[1])&&t.push(r[1]);}}let o=e.getDescendantsOfKind(SyntaxKind.JsxOpeningElement).filter(i=>i.getTagNameNode().getText()==="Link");for(let i of o)try{let a=i.getAttributes();for(let s of a)if(s.isKind(SyntaxKind.JsxAttribute)&&s.getNameNode().getText()==="href"){let l=s.getInitializer()?.getText();if(l){let g=l.match(/['"`]([^'"`]+)['"`]/);g&&!t.includes(g[1])&&t.push(g[1]);}}}catch{}return t}};var K=class extends F{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=[],t=await this.analyzeGraphQLFiles();e.push(...t);let n=await this.analyzeInlineGraphQL();return e.push(...n),await this.findOperationUsage(e),this.log(`Found ${e.length} GraphQL operations`),{graphqlOperations:e}}async analyzeGraphQLFiles(){let e=await z(["**/*.graphql"],{cwd:this.basePath,ignore:["**/node_modules/**","**/.next/**"],absolute:true});return (await E(e,async n=>{let o=await L.readFile(n,"utf-8"),i=parse(o);return this.extractOperationsFromDocument(i,N.relative(this.basePath,n))})).flat()}async analyzeInlineGraphQL(){let e=[],t=await z(["**/*.ts","**/*.tsx"],{cwd:this.basePath,ignore:["**/node_modules/**","**/.next/**","**/__tests__/**","**/*.test.*","**/*.spec.*"],absolute:true});for(let n of t)try{let o=this.project.addSourceFileAtPath(n),i=N.relative(this.basePath,n),a=o.getImportDeclarations().some(c=>{let l=c.getModuleSpecifierValue(),g=c.getNamedImports().map(d=>d.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__"))}),s=o.getDescendantsOfKind(SyntaxKind.TaggedTemplateExpression);for(let c of s){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 d=parse(u),C=this.extractOperationsFromDocument(d,i);e.push(...C);}catch{}}catch{}}let r=o.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 d=u[0],C="";if(d.isKind(SyntaxKind.NoSubstitutionTemplateLiteral))C=d.getLiteralValue();else if(d.isKind(SyntaxKind.TemplateExpression))C=d.getText().slice(1,-1).replace(/\$\{[^}]*\}/g,"");else {let S=d.getText();if(S.includes("`")){let p=S.match(/\/\*\s*GraphQL\s*\*\/\s*`([^`]*)`/);if(p)C=p[1];else {let f=S.match(/`([^`]*)`/);f&&(C=f[1]);}}}if(C&&C.trim())try{let S=parse(C),p=this.extractOperationsFromDocument(S,i);e.push(...p);}catch{}}}}catch{}if(a){let c=o.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 d=l.getInitializer();d&&d.isKind(SyntaxKind.CallExpression);}}}}catch(o){this.warn(`Failed to analyze ${n}: ${o.message}`);}return e}extractOperationsFromDocument(e,t){let n=[];for(let o of e.definitions){let i=this.extractOperation(o,t);i&&n.push(i);}return n}extractOperation(e,t){if(e.kind==="OperationDefinition"){let n=e.name?.value||"anonymous",o=e.operation,i=this.extractVariables(e),a=this.extractFragmentReferences(e),s=this.extractFields(e);return {name:n,type:o,filePath:t,usedIn:[],variables:i,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=(o,i=0)=>{if(!o||!o.selections||i>5)return [];let a=[];for(let s of o.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,i+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,i+1)});}return a};return e.selectionSet?n(e.selectionSet):t}extractVariables(e){let t=[];if(e.variableDefinitions)for(let n of e.variableDefinitions){let o=n.variable.name.value,i=this.typeNodeToString(n.type),a=n.type.kind==="NonNullType";t.push({name:o,type:i,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=o=>{if(o&&(o.kind==="FragmentSpread"&&t.push(o.name.value),o.selectionSet))for(let i of o.selectionSet.selections)n(i);};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){let t=await z(["**/*.ts","**/*.tsx"],{cwd:this.basePath,ignore:["**/node_modules/**","**/.next/**"],absolute:true}),n=new Map;for(let o of e)n.set(o.name,o);for(let o of t)try{let i=await L.readFile(o,"utf-8"),a=N.relative(this.basePath,o);for(let[s,r]of n)(i.includes(`useQuery<${s}`)||i.includes(`useMutation<${s}`)||i.includes(`useLazyQuery<${s}`)||i.includes(`${s}Query`)||i.includes(`${s}Mutation`)||i.includes(`${s}Variables`))&&(r.usedIn.includes(a)||r.usedIn.push(a));}catch{}}};var G=class extends F{project;componentCache=new Map;constructor(e){super(e),this.project=new Project({tsConfigFilePath:this.resolvePath("tsconfig.json"),skipAddingFilesFromTsConfig:true});}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])];for(let i of o){let a=await z(["**/*.tsx"],{cwd:this.resolvePath(i),ignore:["**/*.test.*","**/*.spec.*","**/*.stories.*"],absolute:true});for(let s of a)try{let r=this.project.addSourceFileAtPath(s),c=N.relative(this.basePath,s),l=this.analyzeComponentFile(r,c);e.push(...l);}catch(r){this.warn(`Failed to analyze ${s}: ${r.message}`);}}return this.buildDependencyGraph(e),e}analyzeComponentFile(e,t){let n=[],o=e.getFunctions();for(let s of o){let r=s.getName();if(r&&this.isComponentName(r)){let c=this.extractComponentInfo(s,r,t);n.push(c),this.componentCache.set(r,c);}}let i=e.getVariableDeclarations();for(let s of i){let r=s.getName();if(this.isComponentName(r)){let c=s.getInitializer();if(c&&(c.isKind(SyntaxKind.ArrowFunction)||c.isKind(SyntaxKind.FunctionExpression))){let l=this.extractComponentInfo(c,r,t);n.push(l),this.componentCache.set(r,l);}}}let a=e.getFunctions().filter(s=>{let r=s.getName();return r&&r.startsWith("use")});for(let s of a){let r=s.getName()??"",c=this.extractHookInfo(s,r,t);n.push(c),this.componentCache.set(r,c);}return n}isComponentName(e){return /^[A-Z][a-zA-Z0-9]*$/.test(e)}extractComponentInfo(e,t,n){let o=e.getSourceFile(),i="presentational";["/pages/","/app/","/routes/","/views/","/screens/"].some(g=>n.includes(g))?i="page":t.includes("Container")||t.includes("Provider")?i="container":(t.includes("Layout")||t.includes("Shell")||t.includes("Wrapper")||t.includes("Frame")||t.includes("Scaffold")||n.includes("/layouts/")||n.includes("/layout/"))&&(i="layout");let s=this.extractProps(e),r=this.extractHooksUsed(e),c=this.extractDependencies(o),l=this.extractStateManagement(e);return {name:t,filePath:n,type:i,props:s,dependencies:c,dependents:[],hooks:r,stateManagement:l}}extractHookInfo(e,t,n){let o=e.getSourceFile(),i=this.extractProps(e),a=this.extractHooksUsed(e),s=this.extractDependencies(o),r=this.extractStateManagement(e);return {name:t,filePath:n,type:"hook",props:i,dependencies:s,dependents:[],hooks:a,stateManagement:r}}extractProps(e){let t=[],n=e.getParameters?.()||[];if(n.length>0){let i=n[0].getTypeNode?.();if(i){let a=i.getDescendantsOfKind?.(SyntaxKind.PropertySignature)||[];for(let s of a)t.push({name:s.getName(),type:s.getType().getText(),required:!s.hasQuestionToken()});}}return t}extractHooksUsed(e){let t=[],n=e.getDescendantsOfKind?.(SyntaxKind.CallExpression)||[];for(let o of n)try{let i=o.getExpression().getText();if(i.startsWith("use"))if(i==="useQuery"||i==="useMutation"||i==="useLazyQuery"){let a=this.extractOperationName(o,i);t.includes(a)||t.push(a);}else if(i==="useContext"){let a=this.extractContextName(o);t.includes(a)||t.push(a);}else t.includes(i)||t.push(i);}catch{}return t}extractOperationName(e,t){try{let n=e.getArguments?.()||[];if(n.length>0){let i=n[0].getText().replace(/^(GET_|FETCH_|CREATE_|UPDATE_|DELETE_)/,"").replace(/_QUERY$|_MUTATION$/,"").replace(/Document$/,"").replace(/Query$|Mutation$/,"");return `${t==="useMutation"?"\u270F\uFE0F":"\u{1F4E1}"} ${t==="useMutation"?"Mutation":"Query"}: ${i}`}}catch{}return t}extractContextName(e){try{let t=e.getArguments?.()||[];if(t.length>0)return `\u{1F504} Context: ${t[0].getText().replace(/Context$/,"").replace(/^Session|^Token|^Apollo/,o=>o)}`}catch{}return "useContext"}extractDependencies(e){let t=[],n=e.getImportDeclarations();for(let o of n){let i=o.getModuleSpecifierValue();if(i.startsWith(".")||i.startsWith("@/")){let a=o.getNamedImports();for(let r of a){let c=r.getName();(this.isComponentName(c)||c.startsWith("use"))&&t.push(c);}let s=o.getDefaultImport();if(s){let r=s.getText();this.isComponentName(r)&&t.push(r);}}}return t}extractStateManagement(e){let t=[],n=e.getText?.()||"";return n.includes("useState")&&t.push("useState"),n.includes("useReducer")&&t.push("useReducer"),n.includes("useContext")&&t.push("useContext"),n.includes("useQuery")&&t.push("Apollo Query"),n.includes("useMutation")&&t.push("Apollo Mutation"),n.includes("useRecoil")&&t.push("Recoil"),(n.includes("useSelector")||n.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 o of n.dependencies){let i=t.get(o);i&&!i.dependents.includes(n.name)&&i.dependents.push(n.name);}}async analyzeDataFlows(e){let t=[],n=1,o=this.analyzeContextFlows(e);t.push(...o.map(s=>({...s,id:`flow-${n++}`})));let i=this.analyzeApolloFlows(e);t.push(...i.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(i=>i.name.includes("Provider")||i.name.includes("Context")),o=e.filter(i=>i.hooks.some(a=>a.includes("Context")));for(let i of n){let a=i.name.replace("Provider","").replace("Context","");for(let s of o){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 ${i.name} to ${s.name} via Context`,source:{type:"context",name:i.name},target:{type:"component",name:s.name},via:[],operations:[r||`useContext(${a})`]});}}return t}analyzeApolloFlows(e){let t=[];for(let n of e){let o=n.hooks.filter(a=>a.includes("Query:")||a==="useQuery"||a==="useLazyQuery");for(let a of o){let s=a.includes(":")?a.split(":")[1].trim():n.name;t.push({name:`\u{1F4E1} ${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 i=n.hooks.filter(a=>a.includes("Mutation:")||a==="useMutation");for(let a of i){let s=a.includes(":")?a.split(":")[1].trim():n.name;t.push({name:`\u270F\uFE0F ${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 H=class extends F{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 z(["**/*.ts","**/*.tsx"],{cwd:this.basePath,ignore:["**/node_modules/**","**/.next/**","**/__tests__/**","**/*.test.*","**/*.spec.*","**/*.stories.*","**/__generated__/**","**/dist/**","**/build/**"],absolute:true}),t=new Map;for(let i of e)try{t.set(i,this.project.addSourceFileAtPath(i));}catch{}let o=(await E(Array.from(t.entries()),async([i,a])=>{let s=N.relative(this.basePath,i),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 ${o.length} REST API calls`),{apiCalls:o}}findFetchCalls(e,t){let n=[],o=e.getDescendantsOfKind(SyntaxKind.CallExpression);for(let i of o)try{let s=i.getExpression().getText();if(s==="fetch"||s==="window.fetch"){let r=this.extractFetchCall(i,t);r&&n.push(r);}}catch{}return n}findAxiosCalls(e,t){let n=[],o=e.getDescendantsOfKind(SyntaxKind.CallExpression);for(let i of o)try{let s=i.getExpression().getText(),r=s.match(/^axios\.(get|post|put|delete|patch)$/i);if(r){let c=this.extractAxiosCall(i,t,r[1].toUpperCase());c&&n.push(c);}if(s==="axios"){let c=this.extractAxiosDirectCall(i,t);c&&n.push(c);}}catch{}return n}findSwrCalls(e,t){let n=[],o=e.getDescendantsOfKind(SyntaxKind.CallExpression);for(let i of o)try{let s=i.getExpression().getText();if(s==="useSWR"||s==="useSWRImmutable"){let r=this.extractSwrCall(i,t);r&&n.push(r);}}catch{}return n}extractFetchCall(e,t){let n=e.getArguments();if(n.length===0)return null;let o=n[0].getText(),i=this.extractUrlFromArg(o);if(!i.url||!i.isPlaceholder&&!this.isApiUrl(i.url))return null;let a="GET",s=false;if(n.length>1){let l=n[1].getText(),g=l.match(/method:\s*["'](\w+)["']/i);g&&(a=this.normalizeMethod(g[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:i.url,callType:"fetch",filePath:t,line:c,containingFunction:r,usedIn:[],requiresAuth:s,category:this.categorizeApi(i.url)}}extractAxiosCall(e,t,n){let o=e.getArguments();if(o.length===0)return null;let i=o[0].getText(),a=this.extractUrlFromArg(i);if(!a.url)return null;let s=false;if(o.length>1){let l=o[o.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 o=n[0].getText(),i=o.match(/url:\s*["'`]([^"'`]+)["'`]/),a=o.match(/method:\s*["'](\w+)["']/i);if(!i)return null;let s=i[1],r=a?this.normalizeMethod(a[1]):"GET",c=o.includes("withCredentials")||o.includes("Authorization"),l=this.getContainingFunctionName(e),g=e.getStartLineNumber();return {id:`api-${++this.apiCallCounter}`,method:r,url:s,callType:"axios",filePath:t,line:g,containingFunction:l,usedIn:[],requiresAuth:c,category:this.categorizeApi(s)}}extractSwrCall(e,t){let n=e.getArguments();if(n.length===0)return null;let o=n[0].getText(),i=null;if(o.startsWith('"')||o.startsWith("'")||o.startsWith("`"))i=this.cleanStringLiteral(o);else if(o.includes("?")&&o.includes(":")){let r=o.match(/\?\s*["'`]([^"'`]+)["'`]/);r?i=r[1]:(r=o.match(/:\s*["'`]([^"'`]+)["'`]/),r&&(i=r[1])),i||(r=o.match(/\?\s*`([^`]+)`/),r&&(i=r[1].replace(/\$\{[^}]+\}/g,":param")));}else {let r=this.extractUrlFromArg(o);r.url&&!o.includes("null")&&!o.includes("undefined")&&(i=r.url);}if(!i)return null;let a=this.getContainingFunctionName(e),s=e.getStartLineNumber();return {id:`api-${++this.apiCallCounter}`,method:"GET",url:i,callType:"useSWR",filePath:t,line:s,containingFunction:a,usedIn:[],requiresAuth:false,category:this.categorizeApi(i)}}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 o=n[2].replace(/\$\{[^}]+\}/g,":param");return {url:`[${n[1]}] ${o}`,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{F as a,q as b,K as c,G as d,H as e};