@wtdlee/repomap 0.6.0 → 0.8.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.
Files changed (38) hide show
  1. package/README.md +61 -13
  2. package/dist/analyzers/index.d.ts +175 -25
  3. package/dist/analyzers/index.js +1 -1
  4. package/dist/{chunk-QZWPOG5B.js → chunk-GCIRJGW3.js} +78 -45
  5. package/dist/chunk-H7VVRHQZ.js +34 -0
  6. package/dist/chunk-HPBPEGHS.js +19 -0
  7. package/dist/{chunk-WQANJ7IA.js → chunk-JDM7Y7PX.js} +34 -28
  8. package/dist/{chunk-H4YGP3GL.js → chunk-OQAXO3X2.js} +346 -22
  9. package/dist/chunk-TNUKDIO7.js +5 -0
  10. package/dist/cli.js +21 -35
  11. package/dist/dataflow-analyzer-CJ2T0cGS.d.ts +345 -0
  12. package/dist/generators/assets/docs.css +176 -46
  13. package/dist/generators/assets/favicon/apple-touch-icon.png +0 -0
  14. package/dist/generators/assets/favicon/favicon-96x96.png +0 -0
  15. package/dist/generators/assets/favicon/favicon.ico +0 -0
  16. package/dist/generators/assets/favicon/favicon.svg +3 -0
  17. package/dist/generators/assets/favicon/site.webmanifest +21 -0
  18. package/dist/generators/assets/favicon/web-app-manifest-192x192.png +0 -0
  19. package/dist/generators/assets/favicon/web-app-manifest-512x512.png +0 -0
  20. package/dist/generators/assets/page-map.css +392 -87
  21. package/dist/generators/assets/rails-map.css +221 -48
  22. package/dist/generators/index.d.ts +0 -8
  23. package/dist/generators/index.js +1 -1
  24. package/dist/index.d.ts +18 -9
  25. package/dist/index.js +1 -1
  26. package/dist/page-map-generator-3GO6GL2P.js +1 -0
  27. package/dist/{rails-FFISZ4AE.js → rails-3HNUFTQV.js} +1 -1
  28. package/dist/rails-map-generator-CAQZUBI6.js +1 -0
  29. package/dist/server/index.d.ts +2 -6
  30. package/dist/server/index.js +1 -1
  31. package/dist/types.d.ts +12 -3
  32. package/package.json +1 -5
  33. package/dist/chunk-BPV4UZSW.js +0 -2
  34. package/dist/chunk-PTR5IROV.js +0 -36
  35. package/dist/chunk-XWZH2RDG.js +0 -19
  36. package/dist/dataflow-analyzer-s6ufFkKC.d.ts +0 -215
  37. package/dist/page-map-generator-HBKSOX2E.js +0 -1
  38. package/dist/rails-map-generator-UFLCMFAT.js +0 -1
package/README.md CHANGED
@@ -1,14 +1,36 @@
1
- # @wtdlee/repomap
1
+ <p align="center">
2
+ <img src="./src/generators/assets/favicon/favicon.svg" alt="Repomap" width="120">
3
+ </p>
2
4
 
3
- [![npm version](https://badge.fury.io/js/@wtdlee%2Frepomap.svg)](https://www.npmjs.com/package/@wtdlee/repomap)
4
- [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
5
+ <h1 align="center">@wtdlee/repomap</h1>
5
6
 
6
- Interactive documentation generator for code repositories. Visualize pages, components, routes, and data flows with an intuitive web interface.
7
+ <p align="center">
8
+ <a href="https://www.npmjs.com/package/@wtdlee/repomap"><img src="https://badge.fury.io/js/@wtdlee%2Frepomap.svg" alt="npm version"></a>
9
+ <a href="https://opensource.org/licenses/MIT"><img src="https://img.shields.io/badge/License-MIT-yellow.svg" alt="License: MIT"></a>
10
+ </p>
11
+
12
+ <p align="center">
13
+ Interactive documentation generator for code repositories.<br>
14
+ Visualize pages, components, routes, and data flows with an intuitive web interface.
15
+ </p>
16
+
17
+ ## ⚡ Performance
18
+
19
+ Powered by [SWC](https://swc.rs/) for blazing-fast AST parsing. Analyze large-scale codebases in seconds.
20
+
21
+ | Codebase | Scale | Analysis Time |
22
+ |----------|-------|---------------|
23
+ | Next.js Frontend | 30 pages, 970+ components, 640+ GraphQL ops | **~3.2s** |
24
+ | Rails + React Monolith | 5,700+ routes, 490 controllers, 820 models, 80+ gRPC | **~3.5s** |
25
+
26
+ > 🚀 **10x faster** than ts-morph based solutions. No caching needed!
7
27
 
8
28
  ## Features
9
29
 
10
30
  ### 🗺️ Page Map
11
- - **Multi-framework support** - Next.js (Pages/App Router), React, Rails
31
+ - **Multi-framework support** - Next.js (Pages/App Router), React SPA, Rails
32
+ - **SPA support** - Automatic detection of react-router-dom routes from App.tsx/jsx/js
33
+ - **Zero config for JS projects** - Works without tsconfig.json using smart defaults
12
34
  - **Interactive graph view** - Visual representation of page relationships
13
35
  - **Route analysis** - Automatic detection of routes, authentication, and data dependencies
14
36
  - **React component tracking** - Detect React components used in Rails views
@@ -24,13 +46,16 @@ Interactive documentation generator for code repositories. Visualize pages, comp
24
46
 
25
47
  ### 🔗 GraphQL Analysis
26
48
  - **Operations mapping** - Extract queries, mutations, and fragments
49
+ - **Code Generator support** - Parse `__generated__/graphql.ts` (client preset)
27
50
  - **Field details** - View all fields with types and arguments
28
- - **Usage tracking** - See where operations are used
51
+ - **Usage tracking** - See where operations are used in components
52
+ - **Component integration** - Track GraphQL usage through component dependencies
29
53
 
30
54
  ### 📊 Data Flow
31
55
  - **Visual diagrams** - Mermaid-generated flowcharts
32
56
  - **Cross-component tracking** - Follow data through your application
33
57
  - **REST API detection** - Automatic API endpoint discovery
58
+ - **High performance** - SWC-based parsing (10x faster than ts-morph)
34
59
 
35
60
  ## Installation
36
61
 
@@ -76,17 +101,18 @@ npx @wtdlee/repomap serve
76
101
  repomap serve [options]
77
102
  -p, --port <number> Server port (default: 3030)
78
103
  -c, --config <path> Path to config file
104
+ -o, --output <path> Output directory (default: .repomap)
79
105
  --path <path> Path to repository to analyze
80
- --no-cache Disable caching (always analyze from scratch)
106
+ --temp Use OS temp directory (no files in repository)
81
107
  --no-open Don't open browser automatically
82
108
 
83
109
  # generate command options
84
110
  repomap generate [options]
85
111
  -c, --config <path> Path to config file
86
- -o, --output <path> Output directory
112
+ -o, --output <path> Output directory (default: .repomap)
113
+ --temp Use OS temp directory (no files in repository)
87
114
  --repo <name> Analyze specific repository only
88
115
  --watch Watch for changes and regenerate
89
- --no-cache Disable caching
90
116
  --static Generate standalone HTML files (for GitHub Pages)
91
117
  --ci CI mode: minimal output, exit codes for errors
92
118
  --format <type> Output format: json, html, markdown (default: all)
@@ -97,6 +123,19 @@ repomap rails [options]
97
123
  -o, --output <path> Output HTML file path
98
124
  ```
99
125
 
126
+ ### Output Directory Options
127
+
128
+ ```bash
129
+ # Default: creates .repomap in current directory
130
+ repomap serve
131
+
132
+ # Custom output directory
133
+ repomap serve -o ./docs
134
+
135
+ # Temporary directory (auto-cleaned on exit)
136
+ repomap serve --temp
137
+ ```
138
+
100
139
  ## CI/CD Integration
101
140
 
102
141
  ### Deploy to GitHub Pages
@@ -261,7 +300,7 @@ console.log(`Total pages: ${report.repositories[0].summary.totalPages}`);
261
300
  ```typescript
262
301
  import { DocServer } from "@wtdlee/repomap";
263
302
 
264
- const server = new DocServer(config, 3030, { noCache: false });
303
+ const server = new DocServer(config, 3030);
265
304
  await server.start(true); // true = open browser automatically
266
305
  ```
267
306
 
@@ -392,9 +431,19 @@ export default config;
392
431
  | Framework | Features |
393
432
  |-----------|----------|
394
433
  | **Next.js** | Pages Router, App Router, API routes, data fetching |
395
- | **React** | Components, GraphQL operations, hooks |
434
+ | **React SPA** | react-router-dom routes, components, hooks (auto-detected from App.tsx) |
435
+ | **React (JS)** | JavaScript projects without tsconfig.json |
396
436
  | **Rails** | Routes, Controllers, Models, Views, gRPC, React integration |
397
437
 
438
+ ### GraphQL Support
439
+
440
+ | Pattern | Support |
441
+ |---------|---------|
442
+ | `.graphql` files | ✅ Full support |
443
+ | `gql` template literals | ✅ Full support |
444
+ | GraphQL Code Generator (`__generated__/graphql.ts`) | ✅ Full support |
445
+ | `useQuery`, `useMutation`, `useLazyQuery` hooks | ✅ Tracked |
446
+
398
447
  ## Type Definitions
399
448
 
400
449
  ### Main Types
@@ -462,8 +511,7 @@ src/
462
511
  ├── server/
463
512
  │ └── doc-server.ts # Express server with live reload
464
513
  ├── core/
465
- ├── engine.ts # Main documentation engine
466
- │ └── cache.ts # Caching utilities
514
+ └── engine.ts # Main documentation engine
467
515
  ├── utils/
468
516
  │ ├── env-detector.ts # Environment detection
469
517
  │ └── parallel.ts # Parallel processing utilities
@@ -1,63 +1,213 @@
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
- import { RepositoryConfig, AnalysisResult } from '../types.js';
1
+ import { B as BaseAnalyzer } from '../dataflow-analyzer-CJ2T0cGS.js';
2
+ export { D as DataFlowAnalyzer, G as GraphQLAnalyzer, P as PagesAnalyzer } from '../dataflow-analyzer-CJ2T0cGS.js';
3
+ import { Module, CallExpression } from '@swc/core';
4
+ import { DataFetchingInfo, RepositoryConfig, AnalysisResult } from '../types.js';
5
+
6
+ /**
7
+ * Unified GraphQL extraction utilities
8
+ *
9
+ * This module provides a single source of truth for all GraphQL operation extraction.
10
+ * All analyzers should use these utilities instead of implementing their own logic.
11
+ */
12
+
13
+ /**
14
+ * All supported Apollo/GraphQL query hooks
15
+ */
16
+ declare const GRAPHQL_QUERY_HOOKS: readonly ["useQuery", "useLazyQuery", "useSuspenseQuery", "useBackgroundQuery", "useReadQuery"];
17
+ /**
18
+ * All supported Apollo/GraphQL mutation hooks
19
+ */
20
+ declare const GRAPHQL_MUTATION_HOOKS: readonly ["useMutation"];
21
+ /**
22
+ * All supported Apollo/GraphQL subscription and other hooks
23
+ */
24
+ declare const GRAPHQL_OTHER_HOOKS: readonly ["useSubscription", "useFragment", "useApolloClient"];
25
+ /**
26
+ * All GraphQL hooks combined
27
+ */
28
+ declare const ALL_GRAPHQL_HOOKS: readonly ["useQuery", "useLazyQuery", "useSuspenseQuery", "useBackgroundQuery", "useReadQuery", "useMutation", "useSubscription", "useFragment", "useApolloClient"];
29
+ /**
30
+ * Hook type mapping for data fetching info
31
+ */
32
+ declare const HOOK_TYPE_MAP: Record<string, DataFetchingInfo['type']>;
33
+ /**
34
+ * Keywords that indicate GraphQL usage in a file
35
+ */
36
+ declare const GRAPHQL_INDICATORS: readonly ["Document", "useQuery", "useMutation", "useLazyQuery", "useSuspenseQuery", "useBackgroundQuery", "useSubscription", "Query", "Mutation", "gql", "graphql", "GET_", "FETCH_", "SEARCH_", "CREATE_", "UPDATE_", "DELETE_", "SUBSCRIBE_", "@apollo", "ApolloClient"];
37
+ /**
38
+ * Context extracted from a file for GraphQL operation resolution
39
+ */
40
+ interface GraphQLFileContext {
41
+ /** Document imports: import { GetUserDocument } from '...' */
42
+ documentImports: Map<string, string>;
43
+ /** Variable -> operation name mapping from gql() calls */
44
+ variableOperations: Map<string, string>;
45
+ /** Static property mappings: Component.Query = gql`...` */
46
+ staticPropertyOperations: Map<string, string>;
47
+ /** Codegen mapping: Document name -> operation name */
48
+ codegenMap: Map<string, {
49
+ operationName: string;
50
+ type: string;
51
+ }>;
52
+ }
53
+ /**
54
+ * Result of extracting GraphQL operations from a hook call
55
+ */
56
+ interface ExtractedGraphQLOperation {
57
+ operationName: string;
58
+ hookName: string;
59
+ type: DataFetchingInfo['type'];
60
+ variables?: Record<string, string>;
61
+ }
62
+ /**
63
+ * Check if a hook name is a GraphQL query hook
64
+ */
65
+ declare function isQueryHook(hookName: string): boolean;
66
+ /**
67
+ * Check if a hook name is a GraphQL mutation hook
68
+ */
69
+ declare function isMutationHook(hookName: string): boolean;
70
+ /**
71
+ * Check if a hook name is a GraphQL subscription hook
72
+ */
73
+ declare function isSubscriptionHook(hookName: string): boolean;
74
+ /**
75
+ * Check if a hook name is any GraphQL hook
76
+ */
77
+ declare function isGraphQLHook(hookName: string): boolean;
78
+ /**
79
+ * Get the data fetching type for a hook
80
+ */
81
+ declare function getHookType(hookName: string): DataFetchingInfo['type'];
82
+ /**
83
+ * Check if content has any GraphQL indicators
84
+ */
85
+ declare function hasGraphQLIndicators(content: string): boolean;
86
+ /**
87
+ * Clean operation name by removing common suffixes
88
+ */
89
+ declare function cleanOperationName(name: string): string;
90
+ /**
91
+ * Safely parse TypeScript/TSX content to AST
92
+ */
93
+ declare function parseToAst(content: string): Module | null;
94
+ /**
95
+ * Get callee name from a call expression
96
+ */
97
+ declare function getCalleeName(callee: any): string | null;
98
+ /**
99
+ * Traverse AST and call callback for each node
100
+ */
101
+ declare function traverseAst(node: any, callback: (node: any) => void): void;
102
+ /**
103
+ * Extract all GraphQL context from a file in a single AST pass
104
+ * This is the main entry point for file-level analysis
105
+ */
106
+ declare function extractGraphQLContext(ast: Module, content: string, codegenMap?: Map<string, {
107
+ operationName: string;
108
+ type: string;
109
+ }>): GraphQLFileContext;
110
+ /**
111
+ * Extract operation name from gql() function call
112
+ */
113
+ declare function extractOperationNameFromGqlCall(call: any, content: string): string | null;
114
+ /**
115
+ * Extract operation name from template literal
116
+ */
117
+ declare function extractOperationNameFromTemplate(template: any, _content: string): string | null;
118
+ /**
119
+ * Check if a hook call has GraphQL-related arguments
120
+ * This verifies the hook is actually used for GraphQL, not just has a similar name
121
+ * e.g., useQueryParams() is NOT a GraphQL hook, but useQuery(GetUserDocument) IS
122
+ */
123
+ declare function hasGraphQLArgument(call: CallExpression, content: string, context: GraphQLFileContext): boolean;
124
+ /**
125
+ * Resolve operation name from a hook call using file context
126
+ * This is the main API for resolving operation names
127
+ */
128
+ declare function resolveOperationName(call: CallExpression, content: string, context: GraphQLFileContext): string | null;
129
+ /**
130
+ * Extract all GraphQL operations from a file
131
+ * Returns a list of operations with their hook names and types
132
+ */
133
+ declare function extractGraphQLOperationsFromFile(content: string, codegenMap?: Map<string, {
134
+ operationName: string;
135
+ type: string;
136
+ }>): ExtractedGraphQLOperation[];
137
+ /**
138
+ * Get displayable hook info string (for backward compatibility)
139
+ */
140
+ declare function getHookInfoString(op: ExtractedGraphQLOperation): string;
4
141
 
5
142
  /**
6
143
  * Analyzer for REST API calls (fetch, axios, useSWR, etc.)
7
- * REST API呼び出しの分析器
144
+ * Uses @swc/core for fast parsing
8
145
  */
9
146
  declare class RestApiAnalyzer extends BaseAnalyzer {
10
- private project;
11
147
  private apiCallCounter;
12
148
  constructor(config: RepositoryConfig);
13
149
  getName(): string;
14
150
  analyze(): Promise<Partial<AnalysisResult>>;
15
151
  /**
16
- * Find fetch() calls
152
+ * Analyze a parsed module for API calls
153
+ */
154
+ private analyzeModule;
155
+ /**
156
+ * Traverse AST nodes recursively
17
157
  */
18
- private findFetchCalls;
158
+ private traverseNode;
19
159
  /**
20
- * Find axios calls (axios.get, axios.post, etc.)
160
+ * Analyze a call expression for API calls
21
161
  */
22
- private findAxiosCalls;
162
+ private analyzeCallExpression;
23
163
  /**
24
- * Find useSWR calls
164
+ * Get callee name from expression
25
165
  */
26
- private findSwrCalls;
166
+ private getCalleeName;
27
167
  /**
28
- * Extract API call info from fetch()
168
+ * Extract API call from fetch()
29
169
  */
30
170
  private extractFetchCall;
31
171
  /**
32
- * Extract API call info from axios.method()
172
+ * Extract API call from axios.method()
33
173
  */
34
- private extractAxiosCall;
174
+ private extractAxiosMethodCall;
35
175
  /**
36
- * Extract API call info from axios() direct call
176
+ * Extract API call from axios() direct call
37
177
  */
38
178
  private extractAxiosDirectCall;
39
179
  /**
40
- * Extract API call info from useSWR()
180
+ * Extract API call from useSWR()
41
181
  */
42
182
  private extractSwrCall;
43
183
  /**
44
- * Get the name of the containing function/component
184
+ * Extract URL from an expression
45
185
  */
46
- private getContainingFunctionName;
186
+ private extractUrlFromExpression;
47
187
  /**
48
- * Extract URL from argument (handles literals, variables, function calls)
188
+ * Get line number from byte offset
49
189
  */
50
- private extractUrlFromArg;
190
+ private getLineNumber;
51
191
  /**
52
- * Clean string literal (remove quotes)
192
+ * Static file extensions to exclude from API detection
53
193
  */
54
- private cleanStringLiteral;
194
+ private static readonly STATIC_FILE_EXTENSIONS;
55
195
  /**
56
- * Check if URL looks like an API endpoint
196
+ * Non-API URL schemes to exclude
197
+ */
198
+ private static readonly NON_API_SCHEMES;
199
+ /**
200
+ * Check if URL looks like an API endpoint (generic approach)
201
+ * Uses exclusion-based logic: if it's not a static file, it's likely an API
57
202
  */
58
203
  private isApiUrl;
59
204
  /**
60
- * Categorize API by URL pattern
205
+ * Known external service patterns for categorization
206
+ */
207
+ private static readonly SERVICE_PATTERNS;
208
+ /**
209
+ * Categorize API by URL pattern (generic approach)
210
+ * Automatically extracts service name from domain if not in known patterns
61
211
  */
62
212
  private categorizeApi;
63
213
  /**
@@ -66,4 +216,4 @@ declare class RestApiAnalyzer extends BaseAnalyzer {
66
216
  private normalizeMethod;
67
217
  }
68
218
 
69
- export { BaseAnalyzer, RestApiAnalyzer };
219
+ export { ALL_GRAPHQL_HOOKS, BaseAnalyzer, type ExtractedGraphQLOperation, GRAPHQL_INDICATORS, GRAPHQL_MUTATION_HOOKS, GRAPHQL_OTHER_HOOKS, GRAPHQL_QUERY_HOOKS, type GraphQLFileContext, HOOK_TYPE_MAP, RestApiAnalyzer, cleanOperationName, extractGraphQLContext, extractGraphQLOperationsFromFile, extractOperationNameFromGqlCall, extractOperationNameFromTemplate, getCalleeName, getHookInfoString, getHookType, hasGraphQLArgument, hasGraphQLIndicators, isGraphQLHook, isMutationHook, isQueryHook, isSubscriptionHook, parseToAst, resolveOperationName, traverseAst };
@@ -1 +1 @@
1
- export{a as BaseAnalyzer,d as DataFlowAnalyzer,c as GraphQLAnalyzer,b as PagesAnalyzer,e as RestApiAnalyzer}from'../chunk-BPV4UZSW.js';
1
+ export{e as ALL_GRAPHQL_HOOKS,a as BaseAnalyzer,A as DataFlowAnalyzer,g as GRAPHQL_INDICATORS,c as GRAPHQL_MUTATION_HOOKS,d as GRAPHQL_OTHER_HOOKS,b as GRAPHQL_QUERY_HOOKS,z as GraphQLAnalyzer,f as HOOK_TYPE_MAP,y as PagesAnalyzer,B as RestApiAnalyzer,n as cleanOperationName,r as extractGraphQLContext,w as extractGraphQLOperationsFromFile,s as extractOperationNameFromGqlCall,t as extractOperationNameFromTemplate,p as getCalleeName,x as getHookInfoString,l as getHookType,u as hasGraphQLArgument,m as hasGraphQLIndicators,k as isGraphQLHook,i as isMutationHook,h as isQueryHook,j as isSubscriptionHook,o as parseToAst,v as resolveOperationName,q as traverseAst}from'../chunk-TNUKDIO7.js';