rapidkit 0.25.7 → 0.27.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.
- package/README.md +34 -5
- package/dist/{create-27NVMJAR.js → create-3V7O72CO.js} +20 -15
- package/dist/demo-kit-HMJZ3A3M.js +141 -0
- package/dist/doctor-JEBQTQQE.js +38 -0
- package/dist/index.js +188 -169
- package/dist/package.json +4 -2
- package/dist/springboot-standard-AGTOOTNT.js +697 -0
- package/dist/{workspace-VXNLNKCM.js → workspace-7JHX7L3E.js} +86 -68
- package/package.json +4 -2
- package/dist/demo-kit-63CFMCPD.js +0 -141
- package/dist/doctor-P57TTWEP.js +0 -38
|
@@ -0,0 +1,697 @@
|
|
|
1
|
+
import {b as b$1,c as c$1}from'./chunk-U7XJZHU6.js';import {b}from'./chunk-Q7ULIFQA.js';import {promises}from'fs';import c from'path';import n from'chalk';import R from'ora';import {execa}from'execa';var y="21",$="3.5.0",j="2.8.9";function u(e){return e.trim().toLowerCase().replace(/[^a-z0-9]+/g,".").replace(/^\.+|\.+$/g,"").replace(/\.{2,}/g,".").split(".").map(p=>p.replace(/^[^a-z]+/,"").replace(/[^a-z0-9]/g,"")).filter(Boolean).join(".")}function _(e,t){return e.replace(/[\r\n\t]+/g," ").trim()||t}function x(e){return e.trim().toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"").replace(/-{2,}/g,"-")}function M(e,t){let s=u(e)||"com.rapidkit.apps",p=u(t)||"service";return `${s}.${p}`}function E(e){return e.replace(/\./g,"/")}function T(){return JSON.stringify({engine:"npm",runtime:"java"},null,2)}function A(e,t){return JSON.stringify({kit_name:"springboot.standard",runtime:"java",module_support:false,project_name:e.project_name,artifact_id:e.artifact_id,group_id:e.group_id,package_name:e.package_name,app_version:e.app_version,created_by:"rapidkit-npm",rapidkit_version:t,created_at:new Date().toISOString()},null,2)}function P(e){return `<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
+
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
|
3
|
+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
|
4
|
+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
|
|
5
|
+
<modelVersion>4.0.0</modelVersion>
|
|
6
|
+
|
|
7
|
+
<parent>
|
|
8
|
+
<groupId>org.springframework.boot</groupId>
|
|
9
|
+
<artifactId>spring-boot-starter-parent</artifactId>
|
|
10
|
+
<version>${e.spring_boot_version}</version>
|
|
11
|
+
<relativePath/>
|
|
12
|
+
</parent>
|
|
13
|
+
|
|
14
|
+
<groupId>${e.group_id}</groupId>
|
|
15
|
+
<artifactId>${e.artifact_id}</artifactId>
|
|
16
|
+
<version>${e.app_version}</version>
|
|
17
|
+
<name>${e.project_name}</name>
|
|
18
|
+
<description>${e.description}</description>
|
|
19
|
+
|
|
20
|
+
<properties>
|
|
21
|
+
<java.version>${e.java_version}</java.version>
|
|
22
|
+
<springdoc.version>${e.springdoc_version}</springdoc.version>
|
|
23
|
+
<maven.compiler.release>${e.java_version}</maven.compiler.release>
|
|
24
|
+
</properties>
|
|
25
|
+
|
|
26
|
+
<dependencies>
|
|
27
|
+
<dependency>
|
|
28
|
+
<groupId>org.springframework.boot</groupId>
|
|
29
|
+
<artifactId>spring-boot-starter-web</artifactId>
|
|
30
|
+
</dependency>
|
|
31
|
+
<dependency>
|
|
32
|
+
<groupId>org.springframework.boot</groupId>
|
|
33
|
+
<artifactId>spring-boot-starter-actuator</artifactId>
|
|
34
|
+
</dependency>
|
|
35
|
+
<dependency>
|
|
36
|
+
<groupId>org.springframework.boot</groupId>
|
|
37
|
+
<artifactId>spring-boot-starter-validation</artifactId>
|
|
38
|
+
</dependency>
|
|
39
|
+
<dependency>
|
|
40
|
+
<groupId>org.springframework.boot</groupId>
|
|
41
|
+
<artifactId>spring-boot-configuration-processor</artifactId>
|
|
42
|
+
<optional>true</optional>
|
|
43
|
+
</dependency>
|
|
44
|
+
<dependency>
|
|
45
|
+
<groupId>org.springdoc</groupId>
|
|
46
|
+
<artifactId>springdoc-openapi-starter-webmvc-ui</artifactId>
|
|
47
|
+
<version>\${springdoc.version}</version>
|
|
48
|
+
</dependency>
|
|
49
|
+
<dependency>
|
|
50
|
+
<groupId>org.springframework.boot</groupId>
|
|
51
|
+
<artifactId>spring-boot-starter-test</artifactId>
|
|
52
|
+
<scope>test</scope>
|
|
53
|
+
</dependency>
|
|
54
|
+
</dependencies>
|
|
55
|
+
|
|
56
|
+
<build>
|
|
57
|
+
<plugins>
|
|
58
|
+
<plugin>
|
|
59
|
+
<groupId>org.springframework.boot</groupId>
|
|
60
|
+
<artifactId>spring-boot-maven-plugin</artifactId>
|
|
61
|
+
<configuration>
|
|
62
|
+
<layers>
|
|
63
|
+
<enabled>true</enabled>
|
|
64
|
+
</layers>
|
|
65
|
+
</configuration>
|
|
66
|
+
</plugin>
|
|
67
|
+
<plugin>
|
|
68
|
+
<groupId>org.apache.maven.plugins</groupId>
|
|
69
|
+
<artifactId>maven-compiler-plugin</artifactId>
|
|
70
|
+
<configuration>
|
|
71
|
+
<release>\${maven.compiler.release}</release>
|
|
72
|
+
</configuration>
|
|
73
|
+
</plugin>
|
|
74
|
+
<plugin>
|
|
75
|
+
<groupId>org.apache.maven.plugins</groupId>
|
|
76
|
+
<artifactId>maven-enforcer-plugin</artifactId>
|
|
77
|
+
<version>3.5.0</version>
|
|
78
|
+
<executions>
|
|
79
|
+
<execution>
|
|
80
|
+
<id>enforce-java-and-maven</id>
|
|
81
|
+
<goals>
|
|
82
|
+
<goal>enforce</goal>
|
|
83
|
+
</goals>
|
|
84
|
+
<configuration>
|
|
85
|
+
<rules>
|
|
86
|
+
<requireJavaVersion>
|
|
87
|
+
<version>[${e.java_version},)</version>
|
|
88
|
+
</requireJavaVersion>
|
|
89
|
+
<requireMavenVersion>
|
|
90
|
+
<version>[3.9.0,)</version>
|
|
91
|
+
</requireMavenVersion>
|
|
92
|
+
</rules>
|
|
93
|
+
</configuration>
|
|
94
|
+
</execution>
|
|
95
|
+
</executions>
|
|
96
|
+
</plugin>
|
|
97
|
+
<plugin>
|
|
98
|
+
<groupId>com.diffplug.spotless</groupId>
|
|
99
|
+
<artifactId>spotless-maven-plugin</artifactId>
|
|
100
|
+
<version>2.43.0</version>
|
|
101
|
+
<configuration>
|
|
102
|
+
<java>
|
|
103
|
+
<googleJavaFormat version="1.23.0" />
|
|
104
|
+
<trimTrailingWhitespace />
|
|
105
|
+
<endWithNewline />
|
|
106
|
+
</java>
|
|
107
|
+
</configuration>
|
|
108
|
+
</plugin>
|
|
109
|
+
<plugin>
|
|
110
|
+
<groupId>org.cyclonedx</groupId>
|
|
111
|
+
<artifactId>cyclonedx-maven-plugin</artifactId>
|
|
112
|
+
<version>2.8.1</version>
|
|
113
|
+
<executions>
|
|
114
|
+
<execution>
|
|
115
|
+
<phase>verify</phase>
|
|
116
|
+
<goals>
|
|
117
|
+
<goal>makeAggregateBom</goal>
|
|
118
|
+
</goals>
|
|
119
|
+
</execution>
|
|
120
|
+
</executions>
|
|
121
|
+
</plugin>
|
|
122
|
+
<plugin>
|
|
123
|
+
<groupId>org.owasp</groupId>
|
|
124
|
+
<artifactId>dependency-check-maven</artifactId>
|
|
125
|
+
<version>10.0.4</version>
|
|
126
|
+
<configuration>
|
|
127
|
+
<format>HTML</format>
|
|
128
|
+
<failBuildOnCVSS>9</failBuildOnCVSS>
|
|
129
|
+
</configuration>
|
|
130
|
+
</plugin>
|
|
131
|
+
</plugins>
|
|
132
|
+
</build>
|
|
133
|
+
</project>
|
|
134
|
+
`}function C(e,t){return `package ${e.package_name};
|
|
135
|
+
|
|
136
|
+
import ${e.package_name}.config.ApplicationInfoProperties;
|
|
137
|
+
import org.springframework.boot.SpringApplication;
|
|
138
|
+
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
|
139
|
+
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
|
140
|
+
|
|
141
|
+
@SpringBootApplication
|
|
142
|
+
@EnableConfigurationProperties(ApplicationInfoProperties.class)
|
|
143
|
+
public class ${t} {
|
|
144
|
+
|
|
145
|
+
public static void main(String[] args) {
|
|
146
|
+
SpringApplication.run(${t}.class, args);
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
`}function D(e){return `package ${e.package_name}.config;
|
|
150
|
+
|
|
151
|
+
import org.springframework.boot.context.properties.ConfigurationProperties;
|
|
152
|
+
|
|
153
|
+
@ConfigurationProperties(prefix = "rapidkit.application")
|
|
154
|
+
public record ApplicationInfoProperties(
|
|
155
|
+
String name,
|
|
156
|
+
String description,
|
|
157
|
+
String version,
|
|
158
|
+
String owner
|
|
159
|
+
) {}
|
|
160
|
+
`}function B(e){return `package ${e.package_name}.config;
|
|
161
|
+
|
|
162
|
+
import io.swagger.v3.oas.models.OpenAPI;
|
|
163
|
+
import io.swagger.v3.oas.models.info.Contact;
|
|
164
|
+
import io.swagger.v3.oas.models.info.Info;
|
|
165
|
+
import io.swagger.v3.oas.models.info.License;
|
|
166
|
+
import org.springframework.context.annotation.Bean;
|
|
167
|
+
import org.springframework.context.annotation.Configuration;
|
|
168
|
+
|
|
169
|
+
@Configuration
|
|
170
|
+
public class OpenApiConfiguration {
|
|
171
|
+
|
|
172
|
+
@Bean
|
|
173
|
+
OpenAPI rapidkitOpenApi(ApplicationInfoProperties properties) {
|
|
174
|
+
return new OpenAPI()
|
|
175
|
+
.info(new Info()
|
|
176
|
+
.title(properties.name())
|
|
177
|
+
.description(properties.description())
|
|
178
|
+
.version(properties.version())
|
|
179
|
+
.contact(new Contact().name(properties.owner()))
|
|
180
|
+
.license(new License().name("MIT")));
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
`}function V(e){return `package ${e.package_name}.api.http.dto;
|
|
184
|
+
|
|
185
|
+
import java.time.Instant;
|
|
186
|
+
import java.util.List;
|
|
187
|
+
|
|
188
|
+
public record SystemInfoResponse(
|
|
189
|
+
String name,
|
|
190
|
+
String version,
|
|
191
|
+
String environment,
|
|
192
|
+
String basePath,
|
|
193
|
+
List<String> profiles,
|
|
194
|
+
Instant timestamp
|
|
195
|
+
) {}
|
|
196
|
+
`}function O(e){return `package ${e.package_name}.application;
|
|
197
|
+
|
|
198
|
+
import ${e.package_name}.api.http.dto.SystemInfoResponse;
|
|
199
|
+
import ${e.package_name}.config.ApplicationInfoProperties;
|
|
200
|
+
import java.time.Instant;
|
|
201
|
+
import java.util.Arrays;
|
|
202
|
+
import java.util.List;
|
|
203
|
+
import org.springframework.beans.factory.annotation.Value;
|
|
204
|
+
import org.springframework.core.env.Environment;
|
|
205
|
+
import org.springframework.stereotype.Service;
|
|
206
|
+
|
|
207
|
+
@Service
|
|
208
|
+
public class SystemInfoService {
|
|
209
|
+
|
|
210
|
+
private final ApplicationInfoProperties properties;
|
|
211
|
+
private final Environment environment;
|
|
212
|
+
|
|
213
|
+
@Value("\${api.base-path:/api/v1}")
|
|
214
|
+
private String apiBasePath;
|
|
215
|
+
|
|
216
|
+
public SystemInfoService(ApplicationInfoProperties properties, Environment environment) {
|
|
217
|
+
this.properties = properties;
|
|
218
|
+
this.environment = environment;
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
public SystemInfoResponse snapshot() {
|
|
222
|
+
List<String> activeProfiles = Arrays.stream(environment.getActiveProfiles()).toList();
|
|
223
|
+
String runtimeEnv = activeProfiles.isEmpty() ? "default" : String.join(",", activeProfiles);
|
|
224
|
+
|
|
225
|
+
return new SystemInfoResponse(
|
|
226
|
+
properties.name(),
|
|
227
|
+
properties.version(),
|
|
228
|
+
runtimeEnv,
|
|
229
|
+
apiBasePath,
|
|
230
|
+
activeProfiles,
|
|
231
|
+
Instant.now()
|
|
232
|
+
);
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
`}function L(e){return `package ${e.package_name}.api.http;
|
|
236
|
+
|
|
237
|
+
import ${e.package_name}.api.http.dto.SystemInfoResponse;
|
|
238
|
+
import ${e.package_name}.application.SystemInfoService;
|
|
239
|
+
import io.swagger.v3.oas.annotations.Operation;
|
|
240
|
+
import io.swagger.v3.oas.annotations.tags.Tag;
|
|
241
|
+
import org.springframework.web.bind.annotation.GetMapping;
|
|
242
|
+
import org.springframework.web.bind.annotation.RequestMapping;
|
|
243
|
+
import org.springframework.web.bind.annotation.RestController;
|
|
244
|
+
|
|
245
|
+
@RestController
|
|
246
|
+
@RequestMapping("\${api.base-path:/api/v1}/system")
|
|
247
|
+
@Tag(name = "system", description = "Operational system endpoints")
|
|
248
|
+
public class SystemInfoController {
|
|
249
|
+
|
|
250
|
+
private final SystemInfoService systemInfoService;
|
|
251
|
+
|
|
252
|
+
public SystemInfoController(SystemInfoService systemInfoService) {
|
|
253
|
+
this.systemInfoService = systemInfoService;
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
@GetMapping("/info")
|
|
257
|
+
@Operation(summary = "Expose service metadata for diagnostics and platform wiring")
|
|
258
|
+
public SystemInfoResponse info() {
|
|
259
|
+
return systemInfoService.snapshot();
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
`}function q(e){return `package ${e.package_name}.api.http;
|
|
263
|
+
|
|
264
|
+
import java.time.Instant;
|
|
265
|
+
import java.util.Map;
|
|
266
|
+
import org.springframework.http.HttpStatus;
|
|
267
|
+
import org.springframework.http.ResponseEntity;
|
|
268
|
+
import org.springframework.web.bind.MethodArgumentNotValidException;
|
|
269
|
+
import org.springframework.web.bind.annotation.ExceptionHandler;
|
|
270
|
+
import org.springframework.web.bind.annotation.RestControllerAdvice;
|
|
271
|
+
|
|
272
|
+
@RestControllerAdvice
|
|
273
|
+
public class ApiExceptionHandler {
|
|
274
|
+
|
|
275
|
+
@ExceptionHandler(MethodArgumentNotValidException.class)
|
|
276
|
+
public ResponseEntity<Map<String, Object>> handleValidation(MethodArgumentNotValidException ex) {
|
|
277
|
+
return ResponseEntity.badRequest().body(Map.of(
|
|
278
|
+
"timestamp", Instant.now().toString(),
|
|
279
|
+
"status", HttpStatus.BAD_REQUEST.value(),
|
|
280
|
+
"error", "validation_failed",
|
|
281
|
+
"message", ex.getBindingResult().getErrorCount() + " validation error(s)"
|
|
282
|
+
));
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
@ExceptionHandler(Exception.class)
|
|
286
|
+
public ResponseEntity<Map<String, Object>> handleGeneric(Exception ex) {
|
|
287
|
+
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(Map.of(
|
|
288
|
+
"timestamp", Instant.now().toString(),
|
|
289
|
+
"status", HttpStatus.INTERNAL_SERVER_ERROR.value(),
|
|
290
|
+
"error", "internal_error",
|
|
291
|
+
"message", ex.getMessage() == null ? "Unexpected error" : ex.getMessage()
|
|
292
|
+
));
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
`}function N(e){return `server:
|
|
296
|
+
port: \${PORT:${e.port}}
|
|
297
|
+
shutdown: graceful
|
|
298
|
+
|
|
299
|
+
spring:
|
|
300
|
+
application:
|
|
301
|
+
name: ${e.artifact_id}
|
|
302
|
+
threads:
|
|
303
|
+
virtual:
|
|
304
|
+
enabled: true
|
|
305
|
+
|
|
306
|
+
management:
|
|
307
|
+
endpoints:
|
|
308
|
+
web:
|
|
309
|
+
exposure:
|
|
310
|
+
include: health,info,metrics
|
|
311
|
+
endpoint:
|
|
312
|
+
health:
|
|
313
|
+
probes:
|
|
314
|
+
enabled: true
|
|
315
|
+
info:
|
|
316
|
+
env:
|
|
317
|
+
enabled: true
|
|
318
|
+
|
|
319
|
+
springdoc:
|
|
320
|
+
api-docs:
|
|
321
|
+
path: /api-docs
|
|
322
|
+
swagger-ui:
|
|
323
|
+
path: /docs
|
|
324
|
+
|
|
325
|
+
api:
|
|
326
|
+
base-path: \${API_BASE_PATH:/api/v1}
|
|
327
|
+
|
|
328
|
+
rapidkit:
|
|
329
|
+
application:
|
|
330
|
+
name: ${e.project_name}
|
|
331
|
+
description: ${e.description}
|
|
332
|
+
version: ${e.app_version}
|
|
333
|
+
owner: ${e.author}
|
|
334
|
+
`}function J(){return `spring:
|
|
335
|
+
main:
|
|
336
|
+
banner-mode: off
|
|
337
|
+
|
|
338
|
+
management:
|
|
339
|
+
endpoints:
|
|
340
|
+
web:
|
|
341
|
+
exposure:
|
|
342
|
+
include: health,info
|
|
343
|
+
`}function W(e){return `PORT=${e.port}
|
|
344
|
+
SPRING_PROFILES_ACTIVE=local
|
|
345
|
+
API_BASE_PATH=/api/v1
|
|
346
|
+
JAVA_OPTS=-Xms256m -Xmx512m
|
|
347
|
+
`}function U(){return `FROM maven:3.9.9-eclipse-temurin-21 AS build
|
|
348
|
+
WORKDIR /workspace
|
|
349
|
+
|
|
350
|
+
COPY pom.xml ./
|
|
351
|
+
RUN mvn -B -q -DskipTests dependency:go-offline
|
|
352
|
+
|
|
353
|
+
COPY src ./src
|
|
354
|
+
RUN mvn -B -DskipTests package
|
|
355
|
+
|
|
356
|
+
FROM eclipse-temurin:21-jre
|
|
357
|
+
WORKDIR /app
|
|
358
|
+
|
|
359
|
+
COPY --from=build /workspace/target/*.jar /app/app.jar
|
|
360
|
+
|
|
361
|
+
EXPOSE 8080
|
|
362
|
+
ENV JAVA_OPTS=""
|
|
363
|
+
|
|
364
|
+
ENTRYPOINT ["sh", "-c", "java $JAVA_OPTS -jar /app/app.jar"]
|
|
365
|
+
`}function G(e){return `services:
|
|
366
|
+
${e.artifact_id}:
|
|
367
|
+
build:
|
|
368
|
+
context: .
|
|
369
|
+
dockerfile: Dockerfile
|
|
370
|
+
ports:
|
|
371
|
+
- "${e.port}:8080"
|
|
372
|
+
env_file:
|
|
373
|
+
- .env
|
|
374
|
+
environment:
|
|
375
|
+
SPRING_PROFILES_ACTIVE: docker
|
|
376
|
+
`}function H(){return `target
|
|
377
|
+
.git
|
|
378
|
+
.idea
|
|
379
|
+
.vscode
|
|
380
|
+
node_modules
|
|
381
|
+
coverage
|
|
382
|
+
`}function F(){return `.idea/
|
|
383
|
+
.vscode/
|
|
384
|
+
target/
|
|
385
|
+
.mvn/
|
|
386
|
+
*.log
|
|
387
|
+
.DS_Store
|
|
388
|
+
.env
|
|
389
|
+
`}function z(){return `root = true
|
|
390
|
+
|
|
391
|
+
[*]
|
|
392
|
+
charset = utf-8
|
|
393
|
+
end_of_line = lf
|
|
394
|
+
indent_style = space
|
|
395
|
+
indent_size = 4
|
|
396
|
+
insert_final_newline = true
|
|
397
|
+
trim_trailing_whitespace = true
|
|
398
|
+
|
|
399
|
+
[*.md]
|
|
400
|
+
trim_trailing_whitespace = false
|
|
401
|
+
`}function K(e){return ["name: ci","","on:"," push:"," branches: [main]"," pull_request:","","jobs:"," build-test-e2e:"," runs-on: ${{ matrix.os }}"," strategy:"," fail-fast: false"," matrix:"," os: [ubuntu-latest, windows-latest]",` java: ['${e.java_version}', '22']`," steps:"," - uses: actions/checkout@v4"," - uses: actions/setup-java@v4"," with:"," distribution: temurin"," java-version: ${{ matrix.java }}"," cache: maven"," - name: Generate Maven Wrapper (Unix)"," if: runner.os != 'Windows'"," run: |"," if [ ! -f mvnw ]; then"," mvn -N wrapper:wrapper -Dmaven=3.9.9"," chmod +x mvnw"," fi"," - name: Generate Maven Wrapper (Windows)"," if: runner.os == 'Windows'"," shell: pwsh"," run: |"," if (-not (Test-Path 'mvnw.cmd')) {"," mvn -N wrapper:wrapper -Dmaven=3.9.9"," }"," - name: Verify (Unix)"," if: runner.os != 'Windows'"," run: ./mvnw -B verify"," - name: Verify (Windows)"," if: runner.os == 'Windows'"," run: .\\mvnw.cmd -B verify"," - name: Package (Unix)"," if: runner.os != 'Windows'"," run: ./mvnw -B -DskipTests package"," - name: Package (Windows)"," if: runner.os == 'Windows'"," run: .\\mvnw.cmd -B -DskipTests package"," - name: Security scan (Unix)"," if: runner.os != 'Windows'"," run: ./mvnw -B -DskipTests org.owasp:dependency-check-maven:check -DfailBuildOnCVSS=9"," - name: Security scan (Windows)"," if: runner.os == 'Windows'"," run: .\\mvnw.cmd -B -DskipTests org.owasp:dependency-check-maven:check -DfailBuildOnCVSS=9"," - name: Upload SCA report"," if: always()"," uses: actions/upload-artifact@v4"," with:"," name: dependency-check-report-${{ matrix.os }}-${{ matrix.java }}"," path: target/dependency-check-report.html"," if-no-files-found: ignore"," - name: Upload SBOM"," if: always()"," uses: actions/upload-artifact@v4"," with:"," name: sbom-${{ matrix.os }}-${{ matrix.java }}"," path: target/bom.xml"," if-no-files-found: ignore",""].join(`
|
|
402
|
+
`)}function Y(e){return `# ${e.project_name}
|
|
403
|
+
|
|
404
|
+
Built with Spring Boot and scaffolded by RapidKit.
|
|
405
|
+
|
|
406
|
+
## Stack
|
|
407
|
+
|
|
408
|
+
- Java ${e.java_version}
|
|
409
|
+
- Spring Boot ${e.spring_boot_version}
|
|
410
|
+
- Maven
|
|
411
|
+
- Spring Actuator
|
|
412
|
+
- springdoc OpenAPI
|
|
413
|
+
|
|
414
|
+
## Endpoints
|
|
415
|
+
|
|
416
|
+
- GET /actuator/health
|
|
417
|
+
- GET /api/v1/system/info
|
|
418
|
+
- GET /docs
|
|
419
|
+
|
|
420
|
+
## Quick Start
|
|
421
|
+
|
|
422
|
+
\`\`\`bash
|
|
423
|
+
mvn spring-boot:run
|
|
424
|
+
\`\`\`
|
|
425
|
+
|
|
426
|
+
Or use the generated launcher:
|
|
427
|
+
|
|
428
|
+
\`\`\`bash
|
|
429
|
+
./rapidkit init
|
|
430
|
+
./rapidkit dev
|
|
431
|
+
\`\`\`
|
|
432
|
+
|
|
433
|
+
## Commands
|
|
434
|
+
|
|
435
|
+
\`\`\`bash
|
|
436
|
+
mvn test
|
|
437
|
+
mvn -DskipTests package
|
|
438
|
+
docker compose up --build
|
|
439
|
+
./scripts/perf-smoke.sh
|
|
440
|
+
\`\`\`
|
|
441
|
+
|
|
442
|
+
## Project Structure
|
|
443
|
+
|
|
444
|
+
\`\`\`
|
|
445
|
+
src/main/java/.../api/http # Controllers + HTTP DTOs
|
|
446
|
+
src/main/java/.../application # Application services
|
|
447
|
+
src/main/java/.../config # OpenAPI + app properties
|
|
448
|
+
src/main/resources # Spring configuration
|
|
449
|
+
\`\`\`
|
|
450
|
+
|
|
451
|
+
## Notes
|
|
452
|
+
|
|
453
|
+
- This kit is npm-level and intentionally independent from rapidkit-core modules.
|
|
454
|
+
- Use environment variables for deployment concerns; Spring Boot maps them automatically.
|
|
455
|
+
- CI runs matrix build/test + dependency scan + SBOM artifact generation by default.
|
|
456
|
+
`}function X(e){return `#!/usr/bin/env sh
|
|
457
|
+
set -eu
|
|
458
|
+
|
|
459
|
+
PORT="${e.port}"
|
|
460
|
+
LOG_FILE="./.rapidkit/perf-smoke.log"
|
|
461
|
+
|
|
462
|
+
mkdir -p ./.rapidkit
|
|
463
|
+
|
|
464
|
+
echo "[perf] Building service..."
|
|
465
|
+
./rapidkit build >/dev/null
|
|
466
|
+
|
|
467
|
+
echo "[perf] Measuring startup latency and max RSS..."
|
|
468
|
+
START_EPOCH=$(date +%s)
|
|
469
|
+
/usr/bin/time -f "max_rss_kb=%M" -o "$LOG_FILE" ./rapidkit start >/tmp/rapidkit-perf-app.log 2>&1 &
|
|
470
|
+
APP_PID=$!
|
|
471
|
+
|
|
472
|
+
cleanup() {
|
|
473
|
+
kill "$APP_PID" >/dev/null 2>&1 || true
|
|
474
|
+
}
|
|
475
|
+
trap cleanup EXIT
|
|
476
|
+
|
|
477
|
+
for _ in $(seq 1 45); do
|
|
478
|
+
if curl -fsS "http://127.0.0.1:${e.port}/actuator/health" >/dev/null 2>&1; then
|
|
479
|
+
break
|
|
480
|
+
fi
|
|
481
|
+
sleep 1
|
|
482
|
+
done
|
|
483
|
+
|
|
484
|
+
READY_EPOCH=$(date +%s)
|
|
485
|
+
echo "startup_seconds=$((READY_EPOCH - START_EPOCH))" >> "$LOG_FILE"
|
|
486
|
+
cat "$LOG_FILE"
|
|
487
|
+
`}function Q(e){return `#!/usr/bin/env sh
|
|
488
|
+
# RapidKit Spring Boot project launcher - generated by RapidKit CLI
|
|
489
|
+
|
|
490
|
+
SCRIPT_DIR=$(CDPATH= cd -- "$(dirname -- "$0")" && pwd)
|
|
491
|
+
CMD="\${1:-}"
|
|
492
|
+
shift 2>/dev/null || true
|
|
493
|
+
|
|
494
|
+
maven_cmd() {
|
|
495
|
+
if [ -x "$SCRIPT_DIR/mvnw" ]; then
|
|
496
|
+
echo "$SCRIPT_DIR/mvnw"
|
|
497
|
+
return 0
|
|
498
|
+
fi
|
|
499
|
+
if command -v mvn >/dev/null 2>&1; then
|
|
500
|
+
echo mvn
|
|
501
|
+
return 0
|
|
502
|
+
fi
|
|
503
|
+
return 1
|
|
504
|
+
}
|
|
505
|
+
|
|
506
|
+
jar_path() {
|
|
507
|
+
find "$SCRIPT_DIR/target" -maxdepth 1 -type f -name '*.jar' ! -name '*-sources.jar' ! -name '*-javadoc.jar' | head -n 1
|
|
508
|
+
}
|
|
509
|
+
|
|
510
|
+
case "$CMD" in
|
|
511
|
+
init)
|
|
512
|
+
cd "$SCRIPT_DIR"
|
|
513
|
+
if [ ! -f ".env" ] && [ -f ".env.example" ]; then
|
|
514
|
+
cp .env.example .env && echo "\u2713 .env created from .env.example"
|
|
515
|
+
fi
|
|
516
|
+
MVN_CMD=$(maven_cmd) || {
|
|
517
|
+
echo "rapidkit: Maven or Maven Wrapper is required" >&2
|
|
518
|
+
exit 1
|
|
519
|
+
}
|
|
520
|
+
exec "$MVN_CMD" -B -q -DskipTests dependency:go-offline
|
|
521
|
+
;;
|
|
522
|
+
dev)
|
|
523
|
+
cd "$SCRIPT_DIR"
|
|
524
|
+
MVN_CMD=$(maven_cmd) || {
|
|
525
|
+
echo "rapidkit: Maven or Maven Wrapper is required" >&2
|
|
526
|
+
exit 1
|
|
527
|
+
}
|
|
528
|
+
exec "$MVN_CMD" spring-boot:run "$@"
|
|
529
|
+
;;
|
|
530
|
+
test)
|
|
531
|
+
cd "$SCRIPT_DIR"
|
|
532
|
+
MVN_CMD=$(maven_cmd) || {
|
|
533
|
+
echo "rapidkit: Maven or Maven Wrapper is required" >&2
|
|
534
|
+
exit 1
|
|
535
|
+
}
|
|
536
|
+
exec "$MVN_CMD" test "$@"
|
|
537
|
+
;;
|
|
538
|
+
build)
|
|
539
|
+
cd "$SCRIPT_DIR"
|
|
540
|
+
MVN_CMD=$(maven_cmd) || {
|
|
541
|
+
echo "rapidkit: Maven or Maven Wrapper is required" >&2
|
|
542
|
+
exit 1
|
|
543
|
+
}
|
|
544
|
+
exec "$MVN_CMD" -DskipTests package "$@"
|
|
545
|
+
;;
|
|
546
|
+
start)
|
|
547
|
+
cd "$SCRIPT_DIR"
|
|
548
|
+
JAR=$(jar_path)
|
|
549
|
+
if [ -z "$JAR" ]; then
|
|
550
|
+
MVN_CMD=$(maven_cmd) || {
|
|
551
|
+
echo "rapidkit: Maven or Maven Wrapper is required" >&2
|
|
552
|
+
exit 1
|
|
553
|
+
}
|
|
554
|
+
"$MVN_CMD" -DskipTests package || exit $?
|
|
555
|
+
JAR=$(jar_path)
|
|
556
|
+
fi
|
|
557
|
+
exec java $JAVA_OPTS -jar "$JAR" "$@"
|
|
558
|
+
;;
|
|
559
|
+
help|--help|-h)
|
|
560
|
+
echo "RapidKit - Spring Boot project: ${e.project_name}"
|
|
561
|
+
echo ""
|
|
562
|
+
echo "Available: init, dev, test, build, start"
|
|
563
|
+
;;
|
|
564
|
+
*)
|
|
565
|
+
if [ -n "$CMD" ]; then
|
|
566
|
+
echo "rapidkit: unknown command: $CMD" >&2
|
|
567
|
+
fi
|
|
568
|
+
echo "Available: init, dev, test, build, start" >&2
|
|
569
|
+
exit 1
|
|
570
|
+
;;
|
|
571
|
+
esac
|
|
572
|
+
`}function Z(){return `@echo off
|
|
573
|
+
set CMD=%1
|
|
574
|
+
if "%CMD%"=="" goto usage
|
|
575
|
+
shift
|
|
576
|
+
|
|
577
|
+
set BUILD_CMD=mvn
|
|
578
|
+
if exist mvnw.cmd set BUILD_CMD=mvnw.cmd
|
|
579
|
+
|
|
580
|
+
if "%CMD%"=="init" (
|
|
581
|
+
if not exist .env if exist .env.example copy .env.example .env >nul
|
|
582
|
+
%BUILD_CMD% -B -q -DskipTests dependency:go-offline
|
|
583
|
+
exit /b %ERRORLEVEL%
|
|
584
|
+
)
|
|
585
|
+
if "%CMD%"=="dev" (
|
|
586
|
+
%BUILD_CMD% spring-boot:run %*
|
|
587
|
+
exit /b %ERRORLEVEL%
|
|
588
|
+
)
|
|
589
|
+
if "%CMD%"=="test" (
|
|
590
|
+
%BUILD_CMD% test %*
|
|
591
|
+
exit /b %ERRORLEVEL%
|
|
592
|
+
)
|
|
593
|
+
if "%CMD%"=="build" (
|
|
594
|
+
%BUILD_CMD% -DskipTests package %*
|
|
595
|
+
exit /b %ERRORLEVEL%
|
|
596
|
+
)
|
|
597
|
+
if "%CMD%"=="start" (
|
|
598
|
+
for %%f in (target*.jar) do set APP_JAR=%%f
|
|
599
|
+
if not defined APP_JAR %BUILD_CMD% -DskipTests package
|
|
600
|
+
for %%f in (target*.jar) do set APP_JAR=%%f
|
|
601
|
+
java %JAVA_OPTS% -jar %APP_JAR% %*
|
|
602
|
+
exit /b %ERRORLEVEL%
|
|
603
|
+
)
|
|
604
|
+
|
|
605
|
+
:usage
|
|
606
|
+
echo Available: init, dev, test, build, start
|
|
607
|
+
exit /b 1
|
|
608
|
+
`}function ee(e,t){return `package ${e.package_name};
|
|
609
|
+
|
|
610
|
+
import org.junit.jupiter.api.Test;
|
|
611
|
+
import org.springframework.boot.test.context.SpringBootTest;
|
|
612
|
+
|
|
613
|
+
@SpringBootTest
|
|
614
|
+
class ${t}Tests {
|
|
615
|
+
|
|
616
|
+
@Test
|
|
617
|
+
void contextLoads() {
|
|
618
|
+
}
|
|
619
|
+
}
|
|
620
|
+
`}function te(e){return `package ${e.package_name}.api.http;
|
|
621
|
+
|
|
622
|
+
import static org.mockito.BDDMockito.given;
|
|
623
|
+
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
|
|
624
|
+
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
|
|
625
|
+
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
|
626
|
+
|
|
627
|
+
import ${e.package_name}.api.http.dto.SystemInfoResponse;
|
|
628
|
+
import ${e.package_name}.application.SystemInfoService;
|
|
629
|
+
import java.time.Instant;
|
|
630
|
+
import java.util.List;
|
|
631
|
+
import org.junit.jupiter.api.Test;
|
|
632
|
+
import org.springframework.beans.factory.annotation.Autowired;
|
|
633
|
+
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
|
|
634
|
+
import org.springframework.boot.test.mock.mockito.MockBean;
|
|
635
|
+
import org.springframework.context.annotation.Import;
|
|
636
|
+
import org.springframework.test.web.servlet.MockMvc;
|
|
637
|
+
|
|
638
|
+
@WebMvcTest(SystemInfoController.class)
|
|
639
|
+
@Import(ApiExceptionHandler.class)
|
|
640
|
+
class SystemInfoControllerTest {
|
|
641
|
+
|
|
642
|
+
@Autowired
|
|
643
|
+
private MockMvc mockMvc;
|
|
644
|
+
|
|
645
|
+
@MockBean
|
|
646
|
+
private SystemInfoService systemInfoService;
|
|
647
|
+
|
|
648
|
+
@Test
|
|
649
|
+
void returnsSystemInfo() throws Exception {
|
|
650
|
+
given(systemInfoService.snapshot()).willReturn(new SystemInfoResponse(
|
|
651
|
+
"${e.project_name}",
|
|
652
|
+
"${e.app_version}",
|
|
653
|
+
"test",
|
|
654
|
+
"/api/v1",
|
|
655
|
+
List.of("test"),
|
|
656
|
+
Instant.parse("2026-01-01T00:00:00Z")
|
|
657
|
+
));
|
|
658
|
+
|
|
659
|
+
mockMvc.perform(get("/api/v1/system/info"))
|
|
660
|
+
.andExpect(status().isOk())
|
|
661
|
+
.andExpect(jsonPath("$.name").value("${e.project_name}"))
|
|
662
|
+
.andExpect(jsonPath("$.version").value("${e.app_version}"))
|
|
663
|
+
.andExpect(jsonPath("$.environment").value("test"));
|
|
664
|
+
}
|
|
665
|
+
}
|
|
666
|
+
`}function ie(e){return `package ${e.package_name};
|
|
667
|
+
|
|
668
|
+
import static org.assertj.core.api.Assertions.assertThat;
|
|
669
|
+
|
|
670
|
+
import java.util.Map;
|
|
671
|
+
import org.junit.jupiter.api.Test;
|
|
672
|
+
import org.springframework.beans.factory.annotation.Autowired;
|
|
673
|
+
import org.springframework.boot.test.context.SpringBootTest;
|
|
674
|
+
import org.springframework.boot.test.web.client.TestRestTemplate;
|
|
675
|
+
import org.springframework.http.ResponseEntity;
|
|
676
|
+
|
|
677
|
+
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
|
|
678
|
+
class ServiceRuntimeE2ETest {
|
|
679
|
+
|
|
680
|
+
@Autowired
|
|
681
|
+
private TestRestTemplate restTemplate;
|
|
682
|
+
|
|
683
|
+
@Test
|
|
684
|
+
void healthEndpointShouldBeUp() {
|
|
685
|
+
ResponseEntity<Map> response = restTemplate.getForEntity("/actuator/health", Map.class);
|
|
686
|
+
assertThat(response.getStatusCode().is2xxSuccessful()).isTrue();
|
|
687
|
+
assertThat(response.getBody()).containsEntry("status", "UP");
|
|
688
|
+
}
|
|
689
|
+
}
|
|
690
|
+
`}async function re(e){try{await execa("mvn",["-N","wrapper:wrapper","-Dmaven=3.9.9"],{cwd:e,timeout:12e4});let t=c.join(e,"mvnw");return await promises.stat(t).then(()=>true).catch(()=>false)&&await promises.chmod(t,493),true}catch{return false}}async function ue(e,t){let s=x(t.artifact_id||t.project_name)||"service",p=u(t.group_id||"com.rapidkit.apps")||"com.rapidkit.apps",h=u(t.package_name||M(p,s))||"com.rapidkit.apps.service",r={project_name:t.project_name,artifact_id:s,group_id:p,package_name:h,author:_(t.author||"","RapidKit User"),description:_(t.description||"",`Spring Boot service generated with RapidKit - ${t.project_name}`),java_version:t.java_version||y,spring_boot_version:t.spring_boot_version||$,springdoc_version:t.springdoc_version||j,app_version:t.app_version||"0.1.0",port:t.port||"8080",skipGit:t.skipGit??false},I=b(),d=`${b$1(r.project_name)}Application`,a=E(r.package_name);try{await execa("mvn",["-version"],{timeout:3e3});}catch{console.log(n.yellow(`
|
|
691
|
+
\u26A0 Maven not found in PATH - project will be scaffolded, but init/build commands require Maven 3.9+`)),console.log(n.gray(` Install: https://maven.apache.org/install.html
|
|
692
|
+
`));}let m=R(`Generating Spring Boot project: ${r.project_name}...`).start();try{let i=(l,f)=>c$1(c.join(e,l),f),S=c.join(e,"rapidkit"),b=c.join(e,"rapidkit.cmd");await Promise.all([i("pom.xml",P(r)),i(".gitignore",F()),i(".editorconfig",z()),i(".env.example",W(r)),i(".dockerignore",H()),i("Dockerfile",U()),i("docker-compose.yml",G(r)),i(".github/workflows/ci.yml",K(r)),i("README.md",Y(r)),i("src/main/resources/application.yml",N(r)),i("src/test/resources/application.yml",J()),i(`src/main/java/${a}/${d}.java`,C(r,d)),i(`src/main/java/${a}/config/ApplicationInfoProperties.java`,D(r)),i(`src/main/java/${a}/config/OpenApiConfiguration.java`,B(r)),i(`src/main/java/${a}/application/SystemInfoService.java`,O(r)),i(`src/main/java/${a}/api/http/dto/SystemInfoResponse.java`,V(r)),i(`src/main/java/${a}/api/http/SystemInfoController.java`,L(r)),i(`src/main/java/${a}/api/http/ApiExceptionHandler.java`,q(r)),i(`src/test/java/${a}/${d}Tests.java`,ee(r,d)),i(`src/test/java/${a}/api/http/SystemInfoControllerTest.java`,te(r)),i(`src/test/java/${a}/ServiceRuntimeE2ETest.java`,ie(r)),i("scripts/perf-smoke.sh",X(r)),i(".rapidkit/project.json",A(r,I)),i(".rapidkit/context.json",T()),i("rapidkit",Q(r)),i("rapidkit.cmd",Z())]),await promises.chmod(S,493),await promises.chmod(b,493),await promises.chmod(c.join(e,"scripts","perf-smoke.sh"),493),await re(e)||console.log(n.yellow("\u26A0 Maven Wrapper could not be generated automatically. Run `mvn -N wrapper:wrapper -Dmaven=3.9.9` inside the project.")),m.succeed(n.green(`Project created at ${e}`));try{m.start("Resolving Maven dependencies...");let l=c.join(e,process.platform==="win32"?"mvnw.cmd":"mvnw"),f=await promises.stat(l).then(()=>l).catch(()=>"mvn");await execa(f,["-B","-q","-DskipTests","dependency:go-offline"],{cwd:e,timeout:18e4}),m.succeed(n.gray("\u2713 maven dependency warm-up completed"));}catch{m.warn(n.yellow("\u26A0 Maven dependency warm-up failed - run manually: mvn -B -DskipTests dependency:go-offline"));}if(!r.skipGit)try{await execa("git",["init"],{cwd:e}),await execa("git",["add","-A"],{cwd:e}),await execa("git",["commit","-m","chore: initial scaffold (rapidkit springboot.standard)"],{cwd:e});}catch{console.log(n.yellow("\u26A0 Git initialization failed - continuing without initial commit"));}console.log(n.green(`
|
|
693
|
+
\u2728 Spring Boot project created successfully!
|
|
694
|
+
`)),console.log(n.cyan("\u{1F4C2} Location:"),n.white(e)),console.log(n.cyan(`
|
|
695
|
+
\u{1F680} Get started:
|
|
696
|
+
`)),console.log(n.white(` cd ${r.project_name}`)),console.log(n.white(" ./rapidkit init")),console.log(n.white(` ./rapidkit dev
|
|
697
|
+
`)),console.log(n.gray("Endpoints: /actuator/health, /api/v1/system/info, /docs"));}catch(i){m.fail("Failed to create Spring Boot project");try{await promises.rm(e,{recursive:true,force:true});}catch{}throw i}}export{y as DEFAULT_JAVA_VERSION,j as DEFAULT_SPRINGDOC_VERSION,$ as DEFAULT_SPRING_BOOT_VERSION,ue as generateSpringBootKit};
|