@g1cloud/api-gen 1.0.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 (86) hide show
  1. package/.claude/settings.local.json +22 -0
  2. package/CLAUDE.md +63 -0
  3. package/README.md +379 -0
  4. package/dist/analyzer/controllerAnalyzer.d.ts +20 -0
  5. package/dist/analyzer/controllerAnalyzer.d.ts.map +1 -0
  6. package/dist/analyzer/controllerAnalyzer.js +101 -0
  7. package/dist/analyzer/controllerAnalyzer.js.map +1 -0
  8. package/dist/analyzer/parameterAnalyzer.d.ts +19 -0
  9. package/dist/analyzer/parameterAnalyzer.d.ts.map +1 -0
  10. package/dist/analyzer/parameterAnalyzer.js +207 -0
  11. package/dist/analyzer/parameterAnalyzer.js.map +1 -0
  12. package/dist/analyzer/responseAnalyzer.d.ts +12 -0
  13. package/dist/analyzer/responseAnalyzer.d.ts.map +1 -0
  14. package/dist/analyzer/responseAnalyzer.js +116 -0
  15. package/dist/analyzer/responseAnalyzer.js.map +1 -0
  16. package/dist/analyzer/schemaGenerator.d.ts +6 -0
  17. package/dist/analyzer/schemaGenerator.d.ts.map +1 -0
  18. package/dist/analyzer/schemaGenerator.js +347 -0
  19. package/dist/analyzer/schemaGenerator.js.map +1 -0
  20. package/dist/analyzer/securityAnalyzer.d.ts +6 -0
  21. package/dist/analyzer/securityAnalyzer.d.ts.map +1 -0
  22. package/dist/analyzer/securityAnalyzer.js +177 -0
  23. package/dist/analyzer/securityAnalyzer.js.map +1 -0
  24. package/dist/generator/openapiGenerator.d.ts +14 -0
  25. package/dist/generator/openapiGenerator.d.ts.map +1 -0
  26. package/dist/generator/openapiGenerator.js +340 -0
  27. package/dist/generator/openapiGenerator.js.map +1 -0
  28. package/dist/index.d.ts +3 -0
  29. package/dist/index.d.ts.map +1 -0
  30. package/dist/index.js +218 -0
  31. package/dist/index.js.map +1 -0
  32. package/dist/lib.d.ts +61 -0
  33. package/dist/lib.d.ts.map +1 -0
  34. package/dist/lib.js +199 -0
  35. package/dist/lib.js.map +1 -0
  36. package/dist/mcp-server.d.ts +9 -0
  37. package/dist/mcp-server.d.ts.map +1 -0
  38. package/dist/mcp-server.js +257 -0
  39. package/dist/mcp-server.js.map +1 -0
  40. package/dist/mcp-server.mjs +45586 -0
  41. package/dist/parser/astAnalyzer.d.ts +87 -0
  42. package/dist/parser/astAnalyzer.d.ts.map +1 -0
  43. package/dist/parser/astAnalyzer.js +321 -0
  44. package/dist/parser/astAnalyzer.js.map +1 -0
  45. package/dist/parser/javaParser.d.ts +10 -0
  46. package/dist/parser/javaParser.d.ts.map +1 -0
  47. package/dist/parser/javaParser.js +805 -0
  48. package/dist/parser/javaParser.js.map +1 -0
  49. package/dist/types/index.d.ts +217 -0
  50. package/dist/types/index.d.ts.map +1 -0
  51. package/dist/types/index.js +3 -0
  52. package/dist/types/index.js.map +1 -0
  53. package/examples/CreateUserRequest.java +80 -0
  54. package/examples/DepartmentDTO.java +45 -0
  55. package/examples/Filter.java +39 -0
  56. package/examples/PaginatedList.java +71 -0
  57. package/examples/ProductController.java +136 -0
  58. package/examples/ProductDTO.java +129 -0
  59. package/examples/RoleDTO.java +47 -0
  60. package/examples/SearchParam.java +55 -0
  61. package/examples/Sort.java +70 -0
  62. package/examples/UpdateUserRequest.java +74 -0
  63. package/examples/UserController.java +98 -0
  64. package/examples/UserDTO.java +119 -0
  65. package/package.json +51 -0
  66. package/prompt/01_Initial.md +358 -0
  67. package/prompt/02_/354/266/224/352/260/200.md +31 -0
  68. package/src/analyzer/controllerAnalyzer.ts +125 -0
  69. package/src/analyzer/parameterAnalyzer.ts +259 -0
  70. package/src/analyzer/responseAnalyzer.ts +142 -0
  71. package/src/analyzer/schemaGenerator.ts +412 -0
  72. package/src/analyzer/securityAnalyzer.ts +200 -0
  73. package/src/generator/openapiGenerator.ts +378 -0
  74. package/src/index.ts +212 -0
  75. package/src/lib.ts +240 -0
  76. package/src/mcp-server.ts +310 -0
  77. package/src/parser/astAnalyzer.ts +373 -0
  78. package/src/parser/javaParser.ts +901 -0
  79. package/src/types/index.ts +238 -0
  80. package/test-boolean.yaml +607 -0
  81. package/test-filter.yaml +576 -0
  82. package/test-inner.ts +59 -0
  83. package/test-output.yaml +650 -0
  84. package/test-paginated.yaml +585 -0
  85. package/tsconfig.json +20 -0
  86. package/tsup.config.ts +30 -0
@@ -0,0 +1,22 @@
1
+ {
2
+ "permissions": {
3
+ "allow": [
4
+ "Bash(pnpm build:*)",
5
+ "Bash(pnpm dev:*)",
6
+ "Bash(npx ts-node src/index.ts --source ./examples --out-dir ./test-output)",
7
+ "Bash(chmod:*)",
8
+ "Bash(node dist/index.js:*)",
9
+ "Bash(grep:*)",
10
+ "Bash(node -e:*)",
11
+ "Bash(pnpm add:*)",
12
+ "Bash(pnpm approve-builds:*)",
13
+ "Bash(pnpm bundle:*)",
14
+ "Bash(cat:*)",
15
+ "Bash(./dist/index.js:*)",
16
+ "Bash(node /Users/kimos/git/g1cloud-tool/api-gen/dist/index.js:*)",
17
+ "Bash(pnpm install:*)",
18
+ "Bash(timeout 3 node:*)",
19
+ "Bash(npm whoami:*)"
20
+ ]
21
+ }
22
+ }
package/CLAUDE.md ADDED
@@ -0,0 +1,63 @@
1
+ # CLAUDE.md
2
+
3
+ This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
4
+
5
+ ## Project Overview
6
+
7
+ This is a CLI tool that generates OpenAPI v3 YAML specifications from Spring Boot Java source code. It parses Java files, detects REST controllers, extracts endpoint information, and produces a valid OpenAPI spec.
8
+
9
+ ## Commands
10
+
11
+ ```bash
12
+ # Install dependencies
13
+ pnpm install
14
+
15
+ # Build (compiles TypeScript to dist/)
16
+ pnpm build
17
+
18
+ # Run in development mode
19
+ pnpm dev -- --source ./examples --output ./test-output.yaml
20
+
21
+ # Run the test command (uses example files)
22
+ pnpm test
23
+ ```
24
+
25
+ ## Architecture
26
+
27
+ The tool follows a pipeline architecture with four main stages:
28
+
29
+ 1. **Parsing** (`src/parser/`) - Uses `java-parser` library to parse Java source files into AST
30
+ - `javaParser.ts`: Recursively finds and parses `.java` files, extracting class metadata
31
+ - `astAnalyzer.ts`: Utility functions for querying the parsed AST
32
+
33
+ 2. **Analysis** (`src/analyzer/`) - Extracts API-relevant information from parsed classes
34
+ - `controllerAnalyzer.ts`: Orchestrates analysis, identifies `@RestController`/`@Controller` classes
35
+ - `parameterAnalyzer.ts`: Extracts `@RequestParam`, `@PathVariable`, `@RequestHeader`, `@RequestBody`
36
+ - `responseAnalyzer.ts`: Determines return types and generates response schemas
37
+ - `securityAnalyzer.ts`: Parses `@PreAuthorize`/`@PostAuthorize` SpEL expressions for roles
38
+ - `schemaGenerator.ts`: Recursively generates DTO schemas with validation annotations
39
+
40
+ 3. **Generation** (`src/generator/openapiGenerator.ts`) - Converts analyzed data to OpenAPI spec and writes YAML
41
+
42
+ 4. **Entry Point** (`src/index.ts`) - CLI using Commander, orchestrates the full pipeline
43
+
44
+ ### Key Data Flow
45
+
46
+ ```
47
+ Java Files → JavaFileParser → JavaClass objects → ControllerAnalyzer → EndpointInfo objects → OpenAPIGenerator → YAML
48
+ ```
49
+
50
+ ### ProcessingContext
51
+
52
+ The `ProcessingContext` type is passed through the pipeline and contains:
53
+ - `javaClasses`: Map of parsed Java classes by name
54
+ - `controllers`: Analyzed controller information
55
+ - `dtoSchemas`: Generated schemas for DTOs
56
+ - `referencedTypes`: Set of types that need schema generation
57
+
58
+ ## Special Type Handling
59
+
60
+ The tool has built-in handling for:
61
+ - **SearchParam**: Auto-adds pagination query params (offset, limit, filter, sort)
62
+ - **PaginatedList<T>**: Adds pagination headers (X-Total-Count, X-Offset, X-Limit) and generates wrapper schema
63
+ - **ResponseEntity<T>**: Unwraps the generic type for response schema generation
package/README.md ADDED
@@ -0,0 +1,379 @@
1
+ # @g1cloud/api-gen
2
+
3
+ Spring Boot Java 소스 코드에서 OpenAPI v3 YAML 스펙을 생성하는 CLI 도구입니다.
4
+
5
+ ## 기능
6
+
7
+ - **Java 소스 파싱**: `java-parser`를 사용하여 Java 파일에서 클래스 및 메서드 정보 추출
8
+ - **REST Controller 분석**: `@RestController`, `@Controller` 및 HTTP 매핑 어노테이션 감지
9
+ - **파라미터 추출**: `@RequestParam`, `@PathVariable`, `@RequestHeader`, `@RequestBody` 지원
10
+ - **응답 분석**: 반환 타입 추출 및 응답 스키마 생성
11
+ - **보안 어노테이션 파싱**: `@PreAuthorize`, `@PostAuthorize`, `@Secured` 어노테이션 분석
12
+ - **SpEL 표현식 파싱**: Spring Security 표현식에서 역할(role) 및 권한(authority) 추출
13
+ - **DTO 스키마 생성**: 요청/응답 DTO에 대한 스키마 재귀적 생성
14
+ - **특수 타입 처리**:
15
+ - `SearchParam`: 페이지네이션 파라미터 자동 추가 (offset, limit, filter, sort)
16
+ - `PaginatedList<T>`: 페이지네이션 헤더 추가 (X-Total-Count, X-Offset, X-Limit)
17
+
18
+ ## 설치
19
+
20
+ ```bash
21
+ # 의존성 설치
22
+ pnpm install
23
+
24
+ # 프로젝트 빌드
25
+ pnpm build
26
+
27
+ # 또는 ts-node로 직접 실행
28
+ pnpm dev -- --source ./examples --output ./test-output.yaml
29
+ ```
30
+
31
+ ## 사용법
32
+
33
+ ```bash
34
+ # 기본 사용법 - 단일 통합 YAML 파일 생성
35
+ npx spring-to-openapi --source ./src/main/java --output ./openapi.yaml
36
+
37
+ # 컨트롤러별 모드 - 각 컨트롤러마다 별도 YAML 파일 생성
38
+ npx spring-to-openapi --source ./src/main/java --out-dir ./api-docs
39
+
40
+ # 모든 옵션 사용
41
+ npx spring-to-openapi \
42
+ --source ./src/main/java \
43
+ --output ./openapi.yaml \
44
+ --title "My API" \
45
+ --api-version "1.0.0" \
46
+ --base-path "/api"
47
+ ```
48
+
49
+ ### CLI 옵션
50
+
51
+ | 옵션 | 단축 | 설명 | 기본값 |
52
+ |--------|-------|-------------|---------|
53
+ | `--source` | `-s` | Java 소스 코드 디렉토리 경로 | (필수) |
54
+ | `--output` | `-o` | 출력 YAML 파일 경로 (단일 통합 파일) | `openapi.yaml` |
55
+ | `--out-dir` | `-d` | 출력 디렉토리 경로 (컨트롤러별 YAML 생성) | (없음) |
56
+ | `--title` | `-t` | API 제목 | `API Documentation` |
57
+ | `--api-version` | | API 버전 | `1.0.0` |
58
+ | `--base-path` | `-b` | API 기본 경로 | (없음) |
59
+
60
+ > **참고**: `--output`과 `--out-dir`은 상호 배타적입니다. 단일 통합 파일은 `--output`을, 컨트롤러별 YAML 파일 생성은 `--out-dir`을 사용하세요.
61
+
62
+ ## 예제
63
+
64
+ ### 입력: Java Controller
65
+
66
+ ```java
67
+ @RestController
68
+ @RequestMapping("/api/users")
69
+ public class UserController {
70
+
71
+ @GetMapping
72
+ @PreAuthorize("hasRole('USER')")
73
+ public ResponseEntity<PaginatedList<UserDTO>> searchUsers(SearchParam searchParam) {
74
+ return ResponseEntity.ok(new PaginatedList<>());
75
+ }
76
+
77
+ @GetMapping("/{id}")
78
+ @PreAuthorize("hasAnyRole('USER', 'ADMIN')")
79
+ public ResponseEntity<UserDTO> getUserById(@PathVariable Long id) {
80
+ return ResponseEntity.ok(new UserDTO());
81
+ }
82
+
83
+ @PutMapping("/{id}")
84
+ @PreAuthorize("hasRole('ADMIN') or (#id == authentication.principal.id and hasRole('USER'))")
85
+ public ResponseEntity<UserDTO> updateUser(
86
+ @PathVariable Long id,
87
+ @Valid @RequestBody UpdateUserRequest request) {
88
+ return ResponseEntity.ok(new UserDTO());
89
+ }
90
+ }
91
+ ```
92
+
93
+ ### 출력: OpenAPI YAML
94
+
95
+ ```yaml
96
+ openapi: 3.0.0
97
+ info:
98
+ title: My API
99
+ version: 1.0.0
100
+ paths:
101
+ /api/users:
102
+ get:
103
+ summary: Search users
104
+ operationId: user_searchUsers
105
+ parameters:
106
+ - name: offset
107
+ in: query
108
+ schema:
109
+ type: integer
110
+ description: Pagination offset
111
+ - name: limit
112
+ in: query
113
+ schema:
114
+ type: integer
115
+ description: Pagination limit
116
+ - name: filter
117
+ in: query
118
+ schema:
119
+ $ref: '#/components/schemas/Filter'
120
+ - name: sort
121
+ in: query
122
+ schema:
123
+ $ref: '#/components/schemas/Sort'
124
+ responses:
125
+ '200':
126
+ description: Successful response
127
+ headers:
128
+ X-Total-Count:
129
+ schema:
130
+ type: integer
131
+ description: Total number of items
132
+ X-Offset:
133
+ schema:
134
+ type: integer
135
+ description: Current offset
136
+ X-Limit:
137
+ schema:
138
+ type: integer
139
+ description: Current limit
140
+ content:
141
+ application/json:
142
+ schema:
143
+ $ref: '#/components/schemas/PaginatedListUserDTO'
144
+ security:
145
+ - bearerAuth: []
146
+ x-required-roles:
147
+ - ROLE_USER
148
+
149
+ /api/users/{id}:
150
+ get:
151
+ summary: Get user by ID
152
+ operationId: user_getUserById
153
+ parameters:
154
+ - name: id
155
+ in: path
156
+ required: true
157
+ schema:
158
+ type: integer
159
+ format: int64
160
+ responses:
161
+ '200':
162
+ description: Successful response
163
+ content:
164
+ application/json:
165
+ schema:
166
+ $ref: '#/components/schemas/UserDTO'
167
+ security:
168
+ - bearerAuth: []
169
+ x-required-roles:
170
+ - ROLE_USER
171
+ - ROLE_ADMIN
172
+
173
+ put:
174
+ summary: Update user
175
+ operationId: user_updateUser
176
+ parameters:
177
+ - name: id
178
+ in: path
179
+ required: true
180
+ schema:
181
+ type: integer
182
+ format: int64
183
+ requestBody:
184
+ required: true
185
+ content:
186
+ application/json:
187
+ schema:
188
+ $ref: '#/components/schemas/UpdateUserRequest'
189
+ responses:
190
+ '200':
191
+ description: Successful response
192
+ content:
193
+ application/json:
194
+ schema:
195
+ $ref: '#/components/schemas/UserDTO'
196
+ security:
197
+ - bearerAuth: []
198
+ x-required-roles:
199
+ - ROLE_ADMIN
200
+ - ROLE_USER
201
+ x-security-expression: "hasRole('ADMIN') or (#id == authentication.principal.id and hasRole('USER'))"
202
+
203
+ components:
204
+ schemas:
205
+ UserDTO:
206
+ type: object
207
+ properties:
208
+ id:
209
+ type: integer
210
+ format: int64
211
+ firstName:
212
+ type: string
213
+ minLength: 2
214
+ maxLength: 50
215
+ lastName:
216
+ type: string
217
+ minLength: 2
218
+ maxLength: 50
219
+ email:
220
+ type: string
221
+ required:
222
+ - firstName
223
+ - lastName
224
+ - email
225
+
226
+ Filter:
227
+ type: object
228
+ description: Filter conditions
229
+ additionalProperties: true
230
+
231
+ Sort:
232
+ type: object
233
+ description: Sort conditions
234
+ properties:
235
+ field:
236
+ type: string
237
+ direction:
238
+ type: string
239
+ enum:
240
+ - ASC
241
+ - DESC
242
+
243
+ securitySchemes:
244
+ bearerAuth:
245
+ type: http
246
+ scheme: bearer
247
+ bearerFormat: JWT
248
+ ```
249
+
250
+ ## 특수 타입 처리
251
+
252
+ ### SearchParam
253
+
254
+ 메서드 파라미터가 `SearchParam` 타입인 경우, 생성기가 자동으로 페이지네이션 쿼리 파라미터를 추가합니다:
255
+
256
+ - `offset` (integer) - 페이지네이션 오프셋
257
+ - `limit` (integer) - 페이지네이션 제한
258
+ - `filter` (object) - 필터 조건 (Filter 스키마 참조)
259
+ - `sort` (object) - 정렬 조건 (Sort 스키마 참조)
260
+
261
+ ### PaginatedList<T>
262
+
263
+ 메서드가 `PaginatedList<T>`를 반환하는 경우, 생성기가:
264
+
265
+ 1. 응답에 페이지네이션 헤더를 추가합니다:
266
+ - `X-Total-Count` - 전체 항목 수
267
+ - `X-Offset` - 현재 오프셋
268
+ - `X-Limit` - 현재 제한
269
+
270
+ 2. 다음 구조의 `PaginatedListT` 스키마를 생성합니다:
271
+ ```yaml
272
+ PaginatedListUserDTO:
273
+ type: object
274
+ properties:
275
+ items:
276
+ type: array
277
+ items:
278
+ $ref: '#/components/schemas/UserDTO'
279
+ total:
280
+ type: integer
281
+ offset:
282
+ type: integer
283
+ limit:
284
+ type: integer
285
+ ```
286
+
287
+ ### 보안 표현식
288
+
289
+ 생성기가 `@PreAuthorize` 및 `@PostAuthorize`의 SpEL 표현식을 파싱합니다:
290
+
291
+ - `hasRole('ADMIN')` 같은 단순 표현식 → `x-required-roles: [ROLE_ADMIN]`
292
+ - `hasAnyRole('USER', 'ADMIN')`의 다중 역할 → `x-required-roles: [ROLE_USER, ROLE_ADMIN]`
293
+ - 복잡한 표현식은 `x-security-expression`에 보존
294
+
295
+ ## 유효성 검사 어노테이션
296
+
297
+ 생성기가 DTO 필드의 다음 유효성 검사 어노테이션을 인식합니다:
298
+
299
+ | 어노테이션 | OpenAPI 매핑 |
300
+ |------------|-----------------|
301
+ | `@NotNull`, `@NotBlank`, `@NotEmpty` | `required: true` |
302
+ | `@Size(min, max)` | `minLength`, `maxLength` |
303
+ | `@Min(value)` | `minimum` |
304
+ | `@Max(value)` | `maximum` |
305
+ | `@Pattern(regexp)` | `pattern` |
306
+ | `@Email` | `pattern` (이메일 정규식) |
307
+
308
+ ## 프로젝트 구조
309
+
310
+ ```
311
+ api-gen/
312
+ ├── src/
313
+ │ ├── index.ts # CLI 진입점
314
+ │ ├── parser/
315
+ │ │ ├── javaParser.ts # Java 파일 파싱
316
+ │ │ └── astAnalyzer.ts # AST 분석 유틸리티
317
+ │ ├── analyzer/
318
+ │ │ ├── controllerAnalyzer.ts # Controller 감지
319
+ │ │ ├── parameterAnalyzer.ts # 파라미터 추출
320
+ │ │ ├── responseAnalyzer.ts # 응답 분석
321
+ │ │ ├── securityAnalyzer.ts # 보안 어노테이션 파싱
322
+ │ │ └── schemaGenerator.ts # DTO 스키마 생성
323
+ │ ├── generator/
324
+ │ │ └── openapiGenerator.ts # OpenAPI YAML 생성
325
+ │ └── types/
326
+ │ └── index.ts # TypeScript 타입 정의
327
+ ├── examples/ # 샘플 Java 파일
328
+ ├── package.json
329
+ ├── tsconfig.json
330
+ └── README.md
331
+ ```
332
+
333
+ ## 개발
334
+
335
+ ```bash
336
+ # 의존성 설치
337
+ pnpm install
338
+
339
+ # 개발 모드로 실행
340
+ pnpm dev -- --source ./examples
341
+
342
+ # 프로덕션 빌드
343
+ pnpm build
344
+
345
+ # 테스트 실행 (예제 파일 사용)
346
+ pnpm test
347
+ ```
348
+
349
+ # 실제 사용 예시
350
+
351
+ ```shell
352
+ pnpm start --source /git/g1cloud2/g1cloud-sales --output ./out/g1cloud-sales.yaml --title "G1cloud Sales API" --api-version "2.0.0-SNAPSHOT"
353
+
354
+ npx @redocly/cli build-docs ./out/g1cloud-sales.yaml -o ./out/g1cloud-sales.html
355
+ ```
356
+
357
+ ```shell
358
+ pnpm start --source /git/g1cloud2/g1cloud-sales \
359
+ --api-source /git/g1cloud2/g1cloud-sales/g1cloud-sales-app \
360
+ --output ./out/g1cloud-sales-app.yaml \
361
+ --title "G1cloud Sales API" \
362
+ --api-version "2.0.0-SNAPSHOT"
363
+
364
+ npx @redocly/cli build-docs \
365
+ ./out/g1cloud-sales-app.yaml \
366
+ -o ./out/g1cloud-sales-app.html
367
+ ```
368
+
369
+ ```shell
370
+ pnpm start --source /git/g1cloud2/g1cloud-sales-service \
371
+ --api-source /git/g1cloud2/g1cloud-sales-service/module-basis \
372
+ --output ./out/g1cloud-sales-basis.yaml \
373
+ --title "G1cloud Sales Basis API" \
374
+ --api-version "2.0.0-SNAPSHOT"
375
+
376
+ npx @redocly/cli build-docs \
377
+ ./out/g1cloud-sales-basis.yaml \
378
+ -o ./out/g1cloud-sales-basis.html
379
+ ```
@@ -0,0 +1,20 @@
1
+ import { ControllerInfo, ProcessingContext } from '../types';
2
+ export declare class ControllerAnalyzer {
3
+ private context;
4
+ constructor(context: ProcessingContext);
5
+ /**
6
+ * Analyze all Java classes and extract controller information
7
+ * If apiSourcePath is specified, only analyze controllers within that directory
8
+ */
9
+ analyzeControllers(): ControllerInfo[];
10
+ /**
11
+ * Analyze a single controller class
12
+ */
13
+ private analyzeController;
14
+ /**
15
+ * Analyze a single endpoint method
16
+ */
17
+ private analyzeEndpoint;
18
+ }
19
+ export declare function analyzeControllers(context: ProcessingContext): ControllerInfo[];
20
+ //# sourceMappingURL=controllerAnalyzer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"controllerAnalyzer.d.ts","sourceRoot":"","sources":["../../src/analyzer/controllerAnalyzer.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,cAAc,EAGd,iBAAiB,EAClB,MAAM,UAAU,CAAC;AAMlB,qBAAa,kBAAkB;IAC7B,OAAO,CAAC,OAAO,CAAoB;gBAEvB,OAAO,EAAE,iBAAiB;IAItC;;;OAGG;IACH,kBAAkB,IAAI,cAAc,EAAE;IAqBtC;;OAEG;IACH,OAAO,CAAC,iBAAiB;IA4BzB;;OAEG;IACH,OAAO,CAAC,eAAe;CAwCxB;AAED,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,iBAAiB,GAAG,cAAc,EAAE,CAG/E"}
@@ -0,0 +1,101 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ControllerAnalyzer = void 0;
4
+ exports.analyzeControllers = analyzeControllers;
5
+ const astAnalyzer_1 = require("../parser/astAnalyzer");
6
+ const parameterAnalyzer_1 = require("./parameterAnalyzer");
7
+ const responseAnalyzer_1 = require("./responseAnalyzer");
8
+ const securityAnalyzer_1 = require("./securityAnalyzer");
9
+ class ControllerAnalyzer {
10
+ context;
11
+ constructor(context) {
12
+ this.context = context;
13
+ }
14
+ /**
15
+ * Analyze all Java classes and extract controller information
16
+ * If apiSourcePath is specified, only analyze controllers within that directory
17
+ */
18
+ analyzeControllers() {
19
+ const controllers = [];
20
+ const { apiSourcePath } = this.context;
21
+ for (const [, javaClass] of this.context.javaClasses) {
22
+ // If apiSourcePath is specified, only include controllers from that directory
23
+ if (apiSourcePath && !javaClass.filePath.startsWith(apiSourcePath)) {
24
+ continue;
25
+ }
26
+ if (astAnalyzer_1.ASTAnalyzer.isRestController(javaClass)) {
27
+ const controllerInfo = this.analyzeController(javaClass);
28
+ if (controllerInfo) {
29
+ controllers.push(controllerInfo);
30
+ }
31
+ }
32
+ }
33
+ return controllers;
34
+ }
35
+ /**
36
+ * Analyze a single controller class
37
+ */
38
+ analyzeController(javaClass) {
39
+ const basePath = astAnalyzer_1.ASTAnalyzer.getClassBasePath(javaClass);
40
+ const endpoints = [];
41
+ console.log(` Found controller: ${javaClass.name} (base path: ${basePath || '/'})`);
42
+ for (const method of javaClass.methods) {
43
+ if (astAnalyzer_1.ASTAnalyzer.isEndpointMethod(method)) {
44
+ const endpoint = this.analyzeEndpoint(javaClass, method, basePath);
45
+ if (endpoint) {
46
+ endpoints.push(endpoint);
47
+ console.log(` - ${endpoint.method.toUpperCase()} ${endpoint.path}`);
48
+ }
49
+ }
50
+ }
51
+ if (endpoints.length === 0) {
52
+ return null;
53
+ }
54
+ return {
55
+ className: javaClass.name,
56
+ basePath,
57
+ endpoints,
58
+ javaClass,
59
+ };
60
+ }
61
+ /**
62
+ * Analyze a single endpoint method
63
+ */
64
+ analyzeEndpoint(javaClass, method, basePath) {
65
+ const httpMethod = astAnalyzer_1.ASTAnalyzer.getHttpMethod(method);
66
+ if (!httpMethod) {
67
+ return null;
68
+ }
69
+ const methodPath = astAnalyzer_1.ASTAnalyzer.getMethodPath(method);
70
+ const fullPath = astAnalyzer_1.ASTAnalyzer.combinePaths(basePath, methodPath);
71
+ // Get @param descriptions from javadoc
72
+ const paramDescriptions = method.javadocInfo?.params || {};
73
+ // Analyze parameters (pass javadoc @param descriptions)
74
+ const { parameters, requestBody, hasSearchParam } = (0, parameterAnalyzer_1.analyzeParameters)(method, this.context, paramDescriptions);
75
+ // Analyze response
76
+ const { responses, hasPaginatedList, paginatedListItemType } = (0, responseAnalyzer_1.analyzeResponse)(method, this.context);
77
+ // Analyze security
78
+ const security = (0, securityAnalyzer_1.analyzeMethodSecurity)(method);
79
+ return {
80
+ path: fullPath,
81
+ method: httpMethod,
82
+ operationId: astAnalyzer_1.ASTAnalyzer.generateOperationId(javaClass.name, method.name),
83
+ summary: astAnalyzer_1.ASTAnalyzer.generateSummary(method.name),
84
+ description: method.javadoc,
85
+ returnDescription: method.javadocInfo?.returns,
86
+ parameters,
87
+ requestBody,
88
+ responses,
89
+ security,
90
+ hasSearchParam,
91
+ hasPaginatedList,
92
+ paginatedListItemType,
93
+ };
94
+ }
95
+ }
96
+ exports.ControllerAnalyzer = ControllerAnalyzer;
97
+ function analyzeControllers(context) {
98
+ const analyzer = new ControllerAnalyzer(context);
99
+ return analyzer.analyzeControllers();
100
+ }
101
+ //# sourceMappingURL=controllerAnalyzer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"controllerAnalyzer.js","sourceRoot":"","sources":["../../src/analyzer/controllerAnalyzer.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,19 @@
1
+ import { JavaMethod, ParameterInfo, RequestBodyInfo, ProcessingContext, SchemaInfo } from '../types';
2
+ interface ParameterAnalysisResult {
3
+ parameters: ParameterInfo[];
4
+ requestBody?: RequestBodyInfo;
5
+ hasSearchParam: boolean;
6
+ }
7
+ /**
8
+ * Analyze method parameters and extract OpenAPI parameter/request body info
9
+ * @param method The Java method to analyze
10
+ * @param context Processing context
11
+ * @param paramDescriptions Javadoc @param descriptions (param name -> description)
12
+ */
13
+ export declare function analyzeParameters(method: JavaMethod, context: ProcessingContext, paramDescriptions?: Record<string, string>): ParameterAnalysisResult;
14
+ /**
15
+ * Create a schema for a Java type
16
+ */
17
+ export declare function createSchemaForType(javaType: string, genericType: string | undefined, context: ProcessingContext): SchemaInfo;
18
+ export {};
19
+ //# sourceMappingURL=parameterAnalyzer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parameterAnalyzer.d.ts","sourceRoot":"","sources":["../../src/analyzer/parameterAnalyzer.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,UAAU,EAGV,aAAa,EACb,eAAe,EACf,iBAAiB,EACjB,UAAU,EACX,MAAM,UAAU,CAAC;AAGlB,UAAU,uBAAuB;IAC/B,UAAU,EAAE,aAAa,EAAE,CAAC;IAC5B,WAAW,CAAC,EAAE,eAAe,CAAC;IAC9B,cAAc,EAAE,OAAO,CAAC;CACzB;AAED;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAC/B,MAAM,EAAE,UAAU,EAClB,OAAO,EAAE,iBAAiB,EAC1B,iBAAiB,GAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAM,GAC7C,uBAAuB,CAiCzB;AAkID;;GAEG;AACH,wBAAgB,mBAAmB,CACjC,QAAQ,EAAE,MAAM,EAChB,WAAW,EAAE,MAAM,GAAG,SAAS,EAC/B,OAAO,EAAE,iBAAiB,GACzB,UAAU,CA4CZ"}