@enokdev/springdocs-mcp 1.2.7 → 1.4.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 (112) hide show
  1. package/README.md +108 -40
  2. package/build/config.d.ts +9 -0
  3. package/build/config.d.ts.map +1 -0
  4. package/build/config.js +32 -0
  5. package/build/config.js.map +1 -0
  6. package/build/format.d.ts +6 -0
  7. package/build/format.d.ts.map +1 -0
  8. package/build/format.js +23 -0
  9. package/build/format.js.map +1 -0
  10. package/build/http-server.d.ts +15 -0
  11. package/build/http-server.d.ts.map +1 -0
  12. package/build/http-server.js +131 -0
  13. package/build/http-server.js.map +1 -0
  14. package/build/index.js +184 -69
  15. package/build/index.js.map +1 -1
  16. package/build/prompts.d.ts +23 -0
  17. package/build/prompts.d.ts.map +1 -0
  18. package/build/prompts.js +112 -0
  19. package/build/prompts.js.map +1 -0
  20. package/build/resources.d.ts +31 -0
  21. package/build/resources.d.ts.map +1 -0
  22. package/build/resources.js +66 -0
  23. package/build/resources.js.map +1 -0
  24. package/build/services/advanced-features.d.ts +19 -9
  25. package/build/services/advanced-features.d.ts.map +1 -1
  26. package/build/services/advanced-features.js +266 -191
  27. package/build/services/advanced-features.js.map +1 -1
  28. package/build/services/boot-wiki.d.ts +25 -0
  29. package/build/services/boot-wiki.d.ts.map +1 -0
  30. package/build/services/boot-wiki.js +103 -0
  31. package/build/services/boot-wiki.js.map +1 -0
  32. package/build/services/cache.d.ts +18 -3
  33. package/build/services/cache.d.ts.map +1 -1
  34. package/build/services/cache.js +84 -3
  35. package/build/services/cache.js.map +1 -1
  36. package/build/services/dependency-finder.d.ts +46 -0
  37. package/build/services/dependency-finder.d.ts.map +1 -0
  38. package/build/services/dependency-finder.js +181 -0
  39. package/build/services/dependency-finder.js.map +1 -0
  40. package/build/services/diagnosis.d.ts +46 -0
  41. package/build/services/diagnosis.d.ts.map +1 -0
  42. package/build/services/diagnosis.js +481 -0
  43. package/build/services/diagnosis.js.map +1 -0
  44. package/build/services/guides-list.d.ts +16 -0
  45. package/build/services/guides-list.d.ts.map +1 -0
  46. package/build/services/guides-list.js +45 -0
  47. package/build/services/guides-list.js.map +1 -0
  48. package/build/services/http.d.ts +21 -0
  49. package/build/services/http.d.ts.map +1 -0
  50. package/build/services/http.js +168 -0
  51. package/build/services/http.js.map +1 -0
  52. package/build/services/initializr.d.ts +41 -0
  53. package/build/services/initializr.d.ts.map +1 -0
  54. package/build/services/initializr.js +135 -0
  55. package/build/services/initializr.js.map +1 -0
  56. package/build/services/markdown.d.ts +56 -0
  57. package/build/services/markdown.d.ts.map +1 -0
  58. package/build/services/markdown.js +146 -0
  59. package/build/services/markdown.js.map +1 -0
  60. package/build/services/migration-sources.d.ts +13 -0
  61. package/build/services/migration-sources.d.ts.map +1 -0
  62. package/build/services/migration-sources.js +48 -0
  63. package/build/services/migration-sources.js.map +1 -0
  64. package/build/services/release-notes.d.ts +23 -0
  65. package/build/services/release-notes.d.ts.map +1 -0
  66. package/build/services/release-notes.js +94 -0
  67. package/build/services/release-notes.js.map +1 -0
  68. package/build/services/search-index.d.ts +33 -0
  69. package/build/services/search-index.d.ts.map +1 -0
  70. package/build/services/search-index.js +147 -0
  71. package/build/services/search-index.js.map +1 -0
  72. package/build/services/spring-projects-config.d.ts +98 -0
  73. package/build/services/spring-projects-config.d.ts.map +1 -0
  74. package/build/services/spring-projects-config.js +397 -0
  75. package/build/services/spring-projects-config.js.map +1 -0
  76. package/build/services/springboot-docs-optimized.d.ts +72 -21
  77. package/build/services/springboot-docs-optimized.d.ts.map +1 -1
  78. package/build/services/springboot-docs-optimized.js +354 -208
  79. package/build/services/springboot-docs-optimized.js.map +1 -1
  80. package/build/services/url.d.ts +15 -0
  81. package/build/services/url.d.ts.map +1 -0
  82. package/build/services/url.js +40 -0
  83. package/build/services/url.js.map +1 -0
  84. package/build/tools/index.d.ts +393 -2
  85. package/build/tools/index.d.ts.map +1 -1
  86. package/build/tools/index.js +188 -15
  87. package/build/tools/index.js.map +1 -1
  88. package/build/validation.d.ts +7 -0
  89. package/build/validation.d.ts.map +1 -0
  90. package/build/validation.js +50 -0
  91. package/build/validation.js.map +1 -0
  92. package/build/version.d.ts +3 -0
  93. package/build/version.d.ts.map +1 -0
  94. package/build/version.js +6 -0
  95. package/build/version.js.map +1 -0
  96. package/package.json +9 -7
  97. package/build/debug.d.ts +0 -3
  98. package/build/debug.d.ts.map +0 -1
  99. package/build/debug.js +0 -292
  100. package/build/debug.js.map +0 -1
  101. package/build/services/advanced-features-old.d.ts +0 -45
  102. package/build/services/advanced-features-old.d.ts.map +0 -1
  103. package/build/services/advanced-features-old.js +0 -792
  104. package/build/services/advanced-features-old.js.map +0 -1
  105. package/build/services/springboot-docs-optimized-old.d.ts +0 -55
  106. package/build/services/springboot-docs-optimized-old.d.ts.map +0 -1
  107. package/build/services/springboot-docs-optimized-old.js +0 -588
  108. package/build/services/springboot-docs-optimized-old.js.map +0 -1
  109. package/build/services/springboot-docs.d.ts +0 -65
  110. package/build/services/springboot-docs.d.ts.map +0 -1
  111. package/build/services/springboot-docs.js +0 -708
  112. package/build/services/springboot-docs.js.map +0 -1
@@ -1,792 +0,0 @@
1
- import * as cheerio from 'cheerio';
2
- import TurndownService from 'turndown';
3
- import { CacheService } from './cache.js';
4
- /**
5
- * Advanced features service for Spring documentation - uses real Spring documentation APIs
6
- */
7
- export class AdvancedFeaturesService {
8
- cache;
9
- turndownService;
10
- baseUrl = 'https://docs.spring.io';
11
- springProjectsUrl = 'https://spring.io/projects';
12
- springGuideUrl = 'https://spring.io/guides';
13
- REQUEST_TIMEOUT = 10000;
14
- MAX_RETRIES = 3;
15
- constructor() {
16
- this.cache = new CacheService();
17
- this.turndownService = new TurndownService({
18
- headingStyle: 'atx',
19
- codeBlockStyle: 'fenced',
20
- });
21
- }
22
- /**
23
- * Search across the entire Spring ecosystem
24
- */
25
- async searchEcosystem(query, scope = 'all', limit = 5) {
26
- const cacheKey = `ecosystem:${query}:${scope}:${limit}`;
27
- const cached = this.cache.get(cacheKey);
28
- if (cached)
29
- return cached;
30
- const results = {
31
- query,
32
- scope,
33
- totalResults: 0,
34
- categories: {}
35
- };
36
- try {
37
- if (scope === 'all' || scope === 'projects') {
38
- results.categories.projects = await this.searchProjects(query, limit);
39
- }
40
- if (scope === 'all' || scope === 'guides') {
41
- results.categories.guides = await this.searchGuides(query, limit);
42
- }
43
- if (scope === 'all' || scope === 'docs') {
44
- results.categories.documentation = await this.searchDocumentation(query, limit);
45
- }
46
- if (scope === 'all' || scope === 'api') {
47
- results.categories.api = await this.searchAPI(query, limit);
48
- }
49
- results.totalResults = Object.values(results.categories)
50
- .reduce((total, category) => total + (category?.length || 0), 0);
51
- this.cache.set(cacheKey, results);
52
- return results;
53
- }
54
- catch (error) {
55
- console.error('Error in ecosystem search:', error);
56
- throw new Error('Failed to search Spring ecosystem');
57
- }
58
- }
59
- /**
60
- * Get step-by-step tutorials
61
- */
62
- async getTutorial(topic, level = 'beginner') {
63
- const cacheKey = `tutorial:${topic}:${level}`;
64
- const cached = this.cache.get(cacheKey);
65
- if (cached)
66
- return cached;
67
- const tutorials = this.getTutorialDatabase();
68
- const tutorial = tutorials[topic]?.[level];
69
- if (!tutorial) {
70
- const availableTopics = Object.keys(tutorials).join(', ');
71
- return `# Tutorial Not Found
72
-
73
- The tutorial for "${topic}" at "${level}" level is not available.
74
-
75
- ## Available Topics:
76
- ${availableTopics}
77
-
78
- ## Available Levels:
79
- - beginner
80
- - intermediate
81
- - advanced
82
-
83
- Please use one of the available topics and levels.`;
84
- }
85
- this.cache.setLongTerm(cacheKey, tutorial);
86
- return tutorial;
87
- }
88
- /**
89
- * Compare Spring Boot versions
90
- */
91
- async compareVersions(version1, version2, focus = 'all') {
92
- const cacheKey = `compare:${version1}:${version2}:${focus}`;
93
- const cached = this.cache.get(cacheKey);
94
- if (cached)
95
- return cached;
96
- try {
97
- const comparison = await this.generateVersionComparison(version1, version2, focus);
98
- this.cache.setLongTerm(cacheKey, comparison);
99
- return comparison;
100
- }
101
- catch (error) {
102
- console.error('Error comparing versions:', error);
103
- throw new Error(`Failed to compare Spring Boot versions ${version1} and ${version2}`);
104
- }
105
- }
106
- /**
107
- * Get best practices
108
- */
109
- async getBestPractices(category, experienceLevel = 'intermediate') {
110
- const cacheKey = `practices:${category}:${experienceLevel}`;
111
- const cached = this.cache.get(cacheKey);
112
- if (cached)
113
- return cached;
114
- const practices = this.getBestPracticesDatabase();
115
- const categoryPractices = practices[category];
116
- if (!categoryPractices) {
117
- const availableCategories = Object.keys(practices).join(', ');
118
- return `# Best Practices Not Found
119
-
120
- Best practices for "${category}" category are not available.
121
-
122
- ## Available Categories:
123
- ${availableCategories}
124
-
125
- Please use one of the available categories.`;
126
- }
127
- const result = this.formatBestPractices(categoryPractices, experienceLevel);
128
- this.cache.setLongTerm(cacheKey, result);
129
- return result;
130
- }
131
- /**
132
- * Diagnose Spring issues
133
- */
134
- async diagnoseIssues(errorMessage, component, stackTrace) {
135
- const cacheKey = `diagnose:${this.hashString(errorMessage)}:${component || 'general'}`;
136
- const cached = this.cache.get(cacheKey);
137
- if (cached)
138
- return cached;
139
- const diagnosis = this.performIssueDiagnosis(errorMessage, component, stackTrace);
140
- this.cache.set(cacheKey, diagnosis, 60 * 60 * 1000); // 1 hour cache
141
- return diagnosis;
142
- }
143
- // Private helper methods
144
- async searchProjects(query, limit) {
145
- try {
146
- const response = await this.fetchWithRetry(this.springProjectsUrl);
147
- if (!response.ok) {
148
- throw new Error('Failed to fetch Spring projects');
149
- }
150
- const html = await response.text();
151
- const $ = cheerio.load(html);
152
- const projects = [];
153
- // Parse Spring projects page
154
- $('.project-list .project, .project-item, .card, .project-card').each((index, element) => {
155
- const $project = $(element);
156
- const name = $project.find('h2, h3, .title, .project-title, .card-title').first().text().trim();
157
- const description = $project.find('p, .description, .summary, .card-text').first().text().trim();
158
- const link = $project.find('a').first().attr('href');
159
- if (name && description) {
160
- const url = link?.startsWith('http') ? link : `https://spring.io${link}`;
161
- if (name.toLowerCase().includes(query.toLowerCase()) ||
162
- description.toLowerCase().includes(query.toLowerCase())) {
163
- projects.push({
164
- name,
165
- description,
166
- url,
167
- type: 'project'
168
- });
169
- }
170
- }
171
- });
172
- return projects.slice(0, limit);
173
- }
174
- catch (error) {
175
- console.error('Error searching projects:', error);
176
- return [];
177
- }
178
- }
179
- async searchGuides(query, limit) {
180
- try {
181
- const response = await this.fetchWithRetry(this.springGuideUrl);
182
- if (!response.ok) {
183
- throw new Error('Failed to fetch Spring guides');
184
- }
185
- const html = await response.text();
186
- const $ = cheerio.load(html);
187
- const guides = [];
188
- // Parse Spring guides page
189
- $('.guide-item, .card, .guide-card, .list-item').each((index, element) => {
190
- const $guide = $(element);
191
- const title = $guide.find('h2, h3, .title, .guide-title, .card-title, a').first().text().trim();
192
- const description = $guide.find('p, .description, .summary, .card-text').first().text().trim();
193
- const link = $guide.find('a').first().attr('href');
194
- const type = $guide.find('.badge, .label, .type').first().text().trim() || 'Guide';
195
- if (title) {
196
- const url = link?.startsWith('http') ? link : `https://spring.io${link}`;
197
- if (title.toLowerCase().includes(query.toLowerCase()) ||
198
- description.toLowerCase().includes(query.toLowerCase())) {
199
- guides.push({
200
- title,
201
- description: description || 'Spring Boot guide',
202
- url,
203
- type
204
- });
205
- }
206
- }
207
- });
208
- return guides.slice(0, limit);
209
- }
210
- catch (error) {
211
- console.error('Error searching guides:', error);
212
- return [];
213
- }
214
- }
215
- async searchDocumentation(query, limit) {
216
- try {
217
- // Search Spring Boot reference documentation
218
- const bootDocsUrl = `${this.baseUrl}/spring-boot/docs/current/reference/html/`;
219
- const response = await this.fetchWithRetry(bootDocsUrl);
220
- if (!response.ok) {
221
- throw new Error('Failed to fetch Spring Boot documentation');
222
- }
223
- const html = await response.text();
224
- const $ = cheerio.load(html);
225
- const docs = [];
226
- // Parse documentation sections
227
- $('nav a, .toc a, .nav-link, .chapter a').each((index, element) => {
228
- const $link = $(element);
229
- const title = $link.text().trim();
230
- const href = $link.attr('href');
231
- if (title && href && title.toLowerCase().includes(query.toLowerCase())) {
232
- const url = href.startsWith('http') ? href : `${bootDocsUrl}${href}`;
233
- docs.push({
234
- title: `Spring Boot: ${title}`,
235
- url,
236
- type: 'Reference Documentation'
237
- });
238
- }
239
- });
240
- // Add main documentation pages based on query
241
- const mainDocs = [
242
- { title: 'Spring Boot Reference Documentation', url: 'https://docs.spring.io/spring-boot/docs/current/reference/html/', keywords: ['boot', 'configuration', 'auto-configuration', 'starters'] },
243
- { title: 'Spring Framework Documentation', url: 'https://docs.spring.io/spring-framework/docs/current/reference/html/', keywords: ['core', 'ioc', 'aop', 'mvc'] },
244
- { title: 'Spring Security Reference', url: 'https://docs.spring.io/spring-security/reference/', keywords: ['security', 'authentication', 'authorization', 'oauth2'] },
245
- { title: 'Spring Data JPA Reference', url: 'https://docs.spring.io/spring-data/jpa/docs/current/reference/html/', keywords: ['jpa', 'repository', 'query', 'database'] }
246
- ];
247
- const queryLower = query.toLowerCase();
248
- mainDocs.forEach(doc => {
249
- if (doc.title.toLowerCase().includes(queryLower) ||
250
- doc.keywords.some(keyword => keyword.includes(queryLower))) {
251
- docs.push({
252
- title: doc.title,
253
- url: doc.url,
254
- type: 'Reference'
255
- });
256
- }
257
- });
258
- return docs.slice(0, limit);
259
- }
260
- catch (error) {
261
- console.error('Error searching documentation:', error);
262
- return [];
263
- }
264
- }
265
- async searchAPI(query, limit) {
266
- const apis = [
267
- { title: 'Spring Boot API Documentation', url: 'https://docs.spring.io/spring-boot/docs/current/api/', keywords: ['boot', 'autoconfiguration', 'starters'] },
268
- { title: 'Spring Framework API', url: 'https://docs.spring.io/spring-framework/docs/current/javadoc-api/', keywords: ['core', 'context', 'beans', 'web'] },
269
- { title: 'Spring Security API', url: 'https://docs.spring.io/spring-security/site/docs/current/api/', keywords: ['security', 'authentication', 'config'] },
270
- { title: 'Spring Data JPA API', url: 'https://docs.spring.io/spring-data/jpa/docs/current/api/', keywords: ['jpa', 'repository', 'query'] },
271
- { title: 'Spring Test API', url: 'https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/test/package-summary.html', keywords: ['testing', 'context', 'mock'] }
272
- ];
273
- const queryLower = query.toLowerCase();
274
- return apis
275
- .filter(a => a.title.toLowerCase().includes(queryLower) ||
276
- a.keywords.some(keyword => keyword.toLowerCase().includes(queryLower)))
277
- .map(a => ({
278
- title: a.title,
279
- url: a.url,
280
- type: 'API Documentation'
281
- }))
282
- .slice(0, limit);
283
- }
284
- getTutorialDatabase() {
285
- return {
286
- 'rest-api': {
287
- beginner: `# Building Your First REST API with Spring Boot
288
-
289
- ## Prerequisites
290
- - Java 11 or higher
291
- - Basic understanding of Java
292
- - Maven or Gradle
293
-
294
- ## Step 1: Create a New Spring Boot Project
295
- \`\`\`bash
296
- curl https://start.spring.io/starter.zip \\
297
- -d dependencies=web \\
298
- -d name=my-rest-api \\
299
- -d packageName=com.example.api \\
300
- -o my-rest-api.zip
301
- \`\`\`
302
-
303
- ## Step 2: Create a Simple Controller
304
- \`\`\`java
305
- @RestController
306
- @RequestMapping("/api")
307
- public class HelloController {
308
-
309
- @GetMapping("/hello")
310
- public String hello() {
311
- return "Hello, World!";
312
- }
313
-
314
- @GetMapping("/hello/{name}")
315
- public String helloName(@PathVariable String name) {
316
- return "Hello, " + name + "!";
317
- }
318
- }
319
- \`\`\`
320
-
321
- ## Step 3: Run the Application
322
- \`\`\`bash
323
- ./mvnw spring-boot:run
324
- \`\`\`
325
-
326
- ## Step 4: Test Your API
327
- \`\`\`bash
328
- curl http://localhost:8080/api/hello
329
- curl http://localhost:8080/api/hello/John
330
- \`\`\`
331
-
332
- ## Next Steps
333
- - Add request/response DTOs
334
- - Implement POST, PUT, DELETE methods
335
- - Add input validation
336
- - Handle exceptions properly`,
337
- intermediate: `# Advanced REST API Development with Spring Boot
338
-
339
- ## Data Transfer Objects (DTOs)
340
- \`\`\`java
341
- public class UserDto {
342
- @NotBlank
343
- private String name;
344
-
345
- @Email
346
- private String email;
347
-
348
- // getters and setters
349
- }
350
- \`\`\`
351
-
352
- ## Service Layer
353
- \`\`\`java
354
- @Service
355
- public class UserService {
356
-
357
- @Autowired
358
- private UserRepository userRepository;
359
-
360
- public UserDto createUser(UserDto userDto) {
361
- User user = mapToEntity(userDto);
362
- User savedUser = userRepository.save(user);
363
- return mapToDto(savedUser);
364
- }
365
- }
366
- \`\`\`
367
-
368
- ## Exception Handling
369
- \`\`\`java
370
- @ControllerAdvice
371
- public class GlobalExceptionHandler {
372
-
373
- @ExceptionHandler(ValidationException.class)
374
- public ResponseEntity<ErrorResponse> handleValidation(ValidationException ex) {
375
- return ResponseEntity.badRequest()
376
- .body(new ErrorResponse("Validation failed", ex.getMessage()));
377
- }
378
- }
379
- \`\`\`
380
-
381
- ## Testing
382
- \`\`\`java
383
- @SpringBootTest
384
- @AutoConfigureTestDatabase
385
- class UserControllerTest {
386
-
387
- @Autowired
388
- private TestRestTemplate restTemplate;
389
-
390
- @Test
391
- void shouldCreateUser() {
392
- UserDto user = new UserDto("John", "john@example.com");
393
- ResponseEntity<UserDto> response = restTemplate.postForEntity(
394
- "/api/users", user, UserDto.class);
395
-
396
- assertThat(response.getStatusCode()).isEqualTo(HttpStatus.CREATED);
397
- }
398
- }
399
- \`\`\``,
400
- advanced: `# Production-Ready REST API with Spring Boot
401
-
402
- ## Advanced Features Implementation
403
-
404
- ### 1. API Versioning
405
- \`\`\`java
406
- @RestController
407
- @RequestMapping("/api/v1/users")
408
- public class UserControllerV1 {
409
- // Version 1 implementation
410
- }
411
-
412
- @RestController
413
- @RequestMapping("/api/v2/users")
414
- public class UserControllerV2 {
415
- // Version 2 with breaking changes
416
- }
417
- \`\`\`
418
-
419
- ### 2. HATEOAS Implementation
420
- \`\`\`java
421
- @GetMapping("/{id}")
422
- public EntityModel<UserDto> getUser(@PathVariable Long id) {
423
- UserDto user = userService.findById(id);
424
- return EntityModel.of(user)
425
- .add(linkTo(methodOn(UserController.class).getUser(id)).withSelfRel())
426
- .add(linkTo(UserController.class).withRel("users"));
427
- }
428
- \`\`\`
429
-
430
- ### 3. Advanced Security
431
- \`\`\`java
432
- @Configuration
433
- @EnableWebSecurity
434
- public class SecurityConfig {
435
-
436
- @Bean
437
- public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
438
- http.oauth2ResourceServer(oauth2 -> oauth2.jwt(withDefaults()))
439
- .authorizeHttpRequests(authz -> authz
440
- .requestMatchers("/api/public/**").permitAll()
441
- .requestMatchers(HttpMethod.GET, "/api/users").hasRole("USER")
442
- .requestMatchers("/api/admin/**").hasRole("ADMIN")
443
- .anyRequest().authenticated()
444
- );
445
- return http.build();
446
- }
447
- }
448
- \`\`\`
449
-
450
- ### 4. Metrics and Monitoring
451
- \`\`\`java
452
- @Component
453
- public class ApiMetrics {
454
-
455
- private final MeterRegistry meterRegistry;
456
- private final Counter apiCallCounter;
457
-
458
- public ApiMetrics(MeterRegistry meterRegistry) {
459
- this.meterRegistry = meterRegistry;
460
- this.apiCallCounter = Counter.builder("api.calls")
461
- .description("Number of API calls")
462
- .register(meterRegistry);
463
- }
464
- }
465
- \`\`\`
466
-
467
- ### 5. Rate Limiting
468
- \`\`\`java
469
- @Component
470
- public class RateLimitingFilter implements Filter {
471
-
472
- private final RedisTemplate<String, String> redisTemplate;
473
-
474
- @Override
475
- public void doFilter(ServletRequest request, ServletResponse response,
476
- FilterChain chain) throws IOException, ServletException {
477
-
478
- String clientId = getClientId(request);
479
- if (isRateLimited(clientId)) {
480
- ((HttpServletResponse) response).setStatus(429);
481
- return;
482
- }
483
-
484
- chain.doFilter(request, response);
485
- }
486
- }
487
- \`\`\``
488
- },
489
- // Add more tutorials for other topics
490
- };
491
- }
492
- async generateVersionComparison(version1, version2, focus) {
493
- // This would fetch actual version data in a real implementation
494
- return `# Spring Boot Version Comparison: ${version1} vs ${version2}
495
-
496
- ## Overview
497
- Comparing Spring Boot ${version1} with ${version2}
498
-
499
- ## Major Changes
500
- ${focus === 'all' || focus === 'breaking-changes' ? `
501
- ### Breaking Changes
502
- - Java version requirements updated
503
- - Configuration property changes
504
- - Deprecated APIs removed
505
- ` : ''}
506
-
507
- ${focus === 'all' || focus === 'new-features' ? `
508
- ### New Features
509
- - Enhanced auto-configuration
510
- - New starters available
511
- - Improved monitoring capabilities
512
- ` : ''}
513
-
514
- ${focus === 'all' || focus === 'deprecations' ? `
515
- ### Deprecations
516
- - Legacy configuration support
517
- - Outdated dependencies
518
- - Old API patterns
519
- ` : ''}
520
-
521
- ## Migration Guide
522
- 1. Update Java version if required
523
- 2. Update dependency versions
524
- 3. Review configuration changes
525
- 4. Test thoroughly
526
-
527
- ## Recommendation
528
- ${this.getUpgradeRecommendation(version1, version2)}`;
529
- }
530
- getBestPracticesDatabase() {
531
- return {
532
- architecture: {
533
- title: 'Spring Boot Architecture Best Practices',
534
- practices: [
535
- {
536
- title: 'Layer Separation',
537
- description: 'Maintain clear separation between presentation, business, and data layers',
538
- examples: ['Controller → Service → Repository pattern', 'Use DTOs for data transfer', 'Avoid business logic in controllers'],
539
- level: ['beginner', 'intermediate', 'expert']
540
- },
541
- {
542
- title: 'Dependency Injection',
543
- description: 'Use constructor injection and avoid field injection',
544
- examples: ['@Autowired on constructors', 'Final fields for dependencies', 'Testable dependencies'],
545
- level: ['intermediate', 'expert']
546
- },
547
- {
548
- title: 'Package Structure',
549
- description: 'Organize packages by feature, not by layer',
550
- examples: ['com.company.user (not com.company.controller)', 'Each package contains complete feature', 'Package-private classes for encapsulation'],
551
- level: ['intermediate', 'expert']
552
- },
553
- {
554
- title: 'Configuration Management',
555
- description: 'Use externalized configuration and profiles',
556
- examples: ['application-{profile}.yml', 'Environment-specific configurations', '@ConfigurationProperties classes'],
557
- level: ['beginner', 'intermediate', 'expert']
558
- }
559
- ]
560
- },
561
- performance: {
562
- title: 'Performance Optimization',
563
- practices: [
564
- {
565
- title: 'Database Optimization',
566
- description: 'Optimize database queries and connections',
567
- examples: ['@OneToMany(fetch = FetchType.LAZY)', 'Use @EntityGraph for specific queries', 'Connection pooling with HikariCP', 'Query optimization with indexes'],
568
- level: ['intermediate', 'expert']
569
- },
570
- {
571
- title: 'Caching Strategy',
572
- description: 'Implement effective caching mechanisms',
573
- examples: ['@Cacheable annotations', 'Redis for distributed caching', 'Cache eviction policies', 'EhCache for local caching'],
574
- level: ['intermediate', 'expert']
575
- },
576
- {
577
- title: 'JVM Tuning',
578
- description: 'Optimize JVM settings for production',
579
- examples: ['Heap size configuration', 'Garbage collector selection', 'JIT compiler optimizations', 'Memory profiling'],
580
- level: ['expert']
581
- }
582
- ]
583
- },
584
- security: {
585
- title: 'Security Best Practices',
586
- practices: [
587
- {
588
- title: 'Authentication & Authorization',
589
- description: 'Implement robust security mechanisms',
590
- examples: ['JWT token-based authentication', 'Role-based access control', 'OAuth2 integration', 'Spring Security configuration'],
591
- level: ['intermediate', 'expert']
592
- },
593
- {
594
- title: 'Input Validation',
595
- description: 'Validate all user inputs to prevent attacks',
596
- examples: ['@Valid annotations', 'Custom validators', 'SQL injection prevention', 'XSS protection'],
597
- level: ['beginner', 'intermediate', 'expert']
598
- },
599
- {
600
- title: 'Data Protection',
601
- description: 'Secure sensitive data and communications',
602
- examples: ['HTTPS enforcement', 'Password encryption with BCrypt', 'Sensitive data masking', 'Database encryption'],
603
- level: ['intermediate', 'expert']
604
- }
605
- ]
606
- },
607
- testing: {
608
- title: 'Testing Best Practices',
609
- practices: [
610
- {
611
- title: 'Unit Testing',
612
- description: 'Write comprehensive unit tests for all components',
613
- examples: ['@MockBean for dependencies', 'JUnit 5 test structure', '@WebMvcTest for controllers', 'Test coverage > 80%'],
614
- level: ['beginner', 'intermediate', 'expert']
615
- },
616
- {
617
- title: 'Integration Testing',
618
- description: 'Test component interactions and external dependencies',
619
- examples: ['@SpringBootTest for full context', '@TestContainers for databases', '@WebMvcTest for web layer', 'Test slices for focused testing'],
620
- level: ['intermediate', 'expert']
621
- },
622
- {
623
- title: 'Test Data Management',
624
- description: 'Manage test data effectively',
625
- examples: ['@Sql for test data setup', 'Test data builders', 'Database rollback after tests', 'Mock external services'],
626
- level: ['intermediate', 'expert']
627
- }
628
- ]
629
- },
630
- configuration: {
631
- title: 'Configuration Management',
632
- practices: [
633
- {
634
- title: 'Externalized Configuration',
635
- description: 'Keep configuration outside the code',
636
- examples: ['application.yml profiles', 'Environment variables', 'Configuration server (Spring Cloud Config)', '@ConfigurationProperties validation'],
637
- level: ['beginner', 'intermediate', 'expert']
638
- },
639
- {
640
- title: 'Auto-Configuration',
641
- description: 'Leverage and customize Spring Boot auto-configuration',
642
- examples: ['Custom auto-configuration classes', 'Conditional beans with @ConditionalOn*', 'Configuration properties metadata', 'Exclude unwanted auto-configurations'],
643
- level: ['intermediate', 'expert']
644
- }
645
- ]
646
- },
647
- deployment: {
648
- title: 'Deployment Best Practices',
649
- practices: [
650
- {
651
- title: 'Containerization',
652
- description: 'Package applications in containers for consistent deployment',
653
- examples: ['Multi-stage Docker builds', 'Distroless base images', 'Health checks in containers', 'Resource limits and requests'],
654
- level: ['intermediate', 'expert']
655
- },
656
- {
657
- title: 'Production Readiness',
658
- description: 'Prepare applications for production deployment',
659
- examples: ['Actuator endpoints for monitoring', 'Graceful shutdown configuration', 'Logging configuration', 'Error handling and monitoring'],
660
- level: ['intermediate', 'expert']
661
- },
662
- {
663
- title: 'CI/CD Pipeline',
664
- description: 'Automate build, test, and deployment processes',
665
- examples: ['Automated testing in pipeline', 'Blue-green deployments', 'Rolling updates', 'Automated rollback strategies'],
666
- level: ['expert']
667
- }
668
- ]
669
- }
670
- };
671
- }
672
- formatBestPractices(practices, level) {
673
- const filtered = practices.practices.filter((p) => p.level.includes(level));
674
- if (filtered.length === 0) {
675
- return `# ${practices.title}\n\nNo best practices available for ${level} level.\n\nAvailable levels: beginner, intermediate, expert`;
676
- }
677
- let result = `# ${practices.title}\n\n`;
678
- result += `**Experience Level:** ${level}\n\n`;
679
- filtered.forEach((practice, index) => {
680
- result += `## ${index + 1}. ${practice.title}\n\n`;
681
- result += `${practice.description}\n\n`;
682
- result += `**Examples:**\n`;
683
- practice.examples.forEach((example) => {
684
- result += `- ${example}\n`;
685
- });
686
- result += '\n';
687
- });
688
- return result;
689
- }
690
- performIssueDiagnosis(errorMessage, component, stackTrace) {
691
- const commonIssues = {
692
- 'Port 8080 was already in use': {
693
- cause: 'Another application is using the default Spring Boot port',
694
- solutions: [
695
- 'Change port in application.properties: server.port=8081',
696
- 'Kill the process using port 8080',
697
- 'Use a different port for your application'
698
- ]
699
- },
700
- 'Failed to configure a DataSource': {
701
- cause: 'Database configuration is missing or incorrect',
702
- solutions: [
703
- 'Add database dependency to pom.xml/build.gradle',
704
- 'Configure datasource properties in application.properties',
705
- 'Use @SpringBootApplication(exclude = {DataSourceAutoConfiguration.class}) if no database needed'
706
- ]
707
- },
708
- 'NoSuchBeanDefinitionException': {
709
- cause: 'Required bean is not found in the application context',
710
- solutions: [
711
- 'Check if the class is annotated with @Component, @Service, @Repository, or @Controller',
712
- 'Ensure the class is in a package scanned by @ComponentScan',
713
- 'Verify @Autowired dependencies are correctly configured'
714
- ]
715
- }
716
- };
717
- for (const [pattern, issue] of Object.entries(commonIssues)) {
718
- if (errorMessage.includes(pattern)) {
719
- return `# Spring Boot Issue Diagnosis
720
-
721
- ## Error Analysis
722
- **Error:** ${errorMessage}
723
- ${component ? `**Component:** ${component}` : ''}
724
-
725
- ## Root Cause
726
- ${issue.cause}
727
-
728
- ## Recommended Solutions
729
- ${issue.solutions.map((solution, index) => `${index + 1}. ${solution}`).join('\n')}
730
-
731
- ${stackTrace ? `
732
- ## Stack Trace Analysis
733
- The provided stack trace shows:
734
- \`\`\`
735
- ${stackTrace.substring(0, 500)}${stackTrace.length > 500 ? '...' : ''}
736
- \`\`\`
737
- ` : ''}
738
-
739
- ## Additional Resources
740
- - [Spring Boot Documentation](https://docs.spring.io/spring-boot/docs/current/reference/html/)
741
- - [Common Application Properties](https://docs.spring.io/spring-boot/docs/current/reference/html/application-properties.html)`;
742
- }
743
- }
744
- return `# Spring Boot Issue Diagnosis
745
-
746
- ## Error Analysis
747
- **Error:** ${errorMessage}
748
- ${component ? `**Component:** ${component}` : ''}
749
-
750
- ## Diagnosis
751
- This appears to be a custom or less common error. Here are general troubleshooting steps:
752
-
753
- 1. **Check Logs:** Review the full stack trace for more context
754
- 2. **Verify Configuration:** Ensure all properties are correctly set
755
- 3. **Dependencies:** Check if all required dependencies are included
756
- 4. **Version Compatibility:** Verify Spring Boot and dependency versions are compatible
757
-
758
- ## Recommended Actions
759
- 1. Enable debug logging: \`logging.level.org.springframework=DEBUG\`
760
- 2. Check Spring Boot documentation for the specific component
761
- 3. Search Spring Boot GitHub issues for similar problems
762
- 4. Consider posting on Stack Overflow with the full stack trace
763
-
764
- ${stackTrace ? `
765
- ## Stack Trace Analysis
766
- \`\`\`
767
- ${stackTrace.substring(0, 500)}${stackTrace.length > 500 ? '...' : ''}
768
- \`\`\`
769
- ` : ''}`;
770
- }
771
- getUpgradeRecommendation(version1, version2) {
772
- // Simplified version comparison logic
773
- const v1Major = parseInt(version1.split('.')[0]);
774
- const v2Major = parseInt(version2.split('.')[0]);
775
- if (v2Major > v1Major) {
776
- return `🚨 Major version upgrade detected. This may include breaking changes. Plan for thorough testing and potential code modifications.`;
777
- }
778
- else {
779
- return `✅ Minor/patch version upgrade. Generally safe to upgrade with minimal breaking changes expected.`;
780
- }
781
- }
782
- hashString(str) {
783
- let hash = 0;
784
- for (let i = 0; i < str.length; i++) {
785
- const char = str.charCodeAt(i);
786
- hash = ((hash << 5) - hash) + char;
787
- hash = hash & hash; // Convert to 32-bit integer
788
- }
789
- return Math.abs(hash).toString();
790
- }
791
- }
792
- //# sourceMappingURL=advanced-features-old.js.map