generator-jhipster 6.10.1 → 6.10.5
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 +16 -112
- package/cli/jdl.js +1 -1
- package/generators/client/templates/angular/package.json.ejs +1 -1
- package/generators/client/templates/react/package.json.ejs +1 -1
- package/generators/docker-utils.js +1 -1
- package/generators/entity-client/templates/angular/src/main/webapp/app/entities/entity-management-update.component.ts.ejs +1 -1
- package/generators/generator-constants.js +2 -2
- package/generators/openapi-client/prompts.js +24 -28
- package/generators/server/templates/src/main/java/package/web/rest/UserResource.java.ejs +24 -0
- package/generators/server/templates/src/main/java/package/web/rest/errors/ExceptionTranslator.java.ejs +79 -1
- package/generators/server/templates/src/test/java/package/RedisTestContainerExtension.java.ejs +5 -10
- package/generators/server/templates/src/test/java/package/web/rest/AccountResourceIT.java.ejs +1 -1
- package/generators/server/templates/src/test/java/package/web/rest/UserResourceIT.java.ejs +24 -1
- package/package.json +4 -4
package/README.md
CHANGED
|
@@ -12,7 +12,7 @@ Please read our [guidelines](/CONTRIBUTING.md#submitting-an-issue) before submit
|
|
|
12
12
|
|
|
13
13
|
## Contributing
|
|
14
14
|
|
|
15
|
-
We are honoured by any contributions you may have small or large. Please refer to our [contribution guidelines and instructions document](https://github.com/jhipster/generator-jhipster/blob/
|
|
15
|
+
We are honoured by any contributions you may have small or large. Please refer to our [contribution guidelines and instructions document](https://github.com/jhipster/generator-jhipster/blob/main/CONTRIBUTING.md) for any information about contributing to the project.
|
|
16
16
|
|
|
17
17
|
## Sponsors
|
|
18
18
|
|
|
@@ -35,119 +35,27 @@ Support this project by becoming a sponsor! [Become a sponsor](https://opencolle
|
|
|
35
35
|
<img width="200em" src="https://www.jhipster.tech/images/open-collective/octoconsulting.png">
|
|
36
36
|
</a>
|
|
37
37
|
</td>
|
|
38
|
-
</tr>
|
|
39
|
-
</tbody>
|
|
40
|
-
</table>
|
|
41
|
-
|
|
42
|
-
### Bronze sponsors
|
|
43
|
-
|
|
44
|
-
<table>
|
|
45
|
-
<tbody>
|
|
46
|
-
<tr>
|
|
47
|
-
<td align="center" valign="middle">
|
|
48
|
-
<a href="https://forsyslab.com/" target="_blank">
|
|
49
|
-
<img width="50em" src="https://www.jhipster.tech/images/open-collective/forsyslab.png">
|
|
50
|
-
</a>
|
|
51
|
-
</td>
|
|
52
|
-
<td align="center" valign="middle">
|
|
53
|
-
<a href="https://www.cuba-platform.com/" target="_blank">
|
|
54
|
-
<img width="50em" src="https://www.jhipster.tech/images/open-collective/cubaplatform.png">
|
|
55
|
-
</a>
|
|
56
|
-
</td>
|
|
57
|
-
<td align="center" valign="middle">
|
|
58
|
-
<a href="https://www.codefirst.co.uk" target="_blank">
|
|
59
|
-
<img width="50em" src="https://www.jhipster.tech/images/open-collective/codefirst.png">
|
|
60
|
-
</a>
|
|
61
|
-
</td>
|
|
62
38
|
<td align="center" valign="middle">
|
|
63
|
-
<a href="https://
|
|
64
|
-
<img width="
|
|
65
|
-
</a>
|
|
66
|
-
</td>
|
|
67
|
-
<td align="center" valign="middle">
|
|
68
|
-
<a href="https://clay.global/" target="_blank">
|
|
69
|
-
<img width="50em" src="https://www.jhipster.tech/images/open-collective/clay.png">
|
|
70
|
-
</a>
|
|
71
|
-
</td>
|
|
72
|
-
</tr>
|
|
73
|
-
<tr>
|
|
74
|
-
<td align="center" valign="middle">
|
|
75
|
-
<a href="https://uxplanet.org/" target="_blank">
|
|
76
|
-
<img width="50em" src="https://www.jhipster.tech/images/open-collective/uxplanet.png">
|
|
77
|
-
</a>
|
|
78
|
-
</td>
|
|
79
|
-
<td align="center" valign="middle">
|
|
80
|
-
<a href="https://opencollective.com/top-web-design-agencies" target="_blank">
|
|
81
|
-
<img width="50em" src="https://www.jhipster.tech/images/open-collective/top-web-design-agencies.png">
|
|
82
|
-
</a>
|
|
83
|
-
</td>
|
|
84
|
-
<td align="center" valign="middle">
|
|
85
|
-
<a href="https://fair-laan.se/" target="_blank">
|
|
86
|
-
<img width="50em" src="https://www.jhipster.tech/images/open-collective/fair-laan.png">
|
|
87
|
-
</a>
|
|
88
|
-
</td>
|
|
89
|
-
<td align="center" valign="middle">
|
|
90
|
-
<a href="https://superkredit.net" target="_blank">
|
|
91
|
-
<img width="50em" src="https://www.jhipster.tech/images/open-collective/superkredit.png">
|
|
92
|
-
</a>
|
|
93
|
-
</td>
|
|
94
|
-
<td align="center" valign="middle">
|
|
95
|
-
<a href="https://matchbanker.pl/" target="_blank">
|
|
96
|
-
<img width="50em" src="https://www.jhipster.tech/images/open-collective/matchbanker.png">
|
|
97
|
-
</a>
|
|
98
|
-
</td>
|
|
99
|
-
</tr>
|
|
100
|
-
<tr>
|
|
101
|
-
<td align="center" valign="middle">
|
|
102
|
-
<a href="https://matchbanker.no/" target="_blank">
|
|
103
|
-
<img width="50em" src="https://www.jhipster.tech/images/open-collective/matchbanker.png">
|
|
104
|
-
</a>
|
|
105
|
-
</td>
|
|
106
|
-
<td align="center" valign="middle">
|
|
107
|
-
<a href="https://www.banksecrets.eu/" target="_blank">
|
|
108
|
-
<img width="50em" src="https://www.jhipster.tech/images/open-collective/banksecrets.png">
|
|
109
|
-
</a>
|
|
110
|
-
</td>
|
|
111
|
-
<td align="center" valign="middle">
|
|
112
|
-
<a href="https://writersperhour.com/urgent-essay-writing-service" target="_blank">
|
|
113
|
-
<img width="50em" src="https://www.jhipster.tech/images/open-collective/writersperhour.png">
|
|
114
|
-
</a>
|
|
115
|
-
</td>
|
|
116
|
-
<td align="center" valign="middle">
|
|
117
|
-
<a href="https://www.minitool.com/" target="_blank">
|
|
118
|
-
<img width="50em" src="https://www.jhipster.tech/images/open-collective/minitool.png">
|
|
119
|
-
</a>
|
|
120
|
-
</td>
|
|
121
|
-
<td align="center" valign="middle">
|
|
122
|
-
<a href="https://unscramblex.com/" target="_blank">
|
|
123
|
-
<img width="50em" src="https://www.jhipster.tech/images/open-collective/unscramblex.png">
|
|
124
|
-
</a>
|
|
125
|
-
</td>
|
|
126
|
-
</tr>
|
|
127
|
-
<tr>
|
|
128
|
-
<td align="center" valign="middle">
|
|
129
|
-
<a href="https://edubirdie.com/" target="_blank">
|
|
130
|
-
<img width="50em" src="https://www.jhipster.tech/images/open-collective/edubirdie.png">
|
|
131
|
-
</a>
|
|
132
|
-
</td>
|
|
133
|
-
<td align="center" valign="middle">
|
|
134
|
-
<a href="https://www.zadluzenia.com/" target="_blank">
|
|
135
|
-
<img width="50em" src="https://www.jhipster.tech/images/open-collective/zadluzenia.png">
|
|
136
|
-
</a>
|
|
137
|
-
</td>
|
|
138
|
-
<td align="center" valign="middle">
|
|
139
|
-
<a href="https://opencollective.com/jim-van-dam" target="_blank">
|
|
140
|
-
<img width="50em" src="https://www.jhipster.tech/images/open-collective/jim-van-dam.png">
|
|
39
|
+
<a href="https://dev.entando.org/jhipster" target="_blank">
|
|
40
|
+
<img width="200em" src="https://www.jhipster.tech/images/open-collective/entandoe.png">
|
|
141
41
|
</a>
|
|
142
42
|
</td>
|
|
143
43
|
</tr>
|
|
144
44
|
</tbody>
|
|
145
45
|
</table>
|
|
146
46
|
|
|
47
|
+
### Bronze sponsors
|
|
48
|
+
|
|
49
|
+
[![BronzeSponsors][bronze-sponsors-image]][bronze-sponsors-url]
|
|
50
|
+
|
|
51
|
+
### Backers
|
|
52
|
+
|
|
147
53
|
**Thank you to all our backers!**
|
|
148
54
|
|
|
149
55
|
[![Backers][backers-image]][backers-url]
|
|
150
56
|
|
|
57
|
+
<object data="https://opencollective.com/generator-jhipster/tiers/backer.svg?avatarHeight=40&width=890&button=false" type="image/svg+xml"></object>
|
|
58
|
+
|
|
151
59
|
## Azure Builds
|
|
152
60
|
|
|
153
61
|
Additional builds at [hipster-labs/jhipster-daily-builds](https://github.com/hipster-labs/jhipster-daily-builds)
|
|
@@ -164,14 +72,11 @@ Additional builds at [hipster-labs/jhipster-daily-builds](https://github.com/hip
|
|
|
164
72
|
| [![React Gradle NoSQL][github-react-gradle-nosql]][github-actions] |
|
|
165
73
|
| [![Elasticsearch][github-elasticsearch]][github-actions] |
|
|
166
74
|
| [![Monolith OAuth2][github-monolith-oauth2]][github-actions] |
|
|
167
|
-
| [![Yarn][github-yarn]][github-actions] |
|
|
168
75
|
| [![No Database][github-no-database]][github-actions] |
|
|
169
76
|
| [![Microservices JWT][github-ms-jwt]][github-actions] |
|
|
170
77
|
| [![Microservices OAuth2][github-ms-oauth2]][github-actions] |
|
|
171
78
|
| [![Microservices UAA][github-ms-uaa]][github-actions] |
|
|
172
79
|
| [![Docker Image][github-docker-image]][github-actions] |
|
|
173
|
-
| [![Neo4j][github-neo4j]][github-actions] |
|
|
174
|
-
| [![Couchbase][github-couchbase]][github-actions] |
|
|
175
80
|
| [![Official Windows][github-official-windows]][github-actions] |
|
|
176
81
|
|
|
177
82
|
## Analysis of the sample JHipster project
|
|
@@ -190,32 +95,31 @@ Additional builds at [hipster-labs/jhipster-daily-builds](https://github.com/hip
|
|
|
190
95
|
[github-react-gradle-nosql]: https://github.com/hipster-labs/jhipster-daily-builds/workflows/React%20Gradle%20NoSQL/badge.svg
|
|
191
96
|
[github-elasticsearch]: https://github.com/hipster-labs/jhipster-daily-builds/workflows/Elasticsearch/badge.svg
|
|
192
97
|
[github-monolith-oauth2]: https://github.com/hipster-labs/jhipster-daily-builds/workflows/Monolith%20OAuth2/badge.svg
|
|
193
|
-
[github-yarn]: https://github.com/hipster-labs/jhipster-daily-builds/workflows/Yarn/badge.svg
|
|
194
98
|
[github-no-database]: https://github.com/hipster-labs/jhipster-daily-builds/workflows/No%20Database/badge.svg
|
|
195
99
|
[github-ms-jwt]: https://github.com/hipster-labs/jhipster-daily-builds/workflows/Microservices%20JWT/badge.svg
|
|
196
100
|
[github-ms-oauth2]: https://github.com/hipster-labs/jhipster-daily-builds/workflows/Microservices%20OAuth2/badge.svg
|
|
197
101
|
[github-ms-uaa]: https://github.com/hipster-labs/jhipster-daily-builds/workflows/Microservices%20UAA/badge.svg
|
|
198
102
|
[github-docker-image]: https://github.com/hipster-labs/jhipster-daily-builds/workflows/Docker%20Image/badge.svg
|
|
199
|
-
[github-neo4j]: https://github.com/hipster-labs/jhipster-daily-builds/workflows/Neo4j/badge.svg
|
|
200
|
-
[github-couchbase]: https://github.com/hipster-labs/jhipster-daily-builds/workflows/Couchbase/badge.svg
|
|
201
103
|
[sonar-url]: https://sonarcloud.io/dashboard?id=jhipster-sample-application
|
|
202
104
|
[sonar-quality-gate]: https://sonarcloud.io/api/project_badges/measure?project=jhipster-sample-application&metric=alert_status
|
|
203
105
|
[sonar-coverage]: https://sonarcloud.io/api/project_badges/measure?project=jhipster-sample-application&metric=coverage
|
|
204
106
|
[sonar-bugs]: https://sonarcloud.io/api/project_badges/measure?project=jhipster-sample-application&metric=bugs
|
|
205
107
|
[sonar-vulnerabilities]: https://sonarcloud.io/api/project_badges/measure?project=jhipster-sample-application&metric=vulnerabilities
|
|
206
|
-
[jhipster-image]: https://raw.githubusercontent.com/jhipster/jhipster-artwork/
|
|
108
|
+
[jhipster-image]: https://raw.githubusercontent.com/jhipster/jhipster-artwork/main/logos/JHipster%20RGB-small100x25px.png
|
|
207
109
|
[jhipster-url]: https://www.jhipster.tech/
|
|
208
110
|
[npm-image]: https://badge.fury.io/js/generator-jhipster.svg
|
|
209
111
|
[npm-url]: https://npmjs.org/package/generator-jhipster
|
|
210
|
-
[azure-devops-image]: https://dev.azure.com/jhipster/generator-jhipster/_apis/build/status/jhipster.generator-jhipster?branchName=
|
|
112
|
+
[azure-devops-image]: https://dev.azure.com/jhipster/generator-jhipster/_apis/build/status/jhipster.generator-jhipster?branchName=main
|
|
211
113
|
[azure-devops-url-main]: https://dev.azure.com/jhipster/generator-jhipster/_build
|
|
212
114
|
[github-actions-generator-image]: https://github.com/jhipster/generator-jhipster/workflows/Generator/badge.svg
|
|
213
115
|
[github-actions-angular-image]: https://github.com/jhipster/generator-jhipster/workflows/Angular/badge.svg
|
|
214
116
|
[github-actions-react-image]: https://github.com/jhipster/generator-jhipster/workflows/React/badge.svg
|
|
215
117
|
[github-actions-webflux-image]: https://github.com/jhipster/generator-jhipster/workflows/Webflux/badge.svg
|
|
216
118
|
[github-actions-url]: https://github.com/jhipster/generator-jhipster/actions
|
|
217
|
-
[backers-image]: https://opencollective.com/generator-jhipster/tiers/backer.svg?avatarHeight=
|
|
119
|
+
[backers-image]: https://opencollective.com/generator-jhipster/tiers/backer.svg?avatarHeight=70&width=890
|
|
218
120
|
[backers-url]: https://opencollective.com/generator-jhipster
|
|
121
|
+
[bronze-sponsors-image]: https://opencollective.com/generator-jhipster/tiers/bronze-sponsor.svg?avatarHeight=120&width=890
|
|
122
|
+
[bronze-sponsors-url]: https://opencollective.com/generator-jhipster
|
|
219
123
|
[issue-template]: https://github.com/jhipster/generator-jhipster/issues/new?template=BUG_REPORT.md
|
|
220
124
|
[feature-template]: https://github.com/jhipster/generator-jhipster/issues/new?template=FEATURE_REQUEST.md
|
|
221
125
|
[npmcharts-image]: https://img.shields.io/npm/dm/generator-jhipster.svg?label=Downloads&style=flat
|
package/cli/jdl.js
CHANGED
|
@@ -83,7 +83,7 @@ module.exports = (args, options = {}, env, forkProcess) => {
|
|
|
83
83
|
if (options.skipSampleRepository) {
|
|
84
84
|
return Promise.reject(new Error(`Could not find ${filename}, make sure the path is correct.`));
|
|
85
85
|
}
|
|
86
|
-
url = new URL(filename, 'https://raw.githubusercontent.com/jhipster/jdl-samples/
|
|
86
|
+
url = new URL(filename, 'https://raw.githubusercontent.com/jhipster/jdl-samples/main/').toString();
|
|
87
87
|
filename = path.basename(filename);
|
|
88
88
|
}
|
|
89
89
|
return downloadFile(url, filename);
|
|
@@ -88,7 +88,7 @@ function checkImageExist(opts = { cwd: './', appConfig: null }) {
|
|
|
88
88
|
this.dockerBuildCommand = './mvnw -ntp -Pprod verify jib:dockerBuild';
|
|
89
89
|
} else {
|
|
90
90
|
imagePath = this.destinationPath(`${opts.cwd + opts.cwd}/build/docker`);
|
|
91
|
-
this.dockerBuildCommand = './gradlew
|
|
91
|
+
this.dockerBuildCommand = './gradlew bootJar -Pprod jibDockerBuild';
|
|
92
92
|
}
|
|
93
93
|
|
|
94
94
|
if (shelljs.ls(imagePath).length === 0) {
|
|
@@ -237,7 +237,7 @@ _%>
|
|
|
237
237
|
this.dataUtils.openFile(contentType, base64String);
|
|
238
238
|
}
|
|
239
239
|
|
|
240
|
-
setFileData(event:
|
|
240
|
+
setFileData(event: any, field: string, isImage: boolean): void {
|
|
241
241
|
this.dataUtils.loadFileToForm(event, this.editForm, field, isImage).subscribe(null, (err: JhiFileLoadError) => {
|
|
242
242
|
this.eventManager.broadcast(
|
|
243
243
|
new JhiEventWithContent<AlertError>('<%= angularAppName %>.error', { <% if (enableTranslation) { %>...err, key: 'error.file.' + err.key<% } else { %>message: err.message<% } %> })
|
|
@@ -31,7 +31,7 @@ const GRADLE_VERSION = '6.5';
|
|
|
31
31
|
const JIB_VERSION = '2.4.0';
|
|
32
32
|
|
|
33
33
|
// Libraries version
|
|
34
|
-
const JHIPSTER_DEPENDENCIES_VERSION = '3.9.
|
|
34
|
+
const JHIPSTER_DEPENDENCIES_VERSION = '3.9.1';
|
|
35
35
|
// The spring-boot version should match the one managed by https://mvnrepository.com/artifact/io.github.jhipster/jhipster-dependencies/JHIPSTER_DEPENDENCIES_VERSION
|
|
36
36
|
const SPRING_BOOT_VERSION = '2.2.7.RELEASE';
|
|
37
37
|
const LIQUIBASE_VERSION = '3.9.0';
|
|
@@ -77,7 +77,7 @@ const DOCKER_JHIPSTER_IMPORT_DASHBOARDS = 'jhipster/jhipster-import-dashboards:v
|
|
|
77
77
|
const DOCKER_JHIPSTER_ZIPKIN = 'jhipster/jhipster-zipkin:v4.1.0';
|
|
78
78
|
const DOCKER_TRAEFIK = 'traefik:1.7.24'; // waiting for https://github.com/jhipster/generator-jhipster/issues/11198
|
|
79
79
|
const DOCKER_CONSUL = 'consul:1.7.3';
|
|
80
|
-
const DOCKER_CONSUL_CONFIG_LOADER = 'jhipster/consul-config-loader:v0.
|
|
80
|
+
const DOCKER_CONSUL_CONFIG_LOADER = 'jhipster/consul-config-loader:v0.4.1';
|
|
81
81
|
const DOCKER_PROMETHEUS = 'prom/prometheus:v2.18.1';
|
|
82
82
|
const DOCKER_PROMETHEUS_ALERTMANAGER = 'prom/alertmanager:v0.20.0';
|
|
83
83
|
const DOCKER_GRAFANA = 'grafana/grafana:7.0.1';
|
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
*/
|
|
19
19
|
const path = require('path');
|
|
20
20
|
const shelljs = require('shelljs');
|
|
21
|
-
const request = require('
|
|
21
|
+
const request = require('then-request');
|
|
22
22
|
|
|
23
23
|
module.exports = {
|
|
24
24
|
askActionType,
|
|
@@ -26,11 +26,11 @@ module.exports = {
|
|
|
26
26
|
askGenerationInfos,
|
|
27
27
|
};
|
|
28
28
|
|
|
29
|
-
function fetchSwaggerResources(input) {
|
|
29
|
+
async function fetchSwaggerResources(input) {
|
|
30
30
|
const availableDocs = [];
|
|
31
31
|
|
|
32
32
|
const baseUrl = input.replace(/\/$/, '');
|
|
33
|
-
const swaggerResources = request('GET', `${baseUrl}/swagger-resources`, {
|
|
33
|
+
const swaggerResources = await request('GET', `${baseUrl}/swagger-resources`, {
|
|
34
34
|
// This header is needed to use the custom /swagger-resources controller
|
|
35
35
|
// and not the default one that has only the gateway's swagger resource
|
|
36
36
|
headers: { Accept: 'application/json, text/javascript;' },
|
|
@@ -49,11 +49,9 @@ function fetchSwaggerResources(input) {
|
|
|
49
49
|
|
|
50
50
|
function askActionType() {
|
|
51
51
|
if (this.options.regen) {
|
|
52
|
-
return;
|
|
52
|
+
return undefined;
|
|
53
53
|
}
|
|
54
54
|
|
|
55
|
-
const done = this.async();
|
|
56
|
-
|
|
57
55
|
const hasExistingApis = Object.keys(this.openApiClients).length !== 0;
|
|
58
56
|
|
|
59
57
|
const actionList = [
|
|
@@ -95,9 +93,9 @@ function askActionType() {
|
|
|
95
93
|
name: 'jhipsterEndpoint',
|
|
96
94
|
message: 'Enter the URL of the running Jhipster instance',
|
|
97
95
|
default: 'http://localhost:8080',
|
|
98
|
-
validate: input => {
|
|
96
|
+
validate: async input => {
|
|
99
97
|
try {
|
|
100
|
-
const availableDocs = fetchSwaggerResources(input);
|
|
98
|
+
const availableDocs = await fetchSwaggerResources(input);
|
|
101
99
|
|
|
102
100
|
if (availableDocs.length === 0) {
|
|
103
101
|
return `No live doc found at ${input}`;
|
|
@@ -135,10 +133,10 @@ function askActionType() {
|
|
|
135
133
|
message: 'Where is your Swagger/OpenAPI spec (URL or path) ?',
|
|
136
134
|
default: 'http://petstore.swagger.io/v2/swagger.json',
|
|
137
135
|
store: true,
|
|
138
|
-
validate: input => {
|
|
136
|
+
validate: async input => {
|
|
139
137
|
try {
|
|
140
138
|
if (/^((http|https):\/\/)/.test(input)) {
|
|
141
|
-
request('GET', `${input}`, {
|
|
139
|
+
await request('GET', `${input}`, {
|
|
142
140
|
// headers: { Accept: 'application/json, text/javascript;' }
|
|
143
141
|
});
|
|
144
142
|
} else if (!shelljs.test('-f', input)) {
|
|
@@ -152,15 +150,7 @@ function askActionType() {
|
|
|
152
150
|
},
|
|
153
151
|
];
|
|
154
152
|
|
|
155
|
-
this.prompt(prompts).then(props => {
|
|
156
|
-
if (props.jhipsterEndpoint !== undefined) {
|
|
157
|
-
props.availableDocs = fetchSwaggerResources(props.jhipsterEndpoint);
|
|
158
|
-
} else if (props.jhipsterDirectory !== undefined) {
|
|
159
|
-
props.inputSpec = `${props.jhipsterDirectory}/src/main/resources/swagger/api.yml`;
|
|
160
|
-
} else if (props.customEndpoint !== undefined) {
|
|
161
|
-
props.inputSpec = props.customEndpoint;
|
|
162
|
-
}
|
|
163
|
-
|
|
153
|
+
return this.prompt(prompts).then(props => {
|
|
164
154
|
if (newClient) {
|
|
165
155
|
props.action = 'new';
|
|
166
156
|
}
|
|
@@ -168,15 +158,24 @@ function askActionType() {
|
|
|
168
158
|
props.generatorName = this.config.get('reactive') ? 'java' : 'spring';
|
|
169
159
|
|
|
170
160
|
this.props = props;
|
|
171
|
-
|
|
161
|
+
if (props.jhipsterEndpoint !== undefined) {
|
|
162
|
+
return fetchSwaggerResources(props.jhipsterEndpoint).then(availableDocs => {
|
|
163
|
+
props.availableDocs = availableDocs;
|
|
164
|
+
});
|
|
165
|
+
}
|
|
166
|
+
if (props.jhipsterDirectory !== undefined) {
|
|
167
|
+
props.inputSpec = `${props.jhipsterDirectory}/src/main/resources/swagger/api.yml`;
|
|
168
|
+
} else if (props.customEndpoint !== undefined) {
|
|
169
|
+
props.inputSpec = props.customEndpoint;
|
|
170
|
+
}
|
|
171
|
+
return undefined;
|
|
172
172
|
});
|
|
173
173
|
}
|
|
174
174
|
|
|
175
175
|
function askExistingAvailableDocs() {
|
|
176
176
|
if (this.options.regen) {
|
|
177
|
-
return;
|
|
177
|
+
return undefined;
|
|
178
178
|
}
|
|
179
|
-
const done = this.async();
|
|
180
179
|
|
|
181
180
|
const prompts = [
|
|
182
181
|
{
|
|
@@ -188,21 +187,19 @@ function askExistingAvailableDocs() {
|
|
|
188
187
|
},
|
|
189
188
|
];
|
|
190
189
|
|
|
191
|
-
this.prompt(prompts).then(props => {
|
|
190
|
+
return this.prompt(prompts).then(props => {
|
|
192
191
|
if (props.availableDoc !== undefined) {
|
|
193
192
|
this.props.inputSpec = props.availableDoc.url;
|
|
194
193
|
this.props.cliName = props.availableDoc.name === 'default' ? 'apidocs' : props.availableDoc.name; // "default" cannot be used as it's a keyword in java
|
|
195
194
|
}
|
|
196
|
-
done();
|
|
197
195
|
});
|
|
198
196
|
}
|
|
199
197
|
|
|
200
198
|
function askGenerationInfos() {
|
|
201
199
|
if (this.options.regen) {
|
|
202
|
-
return;
|
|
200
|
+
return undefined;
|
|
203
201
|
}
|
|
204
202
|
|
|
205
|
-
const done = this.async();
|
|
206
203
|
const prompts = [
|
|
207
204
|
{
|
|
208
205
|
when:
|
|
@@ -255,12 +252,11 @@ function askGenerationInfos() {
|
|
|
255
252
|
},
|
|
256
253
|
];
|
|
257
254
|
|
|
258
|
-
this.prompt(prompts).then(props => {
|
|
255
|
+
return this.prompt(prompts).then(props => {
|
|
259
256
|
if (props.cliName !== undefined) {
|
|
260
257
|
this.props.cliName = props.cliName;
|
|
261
258
|
}
|
|
262
259
|
this.props.saveConfig = props.saveConfig;
|
|
263
260
|
this.props.selected = props.selected;
|
|
264
|
-
done();
|
|
265
261
|
});
|
|
266
262
|
}
|
|
@@ -31,6 +31,8 @@ import <%= packageName %>.repository.search.UserSearchRepository;
|
|
|
31
31
|
import <%= packageName %>.security.AuthoritiesConstants;
|
|
32
32
|
<%_ if (authenticationType !== 'oauth2') { _%>
|
|
33
33
|
import <%= packageName %>.service.MailService;
|
|
34
|
+
import org.springframework.data.domain.Sort;
|
|
35
|
+
import java.util.Collections;
|
|
34
36
|
<%_ } _%>
|
|
35
37
|
import <%= packageName %>.service.UserService;
|
|
36
38
|
import <%= packageName %>.service.dto.<%= asDto('User') %>;
|
|
@@ -90,6 +92,7 @@ import java.util.*;
|
|
|
90
92
|
<%_ if (reactive) { _%>
|
|
91
93
|
import java.util.ArrayList;
|
|
92
94
|
import java.util.List;
|
|
95
|
+
import java.util.Arrays;
|
|
93
96
|
<%_ } _%>
|
|
94
97
|
<%_ if (searchEngine === 'elasticsearch' && !reactive) { _%>
|
|
95
98
|
import java.util.stream.Collectors;
|
|
@@ -125,6 +128,9 @@ import static org.elasticsearch.index.query.QueryBuilders.*;
|
|
|
125
128
|
@RestController
|
|
126
129
|
@RequestMapping("/api")
|
|
127
130
|
public class UserResource {
|
|
131
|
+
<%_ if (authenticationType !== 'oauth2') { _%>
|
|
132
|
+
private static final List<String> ALLOWED_ORDERED_PROPERTIES = Collections.unmodifiableList(Arrays.asList("id", "login", "firstName", "lastName", "email", "activated", "langKey"));
|
|
133
|
+
<%_ } _%>
|
|
128
134
|
|
|
129
135
|
private final Logger log = LoggerFactory.getLogger(UserResource.class);
|
|
130
136
|
|
|
@@ -286,11 +292,23 @@ public class UserResource {
|
|
|
286
292
|
<%_ if (databaseType === 'sql' || databaseType === 'mongodb' || databaseType === 'neo4j' || databaseType === 'couchbase') { _%>
|
|
287
293
|
<%_ if (!reactive) { _%>
|
|
288
294
|
public ResponseEntity<List<<%= asDto('User') %>>> getAllUsers(Pageable pageable) {
|
|
295
|
+
<%_ if (authenticationType !== 'oauth2') { _%>
|
|
296
|
+
if (!onlyContainsAllowedProperties(pageable)) {
|
|
297
|
+
return ResponseEntity.badRequest().build();
|
|
298
|
+
}
|
|
299
|
+
<%_ } _%>
|
|
300
|
+
|
|
289
301
|
final Page<<%= asDto('User') %>> page = userService.getAllManagedUsers(pageable);
|
|
290
302
|
HttpHeaders headers = PaginationUtil.generatePaginationHttpHeaders(ServletUriComponentsBuilder.fromCurrentRequest(), page);
|
|
291
303
|
return new ResponseEntity<>(page.getContent(), headers, HttpStatus.OK);
|
|
292
304
|
<%_ } else { _%>
|
|
293
305
|
public Mono<ResponseEntity<Flux<<%= asDto('User') %>>>> getAllUsers(ServerHttpRequest request, Pageable pageable) {
|
|
306
|
+
<%_ if (authenticationType !== 'oauth2') { _%>
|
|
307
|
+
if (!onlyContainsAllowedProperties(pageable)) {
|
|
308
|
+
return Mono.just(ResponseEntity.badRequest().build());
|
|
309
|
+
}
|
|
310
|
+
<%_ } _%>
|
|
311
|
+
|
|
294
312
|
return userService.countManagedUsers()
|
|
295
313
|
.map(total -> new PageImpl<>(new ArrayList<>(), pageable, total))
|
|
296
314
|
.map(page -> PaginationUtil.generatePaginationHttpHeaders(UriComponentsBuilder.fromHttpRequest(request), page))
|
|
@@ -298,6 +316,12 @@ public class UserResource {
|
|
|
298
316
|
<%_ } _%>
|
|
299
317
|
}
|
|
300
318
|
|
|
319
|
+
<%_ if (authenticationType !== 'oauth2') { _%>
|
|
320
|
+
private boolean onlyContainsAllowedProperties(Pageable pageable) {
|
|
321
|
+
return pageable.getSort().stream().map(Sort.Order::getProperty).allMatch(ALLOWED_ORDERED_PROPERTIES::contains);
|
|
322
|
+
}
|
|
323
|
+
<%_ } _%>
|
|
324
|
+
|
|
301
325
|
/**
|
|
302
326
|
* Gets a list of all roles.
|
|
303
327
|
* @return a string list of all roles.
|
|
@@ -18,13 +18,19 @@
|
|
|
18
18
|
-%>
|
|
19
19
|
package <%= packageName %>.web.rest.errors;
|
|
20
20
|
|
|
21
|
+
import io.github.jhipster.config.JHipsterConstants;
|
|
21
22
|
import io.github.jhipster.web.util.HeaderUtil;
|
|
22
23
|
|
|
24
|
+
import org.apache.commons.lang3.StringUtils;
|
|
23
25
|
import org.springframework.beans.factory.annotation.Value;
|
|
24
26
|
<%_ if (databaseType !== 'no' && databaseType !== 'cassandra') { _%>
|
|
25
27
|
import org.springframework.dao.ConcurrencyFailureException;
|
|
26
28
|
<%_ } _%>
|
|
29
|
+
<%_ if (databaseType !== 'no') { _%>
|
|
30
|
+
import org.springframework.dao.DataAccessException;
|
|
31
|
+
<%_ } _%>
|
|
27
32
|
import org.springframework.http.ResponseEntity;
|
|
33
|
+
import org.springframework.http.converter.HttpMessageConversionException;
|
|
28
34
|
<%_ if (reactive && databaseType === 'sql') { _%>
|
|
29
35
|
import org.springframework.stereotype.Component;
|
|
30
36
|
<%_ } _%>
|
|
@@ -41,10 +47,12 @@ import org.springframework.web.server.ServerWebExchange;
|
|
|
41
47
|
<%_ if (!reactive) { _%>
|
|
42
48
|
import org.springframework.web.context.request.NativeWebRequest;
|
|
43
49
|
<%_ } _%>
|
|
50
|
+
import org.springframework.core.env.Environment;
|
|
44
51
|
import org.zalando.problem.DefaultProblem;
|
|
45
52
|
import org.zalando.problem.Problem;
|
|
46
53
|
import org.zalando.problem.ProblemBuilder;
|
|
47
54
|
import org.zalando.problem.Status;
|
|
55
|
+
import org.zalando.problem.StatusType;
|
|
48
56
|
import org.zalando.problem.spring.web<% if (reactive) { %>flux<% } %>.advice.ProblemHandling;
|
|
49
57
|
import org.zalando.problem.spring.web<% if (reactive) { %>flux<% } %>.advice.security.SecurityAdviceTrait;
|
|
50
58
|
import org.zalando.problem.violations.ConstraintViolationProblem;
|
|
@@ -57,7 +65,11 @@ import javax.annotation.Nullable;
|
|
|
57
65
|
<%_ if (!reactive) { _%>
|
|
58
66
|
import javax.servlet.http.HttpServletRequest;
|
|
59
67
|
<%_ } _%>
|
|
68
|
+
import java.net.URI;
|
|
69
|
+
import java.util.Arrays;
|
|
70
|
+
import java.util.Collection;
|
|
60
71
|
import java.util.List;
|
|
72
|
+
import java.util.Optional;
|
|
61
73
|
import java.util.stream.Collectors;
|
|
62
74
|
|
|
63
75
|
/**
|
|
@@ -89,6 +101,12 @@ _%>
|
|
|
89
101
|
@Value("${jhipster.clientApp.name}")
|
|
90
102
|
private String applicationName;
|
|
91
103
|
|
|
104
|
+
private final Environment env;
|
|
105
|
+
|
|
106
|
+
public ExceptionTranslator(Environment env) {
|
|
107
|
+
this.env = env;
|
|
108
|
+
}
|
|
109
|
+
|
|
92
110
|
/**
|
|
93
111
|
* Post-process the Problem payload to add the message key for the front-end if needed.
|
|
94
112
|
*/
|
|
@@ -187,4 +205,64 @@ _%>
|
|
|
187
205
|
return create(ex, problem, request);
|
|
188
206
|
}
|
|
189
207
|
<%_ } _%>
|
|
190
|
-
|
|
208
|
+
|
|
209
|
+
@Override
|
|
210
|
+
public ProblemBuilder prepare(final Throwable throwable, final StatusType status, final URI type) {
|
|
211
|
+
|
|
212
|
+
Collection<String> activeProfiles = Arrays.asList(env.getActiveProfiles());
|
|
213
|
+
|
|
214
|
+
if (activeProfiles.contains(JHipsterConstants.SPRING_PROFILE_PRODUCTION)) {
|
|
215
|
+
if (throwable instanceof HttpMessageConversionException) {
|
|
216
|
+
return Problem.builder()
|
|
217
|
+
.withType(type)
|
|
218
|
+
.withTitle(status.getReasonPhrase())
|
|
219
|
+
.withStatus(status)
|
|
220
|
+
.withDetail("Unable to convert http message")
|
|
221
|
+
.withCause(Optional.ofNullable(throwable.getCause())
|
|
222
|
+
.filter(cause -> isCausalChainsEnabled())
|
|
223
|
+
.map(this::toProblem)
|
|
224
|
+
.orElse(null));
|
|
225
|
+
}
|
|
226
|
+
<%_ if (databaseType !== 'no') { _%>
|
|
227
|
+
if (throwable instanceof DataAccessException) {
|
|
228
|
+
return Problem.builder()
|
|
229
|
+
.withType(type)
|
|
230
|
+
.withTitle(status.getReasonPhrase())
|
|
231
|
+
.withStatus(status)
|
|
232
|
+
.withDetail("Failure during data access")
|
|
233
|
+
.withCause(Optional.ofNullable(throwable.getCause())
|
|
234
|
+
.filter(cause -> isCausalChainsEnabled())
|
|
235
|
+
.map(this::toProblem)
|
|
236
|
+
.orElse(null));
|
|
237
|
+
}
|
|
238
|
+
<%_ } _%>
|
|
239
|
+
if (containsPackageName(throwable.getMessage())) {
|
|
240
|
+
return Problem.builder()
|
|
241
|
+
.withType(type)
|
|
242
|
+
.withTitle(status.getReasonPhrase())
|
|
243
|
+
.withStatus(status)
|
|
244
|
+
.withDetail("Unexpected runtime exception")
|
|
245
|
+
.withCause(Optional.ofNullable(throwable.getCause())
|
|
246
|
+
.filter(cause -> isCausalChainsEnabled())
|
|
247
|
+
.map(this::toProblem)
|
|
248
|
+
.orElse(null));
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
return Problem.builder()
|
|
253
|
+
.withType(type)
|
|
254
|
+
.withTitle(status.getReasonPhrase())
|
|
255
|
+
.withStatus(status)
|
|
256
|
+
.withDetail(throwable.getMessage())
|
|
257
|
+
.withCause(Optional.ofNullable(throwable.getCause())
|
|
258
|
+
.filter(cause -> isCausalChainsEnabled())
|
|
259
|
+
.map(this::toProblem)
|
|
260
|
+
.orElse(null));
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
private boolean containsPackageName(String message) {
|
|
264
|
+
|
|
265
|
+
// This list is for sure not complete
|
|
266
|
+
return StringUtils.containsAny(message, "org.", "java.", "net.", "javax.", "com.", "io.", "de.", "<%= packageName %>");
|
|
267
|
+
}
|
|
268
|
+
}
|
package/generators/server/templates/src/test/java/package/RedisTestContainerExtension.java.ejs
CHANGED
|
@@ -16,13 +16,10 @@
|
|
|
16
16
|
See the License for the specific language governing permissions and
|
|
17
17
|
limitations under the License.
|
|
18
18
|
-%>
|
|
19
|
-
|
|
20
19
|
package <%= packageName %>;
|
|
21
20
|
|
|
22
21
|
import org.junit.jupiter.api.extension.BeforeAllCallback;
|
|
23
22
|
import org.junit.jupiter.api.extension.ExtensionContext;
|
|
24
|
-
import org.springframework.test.context.DynamicPropertyRegistry;
|
|
25
|
-
import org.springframework.test.context.DynamicPropertySource;
|
|
26
23
|
import org.testcontainers.containers.GenericContainer;
|
|
27
24
|
|
|
28
25
|
import java.util.concurrent.atomic.AtomicBoolean;
|
|
@@ -31,18 +28,16 @@ public class RedisTestContainerExtension implements BeforeAllCallback {
|
|
|
31
28
|
|
|
32
29
|
private static AtomicBoolean started = new AtomicBoolean(false);
|
|
33
30
|
|
|
34
|
-
private static GenericContainer redis;
|
|
35
|
-
|
|
36
|
-
@DynamicPropertySource
|
|
37
|
-
static void redisProperties(DynamicPropertyRegistry registry) {
|
|
38
|
-
registry.add("jhipster.cache.redis.server", () -> "redis://" + redis.getContainerIpAddress() + ":" + redis.getMappedPort(6379));
|
|
39
|
-
}
|
|
31
|
+
private static GenericContainer redis = new GenericContainer("<%= DOCKER_REDIS %>").withExposedPorts(6379);
|
|
40
32
|
|
|
41
33
|
@Override
|
|
42
34
|
public void beforeAll(ExtensionContext extensionContext) throws Exception {
|
|
43
35
|
if (!started.get()) {
|
|
44
|
-
redis = new GenericContainer("<%= DOCKER_REDIS %>").withExposedPorts(6379);
|
|
45
36
|
redis.start();
|
|
37
|
+
System.setProperty(
|
|
38
|
+
"jhipster.cache.redis.server",
|
|
39
|
+
"redis://" + redis.getContainerIpAddress() + ":" + redis.getMappedPort(6379)
|
|
40
|
+
);
|
|
46
41
|
started.set(true);
|
|
47
42
|
}
|
|
48
43
|
}
|
package/generators/server/templates/src/test/java/package/web/rest/AccountResourceIT.java.ejs
CHANGED
|
@@ -35,7 +35,7 @@ import <%= packageName %>.service.UserService;
|
|
|
35
35
|
|
|
36
36
|
import org.junit.jupiter.api.BeforeEach;
|
|
37
37
|
import org.junit.jupiter.api.Test;
|
|
38
|
-
<%_ if (databaseType === 'neo4j') { _%>
|
|
38
|
+
<%_ if (databaseType === 'neo4j' || cacheProvider === 'redis') { _%>
|
|
39
39
|
import org.junit.jupiter.api.extension.ExtendWith;
|
|
40
40
|
<%_ } _%>
|
|
41
41
|
import org.springframework.beans.factory.annotation.Autowired;
|
|
@@ -504,7 +504,7 @@ public class UserResourceIT <% if (databaseType === 'cassandra') { %>extends Abs
|
|
|
504
504
|
<%_ } _%>
|
|
505
505
|
.andExpect(jsonPath("$.[*].langKey").value(hasItem(DEFAULT_LANGKEY)));
|
|
506
506
|
<%_ } else { _%>
|
|
507
|
-
<%= asDto('User') %> foundUser = webTestClient.get().uri("/api/users?sort=
|
|
507
|
+
<%= asDto('User') %> foundUser = webTestClient.get().uri("/api/users?sort=id,DESC")
|
|
508
508
|
.accept(MediaType.APPLICATION_JSON)
|
|
509
509
|
.exchange()
|
|
510
510
|
.expectStatus().isOk()
|
|
@@ -522,6 +522,29 @@ public class UserResourceIT <% if (databaseType === 'cassandra') { %>extends Abs
|
|
|
522
522
|
<%_ } _%>
|
|
523
523
|
}
|
|
524
524
|
|
|
525
|
+
<%_ if (databaseType === 'sql' && authenticationType !== 'oauth2') { _%>
|
|
526
|
+
@Test
|
|
527
|
+
<%_ if (!reactive) { _%>
|
|
528
|
+
@Transactional
|
|
529
|
+
<%_ } _%>
|
|
530
|
+
void getAllUsersSortedByParameters() throws Exception {
|
|
531
|
+
// Initialize the database
|
|
532
|
+
userRepository.<% if (reactive) { %>save<% } else { %>saveAndFlush<% } %>(user)<% if (reactive) { %>.block()<% } %>;
|
|
533
|
+
|
|
534
|
+
<%_ if (!reactive) { _%>
|
|
535
|
+
restUserMockMvc.perform(get("/api/users?sort=resetKey,desc").accept(MediaType.APPLICATION_JSON)).andExpect(status().isBadRequest());
|
|
536
|
+
restUserMockMvc.perform(get("/api/users?sort=password,desc").accept(MediaType.APPLICATION_JSON)).andExpect(status().isBadRequest());
|
|
537
|
+
restUserMockMvc.perform(get("/api/users?sort=resetKey,id,desc").accept(MediaType.APPLICATION_JSON)).andExpect(status().isBadRequest());
|
|
538
|
+
restUserMockMvc.perform(get("/api/users?sort=id,desc").accept(MediaType.APPLICATION_JSON)).andExpect(status().isOk());
|
|
539
|
+
<%_ } else { _%>
|
|
540
|
+
webTestClient.get().uri("/api/users?sort=resetKey,DESC").accept(MediaType.APPLICATION_JSON).exchange().expectStatus().isBadRequest();
|
|
541
|
+
webTestClient.get().uri("/api/users?sort=password,DESC").accept(MediaType.APPLICATION_JSON).exchange().expectStatus().isBadRequest();
|
|
542
|
+
webTestClient.get().uri("/api/users?sort=resetKey,id,DESC").accept(MediaType.APPLICATION_JSON).exchange().expectStatus().isBadRequest();
|
|
543
|
+
webTestClient.get().uri("/api/users?sort=id,DESC").accept(MediaType.APPLICATION_JSON).exchange().expectStatus().isOk();
|
|
544
|
+
<%_ } _%>
|
|
545
|
+
}
|
|
546
|
+
<%_ } _%>
|
|
547
|
+
|
|
525
548
|
@Test
|
|
526
549
|
<%_ if (databaseType === 'sql' && !reactive) { _%>
|
|
527
550
|
@Transactional
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "generator-jhipster",
|
|
3
|
-
"version": "6.10.
|
|
3
|
+
"version": "6.10.5",
|
|
4
4
|
"description": "Spring Boot + Angular/React in one handy generator",
|
|
5
5
|
"files": [
|
|
6
6
|
"cli",
|
|
@@ -73,13 +73,13 @@
|
|
|
73
73
|
"os-locale": "5.0.0",
|
|
74
74
|
"parse-gitignore": "1.0.1",
|
|
75
75
|
"pluralize": "8.0.0",
|
|
76
|
-
"prettier": "2.
|
|
77
|
-
"prettier-plugin-java": "0.8.
|
|
76
|
+
"prettier": "2.1.2",
|
|
77
|
+
"prettier-plugin-java": "0.8.2",
|
|
78
78
|
"progress": "2.0.3",
|
|
79
79
|
"randexp": "0.5.3",
|
|
80
80
|
"semver": "7.3.2",
|
|
81
81
|
"shelljs": "0.8.4",
|
|
82
|
-
"
|
|
82
|
+
"then-request": "6.0.2",
|
|
83
83
|
"tabtab": "2.2.2",
|
|
84
84
|
"test": "^0.6.0",
|
|
85
85
|
"through2": "3.0.2",
|