@wtdlee/repomap 0.2.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 (69) 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 -290
  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 +5 -3
  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
@@ -1,262 +0,0 @@
1
- /**
2
- * Rails gRPC Service Analyzer using tree-sitter
3
- * tree-sitterを使用してgRPCサービスを解析する
4
- */
5
- import * as fs from 'fs';
6
- import * as path from 'path';
7
- import { glob } from 'glob';
8
- import { parseRubyFile, findNodes, getClassName, getSuperclass, getMethodName, getMethodParameters, } from './ruby-parser.js';
9
- export class RailsGrpcAnalyzer {
10
- rootPath;
11
- grpcDir;
12
- services = [];
13
- errors = [];
14
- constructor(rootPath) {
15
- this.rootPath = rootPath;
16
- this.grpcDir = path.join(rootPath, 'app', 'grpc_services');
17
- }
18
- async analyze() {
19
- if (!fs.existsSync(this.grpcDir)) {
20
- return {
21
- services: [],
22
- totalRpcs: 0,
23
- namespaces: [],
24
- errors: [`gRPC services directory not found at ${this.grpcDir}`],
25
- };
26
- }
27
- const serviceFiles = await glob('**/*_grpc_service.rb', {
28
- cwd: this.grpcDir,
29
- });
30
- for (const file of serviceFiles) {
31
- const fullPath = path.join(this.grpcDir, file);
32
- try {
33
- const service = await this.parseServiceFile(fullPath, file);
34
- if (service) {
35
- this.services.push(service);
36
- }
37
- }
38
- catch (error) {
39
- this.errors.push(`Error parsing ${file}: ${error}`);
40
- }
41
- }
42
- const namespaces = [
43
- ...new Set(this.services.filter((s) => s.namespace).map((s) => s.namespace)),
44
- ];
45
- const totalRpcs = this.services.reduce((sum, s) => sum + s.rpcs.length, 0);
46
- return {
47
- services: this.services,
48
- totalRpcs,
49
- namespaces,
50
- errors: this.errors,
51
- };
52
- }
53
- async parseServiceFile(filePath, relativePath) {
54
- const tree = await parseRubyFile(filePath);
55
- const rootNode = tree.rootNode;
56
- // Extract namespace from path
57
- const pathParts = relativePath.replace(/_grpc_service\.rb$/, '').split('/');
58
- const namespace = pathParts.length > 1 ? pathParts.slice(0, -1).join('/') : undefined;
59
- const serviceName = pathParts[pathParts.length - 1];
60
- // Find class definition
61
- const classNodes = findNodes(rootNode, 'class');
62
- if (classNodes.length === 0)
63
- return null;
64
- const classNode = classNodes[0];
65
- const className = getClassName(classNode);
66
- const parentClass = getSuperclass(classNode);
67
- if (!className)
68
- return null;
69
- const service = {
70
- name: serviceName,
71
- filePath: relativePath,
72
- className,
73
- parentClass: parentClass || 'Unknown',
74
- namespace,
75
- rpcs: [],
76
- policies: [],
77
- serializers: [],
78
- concerns: [],
79
- line: classNode.startPosition.row + 1,
80
- };
81
- // Extract proto service from parent class
82
- if (parentClass) {
83
- // e.g., Visit::ConversationPb::ConversationService::Service
84
- const protoMatch = parentClass.match(/(\w+)::Service$/);
85
- if (protoMatch) {
86
- service.protoService = parentClass.replace('::Service', '');
87
- }
88
- }
89
- // Find include statements (concerns)
90
- const calls = findNodes(classNode, 'call');
91
- for (const call of calls) {
92
- const methodNode = call.childForFieldName('method');
93
- if (methodNode?.text === 'include') {
94
- const args = this.getCallArguments(call);
95
- for (const arg of args) {
96
- if (arg.type === 'constant' || arg.type === 'scope_resolution') {
97
- service.concerns.push(arg.text);
98
- }
99
- }
100
- }
101
- }
102
- // Find method definitions (RPC methods)
103
- const _methods = findNodes(classNode, 'method');
104
- let currentVisibility = 'public';
105
- const bodyStatement = classNode.childForFieldName('body');
106
- if (bodyStatement) {
107
- for (let i = 0; i < bodyStatement.childCount; i++) {
108
- const child = bodyStatement.child(i);
109
- if (!child)
110
- continue;
111
- if (child.type === 'identifier') {
112
- const text = child.text;
113
- if (text === 'private')
114
- currentVisibility = 'private';
115
- else if (text === 'protected')
116
- currentVisibility = 'protected';
117
- else if (text === 'public')
118
- currentVisibility = 'public';
119
- }
120
- else if (child.type === 'method' && currentVisibility === 'public') {
121
- const rpc = this.parseRpcMethod(child);
122
- if (rpc) {
123
- // Extract policies and serializers from method body
124
- const methodCalls = findNodes(child, 'call');
125
- for (const mc of methodCalls) {
126
- const methodName = mc.childForFieldName('method')?.text;
127
- const receiver = mc.childForFieldName('receiver')?.text;
128
- // Policy patterns
129
- if (methodName === 'authorize!' || methodName === 'new') {
130
- if (receiver?.includes('Policy')) {
131
- if (!service.policies.includes(receiver)) {
132
- service.policies.push(receiver);
133
- }
134
- rpc.policyMethod = 'authorize!';
135
- }
136
- }
137
- // Serializer patterns
138
- if (receiver?.includes('Serializer') && methodName === 'new') {
139
- if (!service.serializers.includes(receiver)) {
140
- service.serializers.push(receiver);
141
- }
142
- }
143
- }
144
- service.rpcs.push(rpc);
145
- }
146
- }
147
- }
148
- }
149
- return service;
150
- }
151
- parseRpcMethod(methodNode) {
152
- const name = getMethodName(methodNode);
153
- if (!name)
154
- return null;
155
- // Skip common non-RPC methods
156
- const skipMethods = ['initialize', 'to_s', 'inspect', 'call', 'perform', 'execute'];
157
- if (skipMethods.includes(name))
158
- return null;
159
- const _params = getMethodParameters(methodNode);
160
- const methodBody = methodNode.text;
161
- const rpc = {
162
- name,
163
- line: methodNode.startPosition.row + 1,
164
- streaming: 'none',
165
- modelsUsed: [],
166
- servicesUsed: [],
167
- };
168
- // Try to extract request/response types from comments or code
169
- // @param [Visit::ConversationPb::GetConversationRequest] req
170
- const requestMatch = methodBody.match(/@param\s+\[([^\]]+)\]\s+req/);
171
- if (requestMatch) {
172
- rpc.requestType = requestMatch[1];
173
- }
174
- // @return [Visit::ConversationPb::Conversation]
175
- const responseMatch = methodBody.match(/@return\s+\[([^\]]+)\]/);
176
- if (responseMatch) {
177
- rpc.responseType = responseMatch[1];
178
- }
179
- // Extract models used (ActiveRecord patterns)
180
- const modelMatches = methodBody.matchAll(/\b([A-Z][a-zA-Z]+)\.(find|find_by|where|all|first|last|create|joins|includes)\b/g);
181
- for (const match of modelMatches) {
182
- const modelName = match[1];
183
- if (!['Rails', 'ActiveRecord', 'GRPC', 'Visit', 'Google'].includes(modelName) &&
184
- !rpc.modelsUsed.includes(modelName)) {
185
- rpc.modelsUsed.push(modelName);
186
- }
187
- }
188
- // Extract services used
189
- const serviceMatches = methodBody.matchAll(/\b(\w+Service)\.(call|new|perform)\b/g);
190
- for (const match of serviceMatches) {
191
- const serviceName = match[1];
192
- if (!rpc.servicesUsed.includes(serviceName)) {
193
- rpc.servicesUsed.push(serviceName);
194
- }
195
- }
196
- return rpc;
197
- }
198
- getCallArguments(call) {
199
- const args = call.childForFieldName('arguments');
200
- if (!args) {
201
- const results = [];
202
- for (let i = 0; i < call.childCount; i++) {
203
- const child = call.child(i);
204
- if (child && !['identifier', '(', ')', ',', 'call'].includes(child.type)) {
205
- if (child !== call.childForFieldName('method') &&
206
- child !== call.childForFieldName('receiver')) {
207
- results.push(child);
208
- }
209
- }
210
- }
211
- return results;
212
- }
213
- const results = [];
214
- for (let i = 0; i < args.childCount; i++) {
215
- const child = args.child(i);
216
- if (child && child.type !== '(' && child.type !== ')' && child.type !== ',') {
217
- results.push(child);
218
- }
219
- }
220
- return results;
221
- }
222
- }
223
- // Standalone execution for testing
224
- async function main() {
225
- const targetPath = process.argv[2] || process.cwd();
226
- console.log(`Analyzing gRPC services in: ${targetPath}`);
227
- const analyzer = new RailsGrpcAnalyzer(targetPath);
228
- const result = await analyzer.analyze();
229
- console.log('\n=== Rails gRPC Services Analysis ===\n');
230
- console.log(`Total services: ${result.services.length}`);
231
- console.log(`Total RPCs: ${result.totalRpcs}`);
232
- console.log(`Namespaces: ${result.namespaces.join(', ') || '(none)'}`);
233
- if (result.errors.length > 0) {
234
- console.log(`\n--- Errors (${result.errors.length}) ---`);
235
- for (const error of result.errors.slice(0, 5)) {
236
- console.log(` ❌ ${error}`);
237
- }
238
- }
239
- console.log('\n--- Sample Services (first 15) ---');
240
- for (const service of result.services.slice(0, 15)) {
241
- console.log(`\n 📡 ${service.className} (${service.filePath})`);
242
- console.log(` Proto: ${service.protoService || 'unknown'}`);
243
- console.log(` RPCs (${service.rpcs.length}): ${service.rpcs.map((r) => r.name).join(', ')}`);
244
- if (service.policies.length > 0) {
245
- console.log(` Policies: ${service.policies.join(', ')}`);
246
- }
247
- if (service.serializers.length > 0) {
248
- console.log(` Serializers: ${service.serializers.join(', ')}`);
249
- }
250
- }
251
- // RPC summary
252
- const allRpcs = result.services.flatMap((s) => s.rpcs);
253
- const rpcsWithModels = allRpcs.filter((r) => r.modelsUsed.length > 0);
254
- console.log('\n--- RPC Summary ---');
255
- console.log(` Total RPCs: ${allRpcs.length}`);
256
- console.log(` RPCs using models: ${rpcsWithModels.length}`);
257
- }
258
- // Run if executed directly
259
- const isMainModule = import.meta.url === `file://${process.argv[1]}`;
260
- if (isMainModule) {
261
- main().catch(console.error);
262
- }
@@ -1,88 +0,0 @@
1
- /**
2
- * Rails Model Analyzer using tree-sitter
3
- * tree-sitterを使用してモデルファイルを解析する
4
- */
5
- export interface ModelInfo {
6
- name: string;
7
- filePath: string;
8
- className: string;
9
- parentClass: string;
10
- tableName?: string;
11
- associations: AssociationInfo[];
12
- validations: ValidationInfo[];
13
- callbacks: CallbackInfo[];
14
- scopes: ScopeInfo[];
15
- concerns: string[];
16
- enums: EnumInfo[];
17
- attributes: AttributeInfo[];
18
- classMethodsCount: number;
19
- instanceMethodsCount: number;
20
- line: number;
21
- }
22
- export interface AssociationInfo {
23
- type: 'belongs_to' | 'has_one' | 'has_many' | 'has_and_belongs_to_many';
24
- name: string;
25
- className?: string;
26
- foreignKey?: string;
27
- through?: string;
28
- polymorphic?: boolean;
29
- dependent?: string;
30
- optional?: boolean;
31
- line: number;
32
- }
33
- export interface ValidationInfo {
34
- type: string;
35
- attributes: string[];
36
- options?: Record<string, string>;
37
- line: number;
38
- }
39
- export interface CallbackInfo {
40
- type: string;
41
- method: string;
42
- conditions?: string;
43
- line: number;
44
- }
45
- export interface ScopeInfo {
46
- name: string;
47
- lambda: boolean;
48
- line: number;
49
- }
50
- export interface EnumInfo {
51
- name: string;
52
- values: string[];
53
- line: number;
54
- }
55
- export interface AttributeInfo {
56
- name: string;
57
- type?: string;
58
- default?: string;
59
- line: number;
60
- }
61
- export interface RailsModelsResult {
62
- models: ModelInfo[];
63
- totalAssociations: number;
64
- totalValidations: number;
65
- concerns: string[];
66
- namespaces: string[];
67
- errors: string[];
68
- }
69
- export declare class RailsModelAnalyzer {
70
- private rootPath;
71
- private modelsDir;
72
- private models;
73
- private errors;
74
- constructor(rootPath: string);
75
- analyze(): Promise<RailsModelsResult>;
76
- private parseModelFile;
77
- private isActiveRecordModel;
78
- private parseTableName;
79
- private parseAssociation;
80
- private parseValidation;
81
- private isCallback;
82
- private parseCallback;
83
- private parseScope;
84
- private parseInclude;
85
- private parseEnum;
86
- private parseAttribute;
87
- private getCallArguments;
88
- }