@wtdlee/repomap 0.1.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 (123) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +527 -0
  3. package/dist/analyzers/base-analyzer.d.ts +46 -0
  4. package/dist/analyzers/base-analyzer.d.ts.map +1 -0
  5. package/dist/analyzers/base-analyzer.js +48 -0
  6. package/dist/analyzers/base-analyzer.js.map +1 -0
  7. package/dist/analyzers/dataflow-analyzer.d.ts +30 -0
  8. package/dist/analyzers/dataflow-analyzer.d.ts.map +1 -0
  9. package/dist/analyzers/dataflow-analyzer.js +426 -0
  10. package/dist/analyzers/dataflow-analyzer.js.map +1 -0
  11. package/dist/analyzers/graphql-analyzer.d.ts +23 -0
  12. package/dist/analyzers/graphql-analyzer.d.ts.map +1 -0
  13. package/dist/analyzers/graphql-analyzer.js +387 -0
  14. package/dist/analyzers/graphql-analyzer.js.map +1 -0
  15. package/dist/analyzers/index.d.ts +6 -0
  16. package/dist/analyzers/index.d.ts.map +1 -0
  17. package/dist/analyzers/index.js +6 -0
  18. package/dist/analyzers/index.js.map +1 -0
  19. package/dist/analyzers/pages-analyzer.d.ts +85 -0
  20. package/dist/analyzers/pages-analyzer.d.ts.map +1 -0
  21. package/dist/analyzers/pages-analyzer.js +1696 -0
  22. package/dist/analyzers/pages-analyzer.js.map +1 -0
  23. package/dist/analyzers/rails/index.d.ts +47 -0
  24. package/dist/analyzers/rails/index.d.ts.map +1 -0
  25. package/dist/analyzers/rails/index.js +146 -0
  26. package/dist/analyzers/rails/index.js.map +1 -0
  27. package/dist/analyzers/rails/rails-controller-analyzer.d.ts +83 -0
  28. package/dist/analyzers/rails/rails-controller-analyzer.d.ts.map +1 -0
  29. package/dist/analyzers/rails/rails-controller-analyzer.js +479 -0
  30. package/dist/analyzers/rails/rails-controller-analyzer.js.map +1 -0
  31. package/dist/analyzers/rails/rails-grpc-analyzer.d.ts +45 -0
  32. package/dist/analyzers/rails/rails-grpc-analyzer.d.ts.map +1 -0
  33. package/dist/analyzers/rails/rails-grpc-analyzer.js +263 -0
  34. package/dist/analyzers/rails/rails-grpc-analyzer.js.map +1 -0
  35. package/dist/analyzers/rails/rails-model-analyzer.d.ts +89 -0
  36. package/dist/analyzers/rails/rails-model-analyzer.d.ts.map +1 -0
  37. package/dist/analyzers/rails/rails-model-analyzer.js +494 -0
  38. package/dist/analyzers/rails/rails-model-analyzer.js.map +1 -0
  39. package/dist/analyzers/rails/rails-react-analyzer.d.ts +42 -0
  40. package/dist/analyzers/rails/rails-react-analyzer.d.ts.map +1 -0
  41. package/dist/analyzers/rails/rails-react-analyzer.js +530 -0
  42. package/dist/analyzers/rails/rails-react-analyzer.js.map +1 -0
  43. package/dist/analyzers/rails/rails-routes-analyzer.d.ts +63 -0
  44. package/dist/analyzers/rails/rails-routes-analyzer.d.ts.map +1 -0
  45. package/dist/analyzers/rails/rails-routes-analyzer.js +541 -0
  46. package/dist/analyzers/rails/rails-routes-analyzer.js.map +1 -0
  47. package/dist/analyzers/rails/rails-view-analyzer.d.ts +50 -0
  48. package/dist/analyzers/rails/rails-view-analyzer.d.ts.map +1 -0
  49. package/dist/analyzers/rails/rails-view-analyzer.js +387 -0
  50. package/dist/analyzers/rails/rails-view-analyzer.js.map +1 -0
  51. package/dist/analyzers/rails/ruby-parser.d.ts +64 -0
  52. package/dist/analyzers/rails/ruby-parser.d.ts.map +1 -0
  53. package/dist/analyzers/rails/ruby-parser.js +213 -0
  54. package/dist/analyzers/rails/ruby-parser.js.map +1 -0
  55. package/dist/analyzers/rest-api-analyzer.d.ts +66 -0
  56. package/dist/analyzers/rest-api-analyzer.d.ts.map +1 -0
  57. package/dist/analyzers/rest-api-analyzer.js +480 -0
  58. package/dist/analyzers/rest-api-analyzer.js.map +1 -0
  59. package/dist/cli.d.ts +3 -0
  60. package/dist/cli.d.ts.map +1 -0
  61. package/dist/cli.js +550 -0
  62. package/dist/cli.js.map +1 -0
  63. package/dist/core/cache.d.ts +48 -0
  64. package/dist/core/cache.d.ts.map +1 -0
  65. package/dist/core/cache.js +152 -0
  66. package/dist/core/cache.js.map +1 -0
  67. package/dist/core/engine.d.ts +47 -0
  68. package/dist/core/engine.d.ts.map +1 -0
  69. package/dist/core/engine.js +320 -0
  70. package/dist/core/engine.js.map +1 -0
  71. package/dist/core/index.d.ts +3 -0
  72. package/dist/core/index.d.ts.map +1 -0
  73. package/dist/core/index.js +3 -0
  74. package/dist/core/index.js.map +1 -0
  75. package/dist/generators/assets/common.css +187 -0
  76. package/dist/generators/assets/docs.css +363 -0
  77. package/dist/generators/assets/page-map.css +305 -0
  78. package/dist/generators/assets/rails-map.css +473 -0
  79. package/dist/generators/index.d.ts +4 -0
  80. package/dist/generators/index.d.ts.map +1 -0
  81. package/dist/generators/index.js +4 -0
  82. package/dist/generators/index.js.map +1 -0
  83. package/dist/generators/markdown-generator.d.ts +26 -0
  84. package/dist/generators/markdown-generator.d.ts.map +1 -0
  85. package/dist/generators/markdown-generator.js +783 -0
  86. package/dist/generators/markdown-generator.js.map +1 -0
  87. package/dist/generators/mermaid-generator.d.ts +36 -0
  88. package/dist/generators/mermaid-generator.d.ts.map +1 -0
  89. package/dist/generators/mermaid-generator.js +365 -0
  90. package/dist/generators/mermaid-generator.js.map +1 -0
  91. package/dist/generators/page-map-generator.d.ts +23 -0
  92. package/dist/generators/page-map-generator.d.ts.map +1 -0
  93. package/dist/generators/page-map-generator.js +3563 -0
  94. package/dist/generators/page-map-generator.js.map +1 -0
  95. package/dist/generators/rails-map-generator.d.ts +22 -0
  96. package/dist/generators/rails-map-generator.d.ts.map +1 -0
  97. package/dist/generators/rails-map-generator.js +909 -0
  98. package/dist/generators/rails-map-generator.js.map +1 -0
  99. package/dist/index.d.ts +11 -0
  100. package/dist/index.d.ts.map +1 -0
  101. package/dist/index.js +12 -0
  102. package/dist/index.js.map +1 -0
  103. package/dist/server/doc-server.d.ts +31 -0
  104. package/dist/server/doc-server.d.ts.map +1 -0
  105. package/dist/server/doc-server.js +1233 -0
  106. package/dist/server/doc-server.js.map +1 -0
  107. package/dist/server/index.d.ts +2 -0
  108. package/dist/server/index.d.ts.map +1 -0
  109. package/dist/server/index.js +2 -0
  110. package/dist/server/index.js.map +1 -0
  111. package/dist/types.d.ts +294 -0
  112. package/dist/types.d.ts.map +1 -0
  113. package/dist/types.js +6 -0
  114. package/dist/types.js.map +1 -0
  115. package/dist/utils/env-detector.d.ts +32 -0
  116. package/dist/utils/env-detector.d.ts.map +1 -0
  117. package/dist/utils/env-detector.js +189 -0
  118. package/dist/utils/env-detector.js.map +1 -0
  119. package/dist/utils/parallel.d.ts +24 -0
  120. package/dist/utils/parallel.d.ts.map +1 -0
  121. package/dist/utils/parallel.js +71 -0
  122. package/dist/utils/parallel.js.map +1 -0
  123. package/package.json +131 -0
@@ -0,0 +1,530 @@
1
+ /**
2
+ * Rails React Component Analyzer
3
+ * Analyzes React components used in Rails views (HAML/ERB)
4
+ * and maps them to their entry points and source files
5
+ *
6
+ * Supports multiple React-Rails integration patterns:
7
+ * - react-rails gem (data-react-component, render_react_component)
8
+ * - react_on_rails gem (react_component, redux_store)
9
+ * - Webpacker packs
10
+ * - Vite entrypoints
11
+ * - Custom entry point patterns
12
+ */
13
+ import * as path from 'path';
14
+ import * as fs from 'fs/promises';
15
+ import { glob } from 'glob';
16
+ // Common entry point directory patterns
17
+ const COMMON_ENTRY_PATTERNS = [
18
+ // Webpacker (Rails 5.1+)
19
+ 'app/javascript/packs',
20
+ 'app/javascript/entrypoints',
21
+ // Vite Rails
22
+ 'app/frontend/entrypoints',
23
+ // jsbundling-rails
24
+ 'app/javascript/application',
25
+ // Custom patterns
26
+ 'frontend/assets/javascripts/entries',
27
+ 'frontend/entries',
28
+ 'app/assets/javascripts/entries',
29
+ 'client/entries',
30
+ 'src/entries',
31
+ ];
32
+ // Common component directory patterns
33
+ const COMMON_COMPONENT_PATTERNS = [
34
+ // Standard Rails
35
+ 'app/javascript/components',
36
+ 'app/javascript/react',
37
+ 'app/javascript/src/components',
38
+ // Webpacker
39
+ 'app/javascript/bundles',
40
+ // Vite
41
+ 'app/frontend/components',
42
+ 'app/frontend/react',
43
+ // Custom patterns
44
+ 'frontend/assets/javascripts/react',
45
+ 'frontend/assets/javascripts/components',
46
+ 'frontend/src',
47
+ 'frontend/src/components',
48
+ 'frontend/components',
49
+ 'client/components',
50
+ 'src/components',
51
+ ];
52
+ // React mount patterns in views
53
+ const VIEW_PATTERNS = {
54
+ // react-rails gem
55
+ dataReactComponent: /react_component:\s*["']([A-Za-z0-9_/]+)["']/g,
56
+ renderReactComponent: /render_react_component\s*\(?\s*["']([A-Za-z0-9_/]+)["']/g,
57
+ // react_on_rails gem
58
+ reactComponent: /<%=?\s*react_component\s*\(\s*["']([A-Za-z0-9_/]+)["']/g,
59
+ reduxStore: /<%=?\s*redux_store\s*\(\s*["']([A-Za-z0-9_/]+)["']/g,
60
+ // Generic patterns
61
+ dataComponent: /data-component\s*[=:]\s*["']([A-Za-z0-9_/]+)["']/g,
62
+ dataReactClass: /data-react-class\s*[=:]\s*["']([A-Za-z0-9_/]+)["']/g,
63
+ };
64
+ export async function analyzeReactComponents(rootPath) {
65
+ const components = new Map();
66
+ const entryPoints = [];
67
+ // 1. Detect project structure
68
+ const detectedPaths = await detectProjectStructure(rootPath);
69
+ console.log(` 📂 Detected paths: ${detectedPaths.entryDirs.length} entry dirs, ${detectedPaths.componentDirs.length} component dirs (${detectedPaths.integrationPattern})`);
70
+ // 2. Analyze entry point files from all detected directories
71
+ for (const entryDir of detectedPaths.entryDirs) {
72
+ const fullEntryDir = path.join(rootPath, entryDir);
73
+ try {
74
+ await fs.access(fullEntryDir);
75
+ const entryFiles = await glob('**/*.{tsx,ts,jsx,js}', {
76
+ cwd: fullEntryDir,
77
+ nodir: true,
78
+ ignore: ['**/*.d.ts', '**/*.test.*', '**/*.spec.*'],
79
+ });
80
+ for (const file of entryFiles) {
81
+ const entryInfo = await parseEntryPoint(path.join(fullEntryDir, file), file, entryDir);
82
+ if (entryInfo) {
83
+ entryPoints.push(entryInfo);
84
+ // Create or update component mapping
85
+ if (entryInfo.componentName) {
86
+ const existing = components.get(entryInfo.componentName);
87
+ if (existing) {
88
+ existing.entryFile = path.join(entryDir, file);
89
+ existing.importPath = entryInfo.imports[0];
90
+ }
91
+ else {
92
+ components.set(entryInfo.componentName, {
93
+ name: entryInfo.componentName,
94
+ entryFile: path.join(entryDir, file),
95
+ importPath: entryInfo.imports[0],
96
+ ssr: false,
97
+ usedIn: [],
98
+ });
99
+ }
100
+ }
101
+ }
102
+ }
103
+ }
104
+ catch {
105
+ // Entry directory doesn't exist
106
+ }
107
+ }
108
+ // 3. Analyze view files for React component usage
109
+ const viewsPath = path.join(rootPath, 'app/views');
110
+ try {
111
+ await fs.access(viewsPath);
112
+ const viewFiles = await glob('**/*.{haml,erb,html.haml,html.erb,slim}', {
113
+ cwd: viewsPath,
114
+ nodir: true,
115
+ });
116
+ for (const viewFile of viewFiles) {
117
+ const usages = await findReactUsageInView(path.join(viewsPath, viewFile), viewFile);
118
+ for (const usage of usages) {
119
+ const existing = components.get(usage.componentName);
120
+ if (existing) {
121
+ existing.usedIn.push({
122
+ viewPath: viewFile,
123
+ controller: usage.controller,
124
+ action: usage.action,
125
+ propsVar: usage.propsVar,
126
+ line: usage.line,
127
+ pattern: usage.pattern,
128
+ });
129
+ if (usage.ssr)
130
+ existing.ssr = true;
131
+ }
132
+ else {
133
+ components.set(usage.componentName, {
134
+ name: usage.componentName,
135
+ ssr: usage.ssr,
136
+ usedIn: [
137
+ {
138
+ viewPath: viewFile,
139
+ controller: usage.controller,
140
+ action: usage.action,
141
+ propsVar: usage.propsVar,
142
+ line: usage.line,
143
+ pattern: usage.pattern,
144
+ },
145
+ ],
146
+ });
147
+ }
148
+ }
149
+ }
150
+ }
151
+ catch {
152
+ // Views directory doesn't exist
153
+ }
154
+ // 4. Try to resolve source files for components
155
+ await resolveSourceFiles(rootPath, components, detectedPaths.componentDirs);
156
+ const componentList = Array.from(components.values());
157
+ const ssrCount = componentList.filter((c) => c.ssr).length;
158
+ return {
159
+ components: componentList,
160
+ entryPoints,
161
+ detectedPaths,
162
+ summary: {
163
+ totalComponents: componentList.length,
164
+ totalEntryPoints: entryPoints.length,
165
+ ssrComponents: ssrCount,
166
+ clientComponents: componentList.length - ssrCount,
167
+ },
168
+ };
169
+ }
170
+ /**
171
+ * Auto-detect project structure for React integration
172
+ */
173
+ async function detectProjectStructure(rootPath) {
174
+ const entryDirs = [];
175
+ const componentDirs = [];
176
+ let integrationPattern = 'unknown';
177
+ // Check for entry point directories
178
+ for (const pattern of COMMON_ENTRY_PATTERNS) {
179
+ const fullPath = path.join(rootPath, pattern);
180
+ try {
181
+ const stat = await fs.stat(fullPath);
182
+ if (stat.isDirectory()) {
183
+ entryDirs.push(pattern);
184
+ }
185
+ }
186
+ catch {
187
+ // Directory doesn't exist
188
+ }
189
+ }
190
+ // Check for component directories
191
+ for (const pattern of COMMON_COMPONENT_PATTERNS) {
192
+ const fullPath = path.join(rootPath, pattern);
193
+ try {
194
+ const stat = await fs.stat(fullPath);
195
+ if (stat.isDirectory()) {
196
+ componentDirs.push(pattern);
197
+ }
198
+ }
199
+ catch {
200
+ // Directory doesn't exist
201
+ }
202
+ }
203
+ // Detect integration pattern
204
+ integrationPattern = await detectIntegrationPattern(rootPath);
205
+ // If no entry dirs found, try to find any directory with React entry patterns
206
+ if (entryDirs.length === 0) {
207
+ const fallbackDirs = await findEntryPointDirectories(rootPath);
208
+ entryDirs.push(...fallbackDirs);
209
+ }
210
+ // If no component dirs found, use entry dirs as fallback
211
+ if (componentDirs.length === 0 && entryDirs.length > 0) {
212
+ componentDirs.push(...entryDirs);
213
+ }
214
+ return { entryDirs, componentDirs, integrationPattern };
215
+ }
216
+ /**
217
+ * Detect which React-Rails integration pattern is used
218
+ */
219
+ async function detectIntegrationPattern(rootPath) {
220
+ try {
221
+ // Check Gemfile for gem detection
222
+ const gemfilePath = path.join(rootPath, 'Gemfile');
223
+ const gemfile = await fs.readFile(gemfilePath, 'utf-8');
224
+ if (gemfile.includes('react_on_rails'))
225
+ return 'react_on_rails';
226
+ if (gemfile.includes('react-rails'))
227
+ return 'react-rails';
228
+ if (gemfile.includes('vite_rails') || gemfile.includes('vite_ruby'))
229
+ return 'vite';
230
+ if (gemfile.includes('webpacker'))
231
+ return 'webpacker';
232
+ // Check for vite.config
233
+ try {
234
+ await fs.access(path.join(rootPath, 'vite.config.ts'));
235
+ return 'vite';
236
+ }
237
+ catch {
238
+ // No vite config
239
+ }
240
+ try {
241
+ await fs.access(path.join(rootPath, 'vite.config.js'));
242
+ return 'vite';
243
+ }
244
+ catch {
245
+ // No vite config
246
+ }
247
+ return 'custom';
248
+ }
249
+ catch {
250
+ return 'unknown';
251
+ }
252
+ }
253
+ /**
254
+ * Find directories that contain React entry point files
255
+ */
256
+ async function findEntryPointDirectories(rootPath) {
257
+ const dirs = [];
258
+ // Search for directories that look like entry points
259
+ const searchPatterns = [
260
+ 'app/**/entries',
261
+ 'app/**/packs',
262
+ 'frontend/**/entries',
263
+ 'client/**/entries',
264
+ 'src/**/entries',
265
+ ];
266
+ for (const pattern of searchPatterns) {
267
+ try {
268
+ const matches = await glob(pattern, {
269
+ cwd: rootPath,
270
+ nodir: false,
271
+ });
272
+ // Filter to only include directories
273
+ for (const match of matches) {
274
+ const fullPath = path.join(rootPath, match);
275
+ try {
276
+ const stat = await fs.stat(fullPath);
277
+ if (stat.isDirectory()) {
278
+ dirs.push(match);
279
+ }
280
+ }
281
+ catch {
282
+ // Skip if can't stat
283
+ }
284
+ }
285
+ }
286
+ catch {
287
+ // Glob error
288
+ }
289
+ }
290
+ return dirs;
291
+ }
292
+ async function parseEntryPoint(fullPath, relativePath, entryDir) {
293
+ try {
294
+ const content = await fs.readFile(fullPath, 'utf-8');
295
+ // Find component name from various selector patterns
296
+ const selectorPatterns = [
297
+ /\[data-react-component[=:][\s]*["']?([A-Za-z0-9_]+)["']?\]/,
298
+ /\[data-component[=:][\s]*["']?([A-Za-z0-9_]+)["']?\]/,
299
+ /\[data-react-class[=:][\s]*["']?([A-Za-z0-9_]+)["']?\]/,
300
+ /getElementById\s*\(\s*["']([A-Za-z0-9_-]+)["']\s*\)/,
301
+ /querySelector\s*\(\s*["']#([A-Za-z0-9_-]+)["']\s*\)/,
302
+ ];
303
+ let componentName = null;
304
+ let selector;
305
+ for (const pattern of selectorPatterns) {
306
+ const match = content.match(pattern);
307
+ if (match) {
308
+ componentName = match[1];
309
+ selector = match[0];
310
+ break;
311
+ }
312
+ }
313
+ // Try to extract component name from file name if not found
314
+ if (!componentName) {
315
+ const baseName = path.basename(relativePath, path.extname(relativePath));
316
+ // Convert snake_case or kebab-case to PascalCase
317
+ componentName = baseName
318
+ .split(/[-_]/)
319
+ .map((s) => s.charAt(0).toUpperCase() + s.slice(1))
320
+ .join('');
321
+ }
322
+ // Find imports that look like React components
323
+ const imports = [];
324
+ const importMatches = content.matchAll(/import\s+(?:\{[^}]+\}|\*\s+as\s+\w+|\w+)\s+from\s+["']([^"']+)["']/g);
325
+ for (const match of importMatches) {
326
+ const importPath = match[1];
327
+ // Filter for likely component imports
328
+ if (importPath.includes('/react/') ||
329
+ importPath.includes('/components/') ||
330
+ importPath.includes('/containers/') ||
331
+ importPath.includes('/bundles/') ||
332
+ importPath.includes('/pages/') ||
333
+ importPath.match(/\/[A-Z][a-zA-Z0-9]*/)) {
334
+ imports.push(importPath);
335
+ }
336
+ }
337
+ // Also check for require statements (CommonJS)
338
+ const requireMatches = content.matchAll(/require\s*\(\s*["']([^"']+)["']\s*\)/g);
339
+ for (const match of requireMatches) {
340
+ const requirePath = match[1];
341
+ if (requirePath.includes('/react/') ||
342
+ requirePath.includes('/components/') ||
343
+ requirePath.includes('/containers/')) {
344
+ imports.push(requirePath);
345
+ }
346
+ }
347
+ if (!componentName && imports.length === 0)
348
+ return null;
349
+ return {
350
+ file: relativePath,
351
+ fullPath: path.join(entryDir, relativePath),
352
+ componentName: componentName || '',
353
+ imports,
354
+ selector,
355
+ };
356
+ }
357
+ catch {
358
+ return null;
359
+ }
360
+ }
361
+ async function findReactUsageInView(fullPath, relativePath) {
362
+ const usages = [];
363
+ try {
364
+ const content = await fs.readFile(fullPath, 'utf-8');
365
+ const lines = content.split('\n');
366
+ // Parse controller and action from path
367
+ const parts = relativePath.split('/');
368
+ const fileName = parts.pop() || '';
369
+ const controller = parts.join('/') || 'application';
370
+ const action = fileName.split('.')[0].replace(/^_/, '');
371
+ let lineNum = 0;
372
+ for (const line of lines) {
373
+ lineNum++;
374
+ // Pattern 1: data: { react_component: "ComponentName" } (react-rails)
375
+ const dataMatches = line.matchAll(VIEW_PATTERNS.dataReactComponent);
376
+ for (const match of dataMatches) {
377
+ const propsMatch = line.match(/react_component_props:\s*(@?\w+(?:\.\w+)*)/);
378
+ usages.push({
379
+ componentName: match[1],
380
+ controller,
381
+ action,
382
+ propsVar: propsMatch ? propsMatch[1] : undefined,
383
+ line: lineNum,
384
+ pattern: 'data-react-component',
385
+ ssr: false,
386
+ });
387
+ }
388
+ // Pattern 2: render_react_component("ComponentName", ...) (react-rails)
389
+ const renderMatch = line.match(VIEW_PATTERNS.renderReactComponent);
390
+ if (renderMatch) {
391
+ const ssrMatch = line.match(/ssr:\s*(true|false|@\w+)/);
392
+ usages.push({
393
+ componentName: renderMatch[1],
394
+ controller,
395
+ action,
396
+ line: lineNum,
397
+ pattern: 'render_react_component',
398
+ ssr: ssrMatch ? ssrMatch[1] === 'true' || ssrMatch[1].startsWith('@') : false,
399
+ });
400
+ }
401
+ // Pattern 3: react_component("ComponentName", ...) (react_on_rails)
402
+ const reactOnRailsMatch = line.match(VIEW_PATTERNS.reactComponent);
403
+ if (reactOnRailsMatch) {
404
+ const propsMatch = line.match(/props:\s*(@?\w+(?:\.\w+)*)/);
405
+ const prerenderMatch = line.match(/prerender:\s*(true|false)/);
406
+ usages.push({
407
+ componentName: reactOnRailsMatch[1],
408
+ controller,
409
+ action,
410
+ propsVar: propsMatch ? propsMatch[1] : undefined,
411
+ line: lineNum,
412
+ pattern: 'react_component',
413
+ ssr: prerenderMatch ? prerenderMatch[1] === 'true' : false,
414
+ });
415
+ }
416
+ // Pattern 4: redux_store("StoreName", ...) (react_on_rails)
417
+ const reduxMatch = line.match(VIEW_PATTERNS.reduxStore);
418
+ if (reduxMatch) {
419
+ usages.push({
420
+ componentName: reduxMatch[1],
421
+ controller,
422
+ action,
423
+ line: lineNum,
424
+ pattern: 'redux_store',
425
+ ssr: false,
426
+ });
427
+ }
428
+ // Pattern 5: data-component="ComponentName" (generic)
429
+ const dataCompMatch = line.match(VIEW_PATTERNS.dataComponent);
430
+ if (dataCompMatch) {
431
+ usages.push({
432
+ componentName: dataCompMatch[1],
433
+ controller,
434
+ action,
435
+ line: lineNum,
436
+ pattern: 'data-react-component',
437
+ ssr: false,
438
+ });
439
+ }
440
+ // Pattern 6: data-react-class="ComponentName" (legacy react-rails)
441
+ const reactClassMatch = line.match(VIEW_PATTERNS.dataReactClass);
442
+ if (reactClassMatch) {
443
+ usages.push({
444
+ componentName: reactClassMatch[1],
445
+ controller,
446
+ action,
447
+ line: lineNum,
448
+ pattern: 'data-react-component',
449
+ ssr: false,
450
+ });
451
+ }
452
+ }
453
+ }
454
+ catch {
455
+ // Error reading file
456
+ }
457
+ return usages;
458
+ }
459
+ async function resolveSourceFiles(rootPath, components, componentDirs) {
460
+ for (const [name, component] of components) {
461
+ // Skip if name is invalid
462
+ if (!name || typeof name !== 'string')
463
+ continue;
464
+ if (component.importPath && typeof component.importPath === 'string') {
465
+ // Resolve from import path
466
+ const cleanPath = component.importPath
467
+ .replace(/\.js$/, '')
468
+ .replace(/\.tsx?$/, '')
469
+ .replace(/^\.\.\//, '')
470
+ .replace(/^\.\//, '');
471
+ component.sourceFile = cleanPath;
472
+ }
473
+ else if (!component.sourceFile) {
474
+ // Try to find by component name in all component directories
475
+ const extensions = ['.tsx', '.ts', '.jsx', '.js'];
476
+ const namingPatterns = [
477
+ name, // PascalCase
478
+ toSnakeCase(name), // snake_case
479
+ toKebabCase(name), // kebab-case
480
+ ].filter(Boolean);
481
+ let found = false;
482
+ for (const dir of componentDirs) {
483
+ if (found)
484
+ break;
485
+ for (const naming of namingPatterns) {
486
+ if (found)
487
+ break;
488
+ for (const ext of extensions) {
489
+ const possiblePaths = [
490
+ path.join(rootPath, dir, naming, `index${ext}`),
491
+ path.join(rootPath, dir, naming, `${naming}${ext}`),
492
+ path.join(rootPath, dir, `${naming}${ext}`),
493
+ path.join(rootPath, dir, 'components', `${naming}${ext}`),
494
+ path.join(rootPath, dir, 'containers', `${naming}${ext}`),
495
+ ];
496
+ for (const possiblePath of possiblePaths) {
497
+ try {
498
+ await fs.access(possiblePath);
499
+ component.sourceFile = path.relative(rootPath, possiblePath);
500
+ found = true;
501
+ break;
502
+ }
503
+ catch {
504
+ // File doesn't exist, try next
505
+ }
506
+ }
507
+ }
508
+ }
509
+ }
510
+ }
511
+ }
512
+ }
513
+ // Helper functions for case conversion
514
+ function toSnakeCase(str) {
515
+ if (!str)
516
+ return '';
517
+ return str
518
+ .replace(/([A-Z])/g, '_$1')
519
+ .toLowerCase()
520
+ .replace(/^_/, '');
521
+ }
522
+ function toKebabCase(str) {
523
+ if (!str)
524
+ return '';
525
+ return str
526
+ .replace(/([A-Z])/g, '-$1')
527
+ .toLowerCase()
528
+ .replace(/^-/, '');
529
+ }
530
+ //# sourceMappingURL=rails-react-analyzer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rails-react-analyzer.js","sourceRoot":"","sources":["../../../src/analyzers/rails/rails-react-analyzer.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,63 @@
1
+ /**
2
+ * Rails Routes Analyzer using tree-sitter
3
+ * tree-sitterを使用してroutes.rbを解析する
4
+ */
5
+ export interface RailsRoute {
6
+ method: 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE' | 'ALL';
7
+ path: string;
8
+ controller: string;
9
+ action: string;
10
+ name?: string;
11
+ namespace?: string;
12
+ authenticated?: boolean;
13
+ line: number;
14
+ }
15
+ export interface ResourceInfo {
16
+ name: string;
17
+ controller: string;
18
+ only?: string[];
19
+ except?: string[];
20
+ nested: ResourceInfo[];
21
+ memberRoutes: RailsRoute[];
22
+ collectionRoutes: RailsRoute[];
23
+ line: number;
24
+ }
25
+ export interface MountedEngine {
26
+ engine: string;
27
+ mountPath: string;
28
+ line: number;
29
+ }
30
+ export interface RailsRoutesResult {
31
+ routes: RailsRoute[];
32
+ namespaces: string[];
33
+ resources: ResourceInfo[];
34
+ mountedEngines: MountedEngine[];
35
+ drawnFiles: string[];
36
+ errors: string[];
37
+ }
38
+ export declare class RailsRoutesAnalyzer {
39
+ private rootPath;
40
+ private routesDir;
41
+ private routes;
42
+ private namespaces;
43
+ private resources;
44
+ private mountedEngines;
45
+ private drawnFiles;
46
+ private errors;
47
+ constructor(rootPath: string);
48
+ analyze(): Promise<RailsRoutesResult>;
49
+ private parseRoutesFile;
50
+ private parseHttpRoute;
51
+ private parseResources;
52
+ private parseMemberCollectionRoutes;
53
+ private parseNamespace;
54
+ private parseMount;
55
+ private parseDraw;
56
+ private parseDeviseFor;
57
+ private parseRoot;
58
+ private generateResourceRoutes;
59
+ private buildPath;
60
+ private extractStringValue;
61
+ private extractArrayValues;
62
+ }
63
+ //# sourceMappingURL=rails-routes-analyzer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rails-routes-analyzer.d.ts","sourceRoot":"","sources":["../../../src/analyzers/rails/rails-routes-analyzer.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAaH,MAAM,WAAW,UAAU;IACzB,MAAM,EAAE,KAAK,GAAG,MAAM,GAAG,KAAK,GAAG,OAAO,GAAG,QAAQ,GAAG,KAAK,CAAC;IAC5D,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB,MAAM,EAAE,YAAY,EAAE,CAAC;IACvB,YAAY,EAAE,UAAU,EAAE,CAAC;IAC3B,gBAAgB,EAAE,UAAU,EAAE,CAAC;IAC/B,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,iBAAiB;IAChC,MAAM,EAAE,UAAU,EAAE,CAAC;IACrB,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,SAAS,EAAE,YAAY,EAAE,CAAC;IAC1B,cAAc,EAAE,aAAa,EAAE,CAAC;IAChC,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB;AAED,qBAAa,mBAAmB;IASlB,OAAO,CAAC,QAAQ;IAR5B,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,MAAM,CAAoB;IAClC,OAAO,CAAC,UAAU,CAAgB;IAClC,OAAO,CAAC,SAAS,CAAsB;IACvC,OAAO,CAAC,cAAc,CAAuB;IAC7C,OAAO,CAAC,UAAU,CAAgB;IAClC,OAAO,CAAC,MAAM,CAAgB;gBAEV,QAAQ,EAAE,MAAM;IAI9B,OAAO,IAAI,OAAO,CAAC,iBAAiB,CAAC;YA8B7B,eAAe;IAoD7B,OAAO,CAAC,cAAc;YAkER,cAAc;IAoE5B,OAAO,CAAC,2BAA2B;YA0CrB,cAAc;IAiD5B,OAAO,CAAC,UAAU;YAsCJ,SAAS;IAiBvB,OAAO,CAAC,cAAc;IAiEtB,OAAO,CAAC,SAAS;IAwCjB,OAAO,CAAC,sBAAsB;IA2D9B,OAAO,CAAC,SAAS;IASjB,OAAO,CAAC,kBAAkB;IAe1B,OAAO,CAAC,kBAAkB;CAmB3B"}