@wtdlee/repomap 0.3.0 → 0.3.1

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 (71) hide show
  1. package/dist/analyzers/index.d.ts +69 -5
  2. package/dist/analyzers/index.js +1 -5
  3. package/dist/chunk-3PWXDB7B.js +153 -0
  4. package/dist/{generators/page-map-generator.js → chunk-3YFXZAP7.js} +322 -358
  5. package/dist/chunk-6F4PWJZI.js +1 -0
  6. package/dist/{generators/rails-map-generator.js → chunk-E4WRODSI.js} +86 -94
  7. package/dist/chunk-GNBMJMET.js +2519 -0
  8. package/dist/{server/doc-server.js → chunk-M6YNU536.js} +702 -303
  9. package/dist/chunk-OWM6WNLE.js +2610 -0
  10. package/dist/chunk-SSU6QFTX.js +1058 -0
  11. package/dist/cli.d.ts +0 -1
  12. package/dist/cli.js +348 -452
  13. package/dist/dataflow-analyzer-BfAiqVUp.d.ts +180 -0
  14. package/dist/env-detector-EEMVUEIA.js +1 -0
  15. package/dist/generators/index.d.ts +431 -3
  16. package/dist/generators/index.js +2 -3
  17. package/dist/index.d.ts +53 -10
  18. package/dist/index.js +8 -11
  19. package/dist/page-map-generator-6MJGPBVA.js +1 -0
  20. package/dist/rails-UWSDRS33.js +1 -0
  21. package/dist/rails-map-generator-D2URLMVJ.js +2 -0
  22. package/dist/server/index.d.ts +33 -1
  23. package/dist/server/index.js +7 -1
  24. package/dist/types.d.ts +39 -37
  25. package/dist/types.js +1 -5
  26. package/package.json +4 -2
  27. package/dist/analyzers/base-analyzer.d.ts +0 -45
  28. package/dist/analyzers/base-analyzer.js +0 -47
  29. package/dist/analyzers/dataflow-analyzer.d.ts +0 -29
  30. package/dist/analyzers/dataflow-analyzer.js +0 -425
  31. package/dist/analyzers/graphql-analyzer.d.ts +0 -22
  32. package/dist/analyzers/graphql-analyzer.js +0 -386
  33. package/dist/analyzers/pages-analyzer.d.ts +0 -84
  34. package/dist/analyzers/pages-analyzer.js +0 -1695
  35. package/dist/analyzers/rails/index.d.ts +0 -46
  36. package/dist/analyzers/rails/index.js +0 -145
  37. package/dist/analyzers/rails/rails-controller-analyzer.d.ts +0 -82
  38. package/dist/analyzers/rails/rails-controller-analyzer.js +0 -478
  39. package/dist/analyzers/rails/rails-grpc-analyzer.d.ts +0 -44
  40. package/dist/analyzers/rails/rails-grpc-analyzer.js +0 -262
  41. package/dist/analyzers/rails/rails-model-analyzer.d.ts +0 -88
  42. package/dist/analyzers/rails/rails-model-analyzer.js +0 -493
  43. package/dist/analyzers/rails/rails-react-analyzer.d.ts +0 -41
  44. package/dist/analyzers/rails/rails-react-analyzer.js +0 -529
  45. package/dist/analyzers/rails/rails-routes-analyzer.d.ts +0 -62
  46. package/dist/analyzers/rails/rails-routes-analyzer.js +0 -540
  47. package/dist/analyzers/rails/rails-view-analyzer.d.ts +0 -49
  48. package/dist/analyzers/rails/rails-view-analyzer.js +0 -386
  49. package/dist/analyzers/rails/ruby-parser.d.ts +0 -63
  50. package/dist/analyzers/rails/ruby-parser.js +0 -212
  51. package/dist/analyzers/rest-api-analyzer.d.ts +0 -65
  52. package/dist/analyzers/rest-api-analyzer.js +0 -479
  53. package/dist/core/cache.d.ts +0 -47
  54. package/dist/core/cache.js +0 -151
  55. package/dist/core/engine.d.ts +0 -46
  56. package/dist/core/engine.js +0 -319
  57. package/dist/core/index.d.ts +0 -2
  58. package/dist/core/index.js +0 -2
  59. package/dist/generators/markdown-generator.d.ts +0 -25
  60. package/dist/generators/markdown-generator.js +0 -782
  61. package/dist/generators/mermaid-generator.d.ts +0 -35
  62. package/dist/generators/mermaid-generator.js +0 -364
  63. package/dist/generators/page-map-generator.d.ts +0 -22
  64. package/dist/generators/rails-map-generator.d.ts +0 -21
  65. package/dist/server/doc-server.d.ts +0 -30
  66. package/dist/utils/env-detector.d.ts +0 -31
  67. package/dist/utils/env-detector.js +0 -188
  68. package/dist/utils/parallel.d.ts +0 -23
  69. package/dist/utils/parallel.js +0 -70
  70. package/dist/utils/port.d.ts +0 -15
  71. package/dist/utils/port.js +0 -41
@@ -1,540 +0,0 @@
1
- /**
2
- * Rails Routes Analyzer using tree-sitter
3
- * tree-sitterを使用してroutes.rbを解析する
4
- */
5
- import * as fs from 'fs';
6
- import * as path from 'path';
7
- import { parseRubyFile, findNodes, getChildByType, getChildrenByType, getCallArguments, } from './ruby-parser.js';
8
- export class RailsRoutesAnalyzer {
9
- rootPath;
10
- routesDir;
11
- routes = [];
12
- namespaces = [];
13
- resources = [];
14
- mountedEngines = [];
15
- drawnFiles = [];
16
- errors = [];
17
- constructor(rootPath) {
18
- this.rootPath = rootPath;
19
- this.routesDir = path.join(rootPath, 'config', 'routes');
20
- }
21
- async analyze() {
22
- const mainRoutesFile = path.join(this.rootPath, 'config', 'routes.rb');
23
- if (!fs.existsSync(mainRoutesFile)) {
24
- return {
25
- routes: [],
26
- namespaces: [],
27
- resources: [],
28
- mountedEngines: [],
29
- drawnFiles: [],
30
- errors: [`routes.rb not found at ${mainRoutesFile}`],
31
- };
32
- }
33
- try {
34
- await this.parseRoutesFile(mainRoutesFile, []);
35
- }
36
- catch (error) {
37
- this.errors.push(`Error parsing ${mainRoutesFile}: ${error}`);
38
- }
39
- return {
40
- routes: this.routes,
41
- namespaces: [...new Set(this.namespaces)],
42
- resources: this.resources,
43
- mountedEngines: this.mountedEngines,
44
- drawnFiles: this.drawnFiles,
45
- errors: this.errors,
46
- };
47
- }
48
- async parseRoutesFile(filePath, currentNamespaces) {
49
- const tree = await parseRubyFile(filePath);
50
- const rootNode = tree.rootNode;
51
- // Find all method calls
52
- const calls = findNodes(rootNode, 'call');
53
- for (const call of calls) {
54
- const methodNode = call.childForFieldName('method');
55
- if (!methodNode)
56
- continue;
57
- const methodName = methodNode.text;
58
- const line = call.startPosition.row + 1;
59
- switch (methodName) {
60
- case 'get':
61
- case 'post':
62
- case 'put':
63
- case 'patch':
64
- case 'delete':
65
- case 'match':
66
- this.parseHttpRoute(call, methodName, currentNamespaces, line);
67
- break;
68
- case 'resources':
69
- case 'resource':
70
- await this.parseResources(call, currentNamespaces, line, methodName === 'resource');
71
- break;
72
- case 'namespace':
73
- await this.parseNamespace(call, currentNamespaces, filePath);
74
- break;
75
- case 'mount':
76
- this.parseMount(call, line);
77
- break;
78
- case 'draw':
79
- await this.parseDraw(call, currentNamespaces);
80
- break;
81
- case 'devise_for':
82
- this.parseDeviseFor(call, currentNamespaces, line);
83
- break;
84
- case 'root':
85
- this.parseRoot(call, currentNamespaces, line);
86
- break;
87
- }
88
- }
89
- }
90
- parseHttpRoute(call, method, namespaces, line) {
91
- const args = getCallArguments(call);
92
- if (args.length === 0)
93
- return;
94
- // First argument is the path
95
- const pathArg = args[0];
96
- const routePath = this.extractStringValue(pathArg);
97
- if (!routePath)
98
- return;
99
- // Find controller#action from 'to:' option or second argument
100
- let controller = '';
101
- let action = '';
102
- // Look for hash/pair arguments
103
- for (const arg of args) {
104
- if (arg.type === 'hash' || arg.type === 'pair') {
105
- const pairs = arg.type === 'hash' ? getChildrenByType(arg, 'pair') : [arg];
106
- for (const pair of pairs) {
107
- const key = pair.child(0)?.text?.replace(/^:/, '');
108
- const value = pair.child(2);
109
- if (key === 'to' && value) {
110
- const toValue = this.extractStringValue(value);
111
- if (toValue && toValue.includes('#')) {
112
- [controller, action] = toValue.split('#');
113
- }
114
- }
115
- }
116
- }
117
- else if (arg.type === 'string' || arg.type === 'string_content') {
118
- const strValue = this.extractStringValue(arg);
119
- if (strValue && strValue.includes('#') && !controller) {
120
- [controller, action] = strValue.split('#');
121
- }
122
- }
123
- }
124
- // If no explicit controller#action, try to infer from path
125
- if (!controller && !action) {
126
- const pathParts = routePath.replace(/^\//, '').split('/');
127
- controller = pathParts[0] || '';
128
- action = pathParts[1] || 'index';
129
- }
130
- // Apply namespace prefix
131
- if (namespaces.length > 0 && controller && !controller.includes('/')) {
132
- controller = `${namespaces.join('/')}/${controller}`;
133
- }
134
- // Build full path with namespace
135
- const fullPath = this.buildPath(namespaces, routePath);
136
- this.routes.push({
137
- method: method === 'match' ? 'ALL' : method.toUpperCase(),
138
- path: fullPath,
139
- controller,
140
- action,
141
- namespace: namespaces.join('/') || undefined,
142
- line,
143
- });
144
- }
145
- async parseResources(call, namespaces, line, singular) {
146
- const args = getCallArguments(call);
147
- if (args.length === 0)
148
- return;
149
- // First argument is the resource name (symbol)
150
- const nameArg = args[0];
151
- const resourceName = nameArg.text.replace(/^:/, '');
152
- const resource = {
153
- name: resourceName,
154
- controller: namespaces.length > 0 ? `${namespaces.join('/')}/${resourceName}` : resourceName,
155
- nested: [],
156
- memberRoutes: [],
157
- collectionRoutes: [],
158
- line,
159
- };
160
- // Parse options (only:, except:, etc.)
161
- for (const arg of args) {
162
- if (arg.type === 'hash') {
163
- const pairs = getChildrenByType(arg, 'pair');
164
- for (const pair of pairs) {
165
- const key = pair.child(0)?.text?.replace(/^:/, '');
166
- const value = pair.child(2);
167
- if (key === 'only' && value) {
168
- resource.only = this.extractArrayValues(value);
169
- }
170
- else if (key === 'except' && value) {
171
- resource.except = this.extractArrayValues(value);
172
- }
173
- }
174
- }
175
- }
176
- // Generate RESTful routes
177
- this.generateResourceRoutes(resource, namespaces, singular);
178
- this.resources.push(resource);
179
- // Parse nested block if exists
180
- const block = call.childForFieldName('block');
181
- if (block) {
182
- // Look for member/collection blocks and nested resources
183
- const nestedCalls = findNodes(block, 'call');
184
- for (const nestedCall of nestedCalls) {
185
- const nestedMethod = nestedCall.childForFieldName('method')?.text;
186
- if (nestedMethod === 'member') {
187
- // Parse member routes
188
- const memberBlock = nestedCall.childForFieldName('block');
189
- if (memberBlock) {
190
- this.parseMemberCollectionRoutes(memberBlock, resource, namespaces, 'member');
191
- }
192
- }
193
- else if (nestedMethod === 'collection') {
194
- // Parse collection routes
195
- const collectionBlock = nestedCall.childForFieldName('block');
196
- if (collectionBlock) {
197
- this.parseMemberCollectionRoutes(collectionBlock, resource, namespaces, 'collection');
198
- }
199
- }
200
- }
201
- }
202
- }
203
- parseMemberCollectionRoutes(block, resource, namespaces, type) {
204
- const calls = findNodes(block, 'call');
205
- for (const call of calls) {
206
- const methodNode = call.childForFieldName('method');
207
- if (!methodNode)
208
- continue;
209
- const method = methodNode.text;
210
- if (!['get', 'post', 'put', 'patch', 'delete'].includes(method))
211
- continue;
212
- const args = getCallArguments(call);
213
- if (args.length === 0)
214
- continue;
215
- const actionName = args[0].text.replace(/^:/, '');
216
- const basePath = type === 'member'
217
- ? `/${resource.name}/:id/${actionName}`
218
- : `/${resource.name}/${actionName}`;
219
- const route = {
220
- method: method.toUpperCase(),
221
- path: this.buildPath(namespaces, basePath),
222
- controller: resource.controller,
223
- action: actionName,
224
- namespace: namespaces.join('/') || undefined,
225
- line: call.startPosition.row + 1,
226
- };
227
- if (type === 'member') {
228
- resource.memberRoutes.push(route);
229
- }
230
- else {
231
- resource.collectionRoutes.push(route);
232
- }
233
- this.routes.push(route);
234
- }
235
- }
236
- async parseNamespace(call, currentNamespaces, _currentFile) {
237
- const args = getCallArguments(call);
238
- if (args.length === 0)
239
- return;
240
- const nsName = args[0].text.replace(/^:/, '');
241
- this.namespaces.push(nsName);
242
- const newNamespaces = [...currentNamespaces, nsName];
243
- // Parse the namespace block
244
- const block = call.childForFieldName('block');
245
- if (block) {
246
- // Look for draw calls or nested route definitions
247
- const nestedCalls = findNodes(block, 'call');
248
- for (const nestedCall of nestedCalls) {
249
- const methodNode = nestedCall.childForFieldName('method');
250
- if (!methodNode)
251
- continue;
252
- const methodName = methodNode.text;
253
- const line = nestedCall.startPosition.row + 1;
254
- switch (methodName) {
255
- case 'get':
256
- case 'post':
257
- case 'put':
258
- case 'patch':
259
- case 'delete':
260
- case 'match':
261
- this.parseHttpRoute(nestedCall, methodName, newNamespaces, line);
262
- break;
263
- case 'resources':
264
- case 'resource':
265
- await this.parseResources(nestedCall, newNamespaces, line, methodName === 'resource');
266
- break;
267
- case 'draw':
268
- await this.parseDraw(nestedCall, newNamespaces);
269
- break;
270
- }
271
- }
272
- }
273
- }
274
- parseMount(call, line) {
275
- const args = getCallArguments(call);
276
- if (args.length === 0)
277
- return;
278
- // First arg is the engine
279
- const engineArg = args[0];
280
- const engine = engineArg.text;
281
- // Find mount path from 'at:' option or '=>' syntax
282
- let mountPath = '/';
283
- for (const arg of args) {
284
- if (arg.type === 'hash' || arg.type === 'pair') {
285
- const pairs = arg.type === 'hash' ? getChildrenByType(arg, 'pair') : [arg];
286
- for (const pair of pairs) {
287
- const key = pair.child(0)?.text?.replace(/^:/, '');
288
- const value = pair.child(2);
289
- if (key === 'at' && value) {
290
- mountPath = this.extractStringValue(value) || mountPath;
291
- }
292
- }
293
- }
294
- else if (arg.type === 'string') {
295
- // Could be the path in "mount Engine => '/path'" syntax
296
- const strValue = this.extractStringValue(arg);
297
- if (strValue && strValue.startsWith('/')) {
298
- mountPath = strValue;
299
- }
300
- }
301
- }
302
- this.mountedEngines.push({
303
- engine,
304
- mountPath,
305
- line,
306
- });
307
- }
308
- async parseDraw(call, namespaces) {
309
- const args = getCallArguments(call);
310
- if (args.length === 0)
311
- return;
312
- const drawName = args[0].text.replace(/^:/, '');
313
- const drawFile = path.join(this.routesDir, `${drawName}.rb`);
314
- if (fs.existsSync(drawFile)) {
315
- this.drawnFiles.push(drawFile);
316
- try {
317
- await this.parseRoutesFile(drawFile, namespaces);
318
- }
319
- catch (error) {
320
- this.errors.push(`Error parsing drawn file ${drawFile}: ${error}`);
321
- }
322
- }
323
- }
324
- parseDeviseFor(call, namespaces, line) {
325
- const args = getCallArguments(call);
326
- if (args.length === 0)
327
- return;
328
- const resource = args[0].text.replace(/^:/, '');
329
- // Generate standard Devise routes
330
- const deviseRoutes = [
331
- { method: 'GET', path: `/${resource}/sign_in`, action: 'new', controller: 'devise/sessions' },
332
- {
333
- method: 'POST',
334
- path: `/${resource}/sign_in`,
335
- action: 'create',
336
- controller: 'devise/sessions',
337
- },
338
- {
339
- method: 'DELETE',
340
- path: `/${resource}/sign_out`,
341
- action: 'destroy',
342
- controller: 'devise/sessions',
343
- },
344
- {
345
- method: 'GET',
346
- path: `/${resource}/password/new`,
347
- action: 'new',
348
- controller: 'devise/passwords',
349
- },
350
- {
351
- method: 'POST',
352
- path: `/${resource}/password`,
353
- action: 'create',
354
- controller: 'devise/passwords',
355
- },
356
- {
357
- method: 'GET',
358
- path: `/${resource}/sign_up`,
359
- action: 'new',
360
- controller: 'devise/registrations',
361
- },
362
- {
363
- method: 'POST',
364
- path: `/${resource}`,
365
- action: 'create',
366
- controller: 'devise/registrations',
367
- },
368
- ];
369
- for (const dr of deviseRoutes) {
370
- this.routes.push({
371
- method: dr.method,
372
- path: this.buildPath(namespaces, dr.path),
373
- controller: dr.controller,
374
- action: dr.action,
375
- namespace: namespaces.join('/') || undefined,
376
- line,
377
- authenticated: false,
378
- });
379
- }
380
- }
381
- parseRoot(call, namespaces, line) {
382
- const args = getCallArguments(call);
383
- let controller = '';
384
- let action = 'index';
385
- for (const arg of args) {
386
- if (arg.type === 'string') {
387
- const value = this.extractStringValue(arg);
388
- if (value && value.includes('#')) {
389
- [controller, action] = value.split('#');
390
- }
391
- }
392
- else if (arg.type === 'hash' || arg.type === 'pair') {
393
- const pairs = arg.type === 'hash' ? getChildrenByType(arg, 'pair') : [arg];
394
- for (const pair of pairs) {
395
- const key = pair.child(0)?.text?.replace(/^:/, '');
396
- const value = pair.child(2);
397
- if (key === 'to' && value) {
398
- const toValue = this.extractStringValue(value);
399
- if (toValue && toValue.includes('#')) {
400
- [controller, action] = toValue.split('#');
401
- }
402
- }
403
- }
404
- }
405
- }
406
- if (controller) {
407
- this.routes.push({
408
- method: 'GET',
409
- path: this.buildPath(namespaces, '/'),
410
- controller,
411
- action,
412
- namespace: namespaces.join('/') || undefined,
413
- line,
414
- });
415
- }
416
- }
417
- generateResourceRoutes(resource, namespaces, singular) {
418
- const basePath = this.buildPath(namespaces, `/${resource.name}`);
419
- const allActions = singular
420
- ? ['show', 'new', 'create', 'edit', 'update', 'destroy']
421
- : ['index', 'show', 'new', 'create', 'edit', 'update', 'destroy'];
422
- const actions = resource.only ||
423
- (resource.except
424
- ? allActions.filter((a) => !resource.except.includes(a))
425
- : allActions);
426
- const restfulRoutes = [];
427
- if (!singular) {
428
- if (actions.includes('index')) {
429
- restfulRoutes.push({ method: 'GET', path: basePath, action: 'index' });
430
- }
431
- }
432
- if (actions.includes('new')) {
433
- restfulRoutes.push({ method: 'GET', path: `${basePath}/new`, action: 'new' });
434
- }
435
- if (actions.includes('create')) {
436
- restfulRoutes.push({ method: 'POST', path: basePath, action: 'create' });
437
- }
438
- const showPath = singular ? basePath : `${basePath}/:id`;
439
- if (actions.includes('show')) {
440
- restfulRoutes.push({ method: 'GET', path: showPath, action: 'show' });
441
- }
442
- if (actions.includes('edit')) {
443
- restfulRoutes.push({ method: 'GET', path: `${showPath}/edit`, action: 'edit' });
444
- }
445
- if (actions.includes('update')) {
446
- restfulRoutes.push({ method: 'PUT', path: showPath, action: 'update' });
447
- restfulRoutes.push({ method: 'PATCH', path: showPath, action: 'update' });
448
- }
449
- if (actions.includes('destroy')) {
450
- restfulRoutes.push({ method: 'DELETE', path: showPath, action: 'destroy' });
451
- }
452
- for (const route of restfulRoutes) {
453
- this.routes.push({
454
- method: route.method,
455
- path: route.path,
456
- controller: resource.controller,
457
- action: route.action,
458
- namespace: namespaces.join('/') || undefined,
459
- line: resource.line,
460
- });
461
- }
462
- }
463
- buildPath(namespaces, routePath) {
464
- if (routePath.startsWith('/')) {
465
- return routePath;
466
- }
467
- const nsPath = namespaces.length > 0 ? `/${namespaces.join('/')}` : '';
468
- return `${nsPath}/${routePath}`;
469
- }
470
- extractStringValue(node) {
471
- if (node.type === 'string') {
472
- // String has quotes, extract content
473
- const content = getChildByType(node, 'string_content');
474
- return content ? content.text : node.text.replace(/^["']|["']$/g, '');
475
- }
476
- if (node.type === 'string_content') {
477
- return node.text;
478
- }
479
- if (node.type === 'simple_symbol' || node.type === 'symbol') {
480
- return node.text.replace(/^:/, '');
481
- }
482
- return node.text.replace(/^["']|["']$/g, '');
483
- }
484
- extractArrayValues(node) {
485
- const values = [];
486
- if (node.type === 'array') {
487
- for (let i = 0; i < node.childCount; i++) {
488
- const child = node.child(i);
489
- if (child && child.type !== '[' && child.type !== ']' && child.type !== ',') {
490
- const value = this.extractStringValue(child);
491
- if (value)
492
- values.push(value);
493
- }
494
- }
495
- }
496
- else {
497
- // Single value
498
- const value = this.extractStringValue(node);
499
- if (value)
500
- values.push(value);
501
- }
502
- return values;
503
- }
504
- }
505
- // Standalone execution for testing
506
- async function main() {
507
- const targetPath = process.argv[2] || process.cwd();
508
- console.log(`Analyzing routes in: ${targetPath}`);
509
- const analyzer = new RailsRoutesAnalyzer(targetPath);
510
- const result = await analyzer.analyze();
511
- console.log('\n=== Rails Routes Analysis ===\n');
512
- console.log(`Total routes: ${result.routes.length}`);
513
- console.log(`Namespaces: ${result.namespaces.join(', ') || '(none)'}`);
514
- console.log(`Resources: ${result.resources.length}`);
515
- console.log(`Mounted engines: ${result.mountedEngines.length}`);
516
- console.log(`External route files: ${result.drawnFiles.length}`);
517
- if (result.errors.length > 0) {
518
- console.log(`\n--- Errors ---`);
519
- for (const error of result.errors) {
520
- console.log(` ❌ ${error}`);
521
- }
522
- }
523
- console.log('\n--- Sample Routes (first 30) ---');
524
- for (const route of result.routes.slice(0, 30)) {
525
- console.log(` ${route.method.padEnd(7)} ${route.path.padEnd(50)} => ${route.controller}#${route.action}`);
526
- }
527
- console.log('\n--- Mounted Engines ---');
528
- for (const engine of result.mountedEngines) {
529
- console.log(` ${engine.engine} => ${engine.mountPath}`);
530
- }
531
- console.log('\n--- External Route Files ---');
532
- for (const file of result.drawnFiles) {
533
- console.log(` ${path.basename(file)}`);
534
- }
535
- }
536
- // Run if executed directly
537
- const isMainModule = import.meta.url === `file://${process.argv[1]}`;
538
- if (isMainModule) {
539
- main().catch(console.error);
540
- }
@@ -1,49 +0,0 @@
1
- export interface ReactComponentRef {
2
- name: string;
3
- propsVar?: string;
4
- ssr?: boolean;
5
- line?: number;
6
- }
7
- export interface RailsViewInfo {
8
- name: string;
9
- path: string;
10
- controller: string;
11
- action: string;
12
- format: string;
13
- template: 'haml' | 'erb' | 'yml' | 'other';
14
- routePath?: string;
15
- partials: string[];
16
- helpers: string[];
17
- instanceVars: string[];
18
- reactComponents: ReactComponentRef[];
19
- line?: number;
20
- }
21
- export interface RailsPageInfo {
22
- route: string;
23
- method: string;
24
- controller: string;
25
- action: string;
26
- view?: RailsViewInfo;
27
- apis: RailsApiCall[];
28
- services: string[];
29
- grpcCalls: string[];
30
- modelAccess: string[];
31
- }
32
- export interface RailsApiCall {
33
- type: 'grpc' | 'service' | 'http' | 'internal';
34
- name: string;
35
- method?: string;
36
- source: string;
37
- line?: number;
38
- }
39
- export interface RailsViewAnalysisResult {
40
- views: RailsViewInfo[];
41
- pages: RailsPageInfo[];
42
- summary: {
43
- totalViews: number;
44
- totalPages: number;
45
- byController: Record<string, number>;
46
- byTemplate: Record<string, number>;
47
- };
48
- }
49
- export declare function analyzeRailsViews(rootPath: string): Promise<RailsViewAnalysisResult>;