@mshima/generator-jhipster-nodejs 0.0.0-stage → 0.0.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 (209) hide show
  1. package/LICENSE.txt +204 -0
  2. package/README.md +243 -2
  3. package/build-info.json +3 -0
  4. package/cli/cli-customizations.cjs +9 -0
  5. package/cli/cli.cjs +40 -0
  6. package/cli/logo.js +31 -0
  7. package/cli/version.cjs +12 -0
  8. package/generators/ci-cd/USAGE +5 -0
  9. package/generators/ci-cd/command.js +5 -0
  10. package/generators/ci-cd/generator.js +158 -0
  11. package/generators/ci-cd/index.js +2 -0
  12. package/generators/ci-cd/templates/.gitlab-ci.yml.ejs +137 -0
  13. package/generators/ci-cd/templates/azure-pipelines.yml.ejs +68 -0
  14. package/generators/ci-cd/templates/circle.yml.ejs +59 -0
  15. package/generators/ci-cd/templates/docker-registry.yml.ejs +58 -0
  16. package/generators/ci-cd/templates/github-ci.yml.ejs +90 -0
  17. package/generators/ci-cd/templates/jenkins/Jenkinsfile.ejs +104 -0
  18. package/generators/ci-cd/templates/jenkins/idea.gdsl +90 -0
  19. package/generators/ci-cd/templates/jenkins/jenkins.yml.ejs +33 -0
  20. package/generators/ci-cd/templates/travis.yml.ejs +75 -0
  21. package/generators/client/command.js +5 -0
  22. package/generators/client/generator.js +21 -0
  23. package/generators/client/generators/bootstrap/command.js +5 -0
  24. package/generators/client/generators/bootstrap/generator.js +28 -0
  25. package/generators/client/generators/bootstrap/index.js +2 -0
  26. package/generators/client/index.js +2 -0
  27. package/generators/common/generators/bootstrap/command.js +5 -0
  28. package/generators/common/generators/bootstrap/generator.js +37 -0
  29. package/generators/common/generators/bootstrap/index.js +2 -0
  30. package/generators/docker/command.js +5 -0
  31. package/generators/docker/generator.js +16 -0
  32. package/generators/docker/generators/bootstrap/command.js +5 -0
  33. package/generators/docker/generators/bootstrap/generator.js +56 -0
  34. package/generators/docker/generators/bootstrap/index.js +2 -0
  35. package/generators/docker/index.js +2 -0
  36. package/generators/docker/templates/docker/app.yml.ejs +25 -0
  37. package/generators/generator-nodejs-constants.js +32 -0
  38. package/generators/languages/command.js +5 -0
  39. package/generators/languages/generator.js +22 -0
  40. package/generators/languages/index.js +2 -0
  41. package/generators/languages/templates/src/main/webapp/i18n/en/home.json +19 -0
  42. package/generators/languages/templates/src/main/webapp/i18n/es/home.json +19 -0
  43. package/generators/languages/templates/src/main/webapp/i18n/it/home.json +19 -0
  44. package/generators/node-server/command.js +96 -0
  45. package/generators/node-server/entity-files.js +41 -0
  46. package/generators/node-server/files.js +254 -0
  47. package/generators/node-server/generator.js +702 -0
  48. package/generators/node-server/generators/bootstrap/command.js +5 -0
  49. package/generators/node-server/generators/bootstrap/generator.js +83 -0
  50. package/generators/node-server/generators/bootstrap/index.js +2 -0
  51. package/generators/node-server/index.js +2 -0
  52. package/generators/node-server/resources/package.json +76 -0
  53. package/generators/node-server/support/api-fake-data.js +54 -0
  54. package/generators/node-server/support/columns.js +73 -0
  55. package/generators/node-server/support/database.js +24 -0
  56. package/generators/node-server/support/entity-authorities.js +32 -0
  57. package/generators/node-server/support/entity-paths.js +13 -0
  58. package/generators/node-server/support/enums.js +11 -0
  59. package/generators/node-server/support/index.js +9 -0
  60. package/generators/node-server/support/mail-templates.js +82 -0
  61. package/generators/node-server/support/migrations.js +197 -0
  62. package/generators/node-server/support/validators.js +25 -0
  63. package/generators/node-server/templates/.dockerignore.ejs +16 -0
  64. package/generators/node-server/templates/.gitignore.jhi.nodejs.ejs +24 -0
  65. package/generators/node-server/templates/Dockerfile.ejs +54 -0
  66. package/generators/node-server/templates/README.md.jhi.nodejs.ejs +220 -0
  67. package/generators/node-server/templates/package.json.ejs +84 -0
  68. package/generators/node-server/templates/server/README.md.ejs +269 -0
  69. package/generators/node-server/templates/server/e2e/_entityFileName_.database.e2e-spec.ts.ejs +192 -0
  70. package/generators/node-server/templates/server/e2e/_entityFileName_.e2e-spec.ts.ejs +402 -0
  71. package/generators/node-server/templates/server/e2e/account.e2e-spec.ts.ejs +349 -0
  72. package/generators/node-server/templates/server/e2e/app.e2e-spec.ts.ejs +188 -0
  73. package/generators/node-server/templates/server/e2e/authority.e2e-spec.ts.ejs +50 -0
  74. package/generators/node-server/templates/server/e2e/cors.e2e-spec.ts.ejs +110 -0
  75. package/generators/node-server/templates/server/e2e/management.e2e-spec.ts.ejs +180 -0
  76. package/generators/node-server/templates/server/e2e/oauth2-bearer.e2e-spec.ts.ejs +71 -0
  77. package/generators/node-server/templates/server/e2e/session.e2e-spec.ts.ejs +219 -0
  78. package/generators/node-server/templates/server/e2e/setup.test.js.ejs +1 -0
  79. package/generators/node-server/templates/server/e2e/user.e2e-spec.ts.ejs +318 -0
  80. package/generators/node-server/templates/server/env.ejs +1 -0
  81. package/generators/node-server/templates/server/eslint.config.mjs.ejs +48 -0
  82. package/generators/node-server/templates/server/nest-cli.json.ejs +11 -0
  83. package/generators/node-server/templates/server/ormconfig.ts.ejs +35 -0
  84. package/generators/node-server/templates/server/package.json.ejs +143 -0
  85. package/generators/node-server/templates/server/sonar-project.properties.ejs +10 -0
  86. package/generators/node-server/templates/server/src/app.config.spec.ts.ejs +13 -0
  87. package/generators/node-server/templates/server/src/app.config.ts.ejs +179 -0
  88. package/generators/node-server/templates/server/src/app.module.ts.ejs +80 -0
  89. package/generators/node-server/templates/server/src/application-config.ts.ejs +153 -0
  90. package/generators/node-server/templates/server/src/auth/account.controller.ts.ejs +183 -0
  91. package/generators/node-server/templates/server/src/auth/auth.module.ts.ejs +104 -0
  92. package/generators/node-server/templates/server/src/auth/auth.service.ts.ejs +294 -0
  93. package/generators/node-server/templates/server/src/auth/csrf.middleware.spec.ts.ejs +65 -0
  94. package/generators/node-server/templates/server/src/auth/csrf.middleware.ts.ejs +76 -0
  95. package/generators/node-server/templates/server/src/auth/decorators/auth-user.decorator.ts.ejs +8 -0
  96. package/generators/node-server/templates/server/src/auth/decorators/roles.decorator.ts.ejs +4 -0
  97. package/generators/node-server/templates/server/src/auth/dto/key-and-password.dto.ts.ejs +17 -0
  98. package/generators/node-server/templates/server/src/auth/dto/password-change.dto.ts.ejs +17 -0
  99. package/generators/node-server/templates/server/src/auth/dto/user-login.dto.ts.ejs +21 -0
  100. package/generators/node-server/templates/server/src/auth/guards/auth.guard.ts.ejs +50 -0
  101. package/generators/node-server/templates/server/src/auth/guards/oauth2-login.guard.ts.ejs +6 -0
  102. package/generators/node-server/templates/server/src/auth/guards/roles.guard.ts.ejs +25 -0
  103. package/generators/node-server/templates/server/src/auth/index.ts.ejs +8 -0
  104. package/generators/node-server/templates/server/src/auth/jwt.config.spec.ts.ejs +22 -0
  105. package/generators/node-server/templates/server/src/auth/jwt.config.ts.ejs +29 -0
  106. package/generators/node-server/templates/server/src/auth/oauth2.authorities.spec.ts.ejs +24 -0
  107. package/generators/node-server/templates/server/src/auth/oauth2.authorities.ts.ejs +33 -0
  108. package/generators/node-server/templates/server/src/auth/oauth2.config.ts.ejs +51 -0
  109. package/generators/node-server/templates/server/src/auth/passport.jwt.strategy.ts.ejs +45 -0
  110. package/generators/node-server/templates/server/src/auth/passport.oauth2-bearer.strategy.ts.ejs +32 -0
  111. package/generators/node-server/templates/server/src/auth/passport.oauth2.strategy.spec.ts.ejs +27 -0
  112. package/generators/node-server/templates/server/src/auth/passport.oauth2.strategy.ts.ejs +44 -0
  113. package/generators/node-server/templates/server/src/auth/password-util.ts.ejs +10 -0
  114. package/generators/node-server/templates/server/src/auth/password.service.ts.ejs +34 -0
  115. package/generators/node-server/templates/server/src/auth/payload.interface.ts.ejs +14 -0
  116. package/generators/node-server/templates/server/src/auth/role-type.ts.ejs +7 -0
  117. package/generators/node-server/templates/server/src/auth/session-user.middleware.ts.ejs +33 -0
  118. package/generators/node-server/templates/server/src/auth/session.entity.ts.ejs +36 -0
  119. package/generators/node-server/templates/server/src/auth/session.store.spec.ts.ejs +99 -0
  120. package/generators/node-server/templates/server/src/auth/session.store.ts.ejs +116 -0
  121. package/generators/node-server/templates/server/src/auth/user.jwt.controller.ts.ejs +26 -0
  122. package/generators/node-server/templates/server/src/auth/user.oauth2.controller.ts.ejs +78 -0
  123. package/generators/node-server/templates/server/src/auth/user.session.controller.ts.ejs +103 -0
  124. package/generators/node-server/templates/server/src/common/common.module.ts.ejs +19 -0
  125. package/generators/node-server/templates/server/src/common/database/base.entity.ts.ejs +13 -0
  126. package/generators/node-server/templates/server/src/common/database/column-transformers.spec.ts.ejs +46 -0
  127. package/generators/node-server/templates/server/src/common/database/column-transformers.ts.ejs +69 -0
  128. package/generators/node-server/templates/server/src/common/database/column-types.spec.ts.ejs +21 -0
  129. package/generators/node-server/templates/server/src/common/database/column-types.ts.ejs +29 -0
  130. package/generators/node-server/templates/server/src/common/database/pagination.entity.spec.ts.ejs +66 -0
  131. package/generators/node-server/templates/server/src/common/database/pagination.entity.ts.ejs +108 -0
  132. package/generators/node-server/templates/server/src/common/dto/base.dto.ts.ejs +19 -0
  133. package/generators/node-server/templates/server/src/common/errors/error-constants.ts.ejs +10 -0
  134. package/generators/node-server/templates/server/src/common/errors/problem-details.filter.ts.ejs +63 -0
  135. package/generators/node-server/templates/server/src/common/errors/problem.exception.ts.ejs +92 -0
  136. package/generators/node-server/templates/server/src/common/field_validators.ejs +77 -0
  137. package/generators/node-server/templates/server/src/common/header-util.ts.ejs +105 -0
  138. package/generators/node-server/templates/server/src/common/interceptors/logging.interceptor.spec.ts.ejs +93 -0
  139. package/generators/node-server/templates/server/src/common/interceptors/logging.interceptor.ts.ejs +48 -0
  140. package/generators/node-server/templates/server/src/common/logging.spec.ts.ejs +83 -0
  141. package/generators/node-server/templates/server/src/common/logging.ts.ejs +129 -0
  142. package/generators/node-server/templates/server/src/common/metrics.spec.ts.ejs +43 -0
  143. package/generators/node-server/templates/server/src/common/metrics.ts.ejs +198 -0
  144. package/generators/node-server/templates/server/src/common/request.ts.ejs +8 -0
  145. package/generators/node-server/templates/server/src/common/sortable-properties.ts.ejs +43 -0
  146. package/generators/node-server/templates/server/src/common/updatable-properties.ts.ejs +14 -0
  147. package/generators/node-server/templates/server/src/config/application-dev.yml.ejs +118 -0
  148. package/generators/node-server/templates/server/src/config/application-prod.yml.ejs +97 -0
  149. package/generators/node-server/templates/server/src/config/application-secret-samples.yml.ejs +42 -0
  150. package/generators/node-server/templates/server/src/config/application-test.yml.ejs +68 -0
  151. package/generators/node-server/templates/server/src/config/application-tls-samples.yml.ejs +15 -0
  152. package/generators/node-server/templates/server/src/config/application-tls.yml.ejs +15 -0
  153. package/generators/node-server/templates/server/src/config/application.yml.ejs +149 -0
  154. package/generators/node-server/templates/server/src/config.spec.ts.ejs +81 -0
  155. package/generators/node-server/templates/server/src/config.ts.ejs +255 -0
  156. package/generators/node-server/templates/server/src/entities/_entityFileName_/_entityFileName_.controller.ts.ejs +178 -0
  157. package/generators/node-server/templates/server/src/entities/_entityFileName_/_entityFileName_.entity.ts.ejs +110 -0
  158. package/generators/node-server/templates/server/src/entities/_entityFileName_/_entityFileName_.mapper.ts.ejs +37 -0
  159. package/generators/node-server/templates/server/src/entities/_entityFileName_/_entityFileName_.module.ts.ejs +14 -0
  160. package/generators/node-server/templates/server/src/entities/_entityFileName_/_entityFileName_.service.ts.ejs +123 -0
  161. package/generators/node-server/templates/server/src/entities/_entityFileName_/dto/_entityFileName_.dto.ts.ejs +99 -0
  162. package/generators/node-server/templates/server/src/mail/mail.module.ts.ejs +49 -0
  163. package/generators/node-server/templates/server/src/mail/mail.service.spec.ts.ejs +105 -0
  164. package/generators/node-server/templates/server/src/mail/mail.service.ts.ejs +120 -0
  165. package/generators/node-server/templates/server/src/main.ts.ejs +114 -0
  166. package/generators/node-server/templates/server/src/management/api-docs.controller.ts.ejs +27 -0
  167. package/generators/node-server/templates/server/src/management/api-docs.service.ts.ejs +8 -0
  168. package/generators/node-server/templates/server/src/management/configuration.controller.ts.ejs +80 -0
  169. package/generators/node-server/templates/server/src/management/health.controller.spec.ts.ejs +79 -0
  170. package/generators/node-server/templates/server/src/management/health.controller.ts.ejs +87 -0
  171. package/generators/node-server/templates/server/src/management/health.module.ts.ejs +9 -0
  172. package/generators/node-server/templates/server/src/management/loggers.controller.ts.ejs +40 -0
  173. package/generators/node-server/templates/server/src/management/management.controller.spec.ts.ejs +26 -0
  174. package/generators/node-server/templates/server/src/management/management.controller.ts.ejs +34 -0
  175. package/generators/node-server/templates/server/src/management/management.module.ts.ejs +21 -0
  176. package/generators/node-server/templates/server/src/management/metrics.controller.ts.ejs +85 -0
  177. package/generators/node-server/templates/server/src/migrations/1570200270081-CreateTables.ts.ejs +64 -0
  178. package/generators/node-server/templates/server/src/migrations/1570200270082-CreateSessions.ts.ejs +26 -0
  179. package/generators/node-server/templates/server/src/migrations/1570200490072-SeedUsersRoles.ts.ejs +74 -0
  180. package/generators/node-server/templates/server/src/migrations/_entityConstraintsMigration_.ts.ejs +40 -0
  181. package/generators/node-server/templates/server/src/migrations/_entityMigration_.ts.ejs +26 -0
  182. package/generators/node-server/templates/server/src/migrations/support/schema.ts.ejs +202 -0
  183. package/generators/node-server/templates/server/src/orm.config.ts.ejs +147 -0
  184. package/generators/node-server/templates/server/src/registry/consul.service.ts.ejs +70 -0
  185. package/generators/node-server/templates/server/src/registry/eureka.service.ts.ejs +129 -0
  186. package/generators/node-server/templates/server/src/swagger.ts.ejs +24 -0
  187. package/generators/node-server/templates/server/src/tls.ts.ejs +27 -0
  188. package/generators/node-server/templates/server/src/users/authority.controller.ts.ejs +85 -0
  189. package/generators/node-server/templates/server/src/users/authority.entity.ts.ejs +22 -0
  190. package/generators/node-server/templates/server/src/users/dto/authority.dto.ts.ejs +10 -0
  191. package/generators/node-server/templates/server/src/users/dto/user.dto.ts.ejs +116 -0
  192. package/generators/node-server/templates/server/src/users/public.user.controller.ts.ejs +51 -0
  193. package/generators/node-server/templates/server/src/users/user.controller.ts.ejs +191 -0
  194. package/generators/node-server/templates/server/src/users/user.entity.ts.ejs +63 -0
  195. package/generators/node-server/templates/server/src/users/user.mapper.ts.ejs +26 -0
  196. package/generators/node-server/templates/server/src/users/user.module.ts.ejs +19 -0
  197. package/generators/node-server/templates/server/src/users/user.service.ts.ejs +156 -0
  198. package/generators/node-server/templates/server/tsconfig.build.json.ejs +9 -0
  199. package/generators/node-server/templates/server/tsconfig.json.ejs +23 -0
  200. package/generators/node-server/templates/server/typeorm-migration.ts.ejs +18 -0
  201. package/generators/node-server/templates/server/vitest.config.e2e.ts.ejs +16 -0
  202. package/generators/node-server/templates/server/vitest.config.ts.ejs +16 -0
  203. package/generators/server/command.js +7 -0
  204. package/generators/server/generator.js +20 -0
  205. package/generators/server/generators/bootstrap/command.js +5 -0
  206. package/generators/server/generators/bootstrap/generator.js +15 -0
  207. package/generators/server/generators/bootstrap/index.js +2 -0
  208. package/generators/server/index.js +2 -0
  209. package/package.json +75 -4
@@ -0,0 +1,702 @@
1
+ import { readFile } from 'node:fs/promises';
2
+
3
+ import { TEMPLATES_WEBAPP_SOURCES_DIR } from 'generator-jhipster';
4
+ import BaseApplicationGenerator from 'generator-jhipster/generators/base-application';
5
+ import { createNeedleCallback } from 'generator-jhipster/generators/base-core/support';
6
+ import { createKeyStore } from 'generator-jhipster/generators/java/support';
7
+ import { createBase64Secret, createReproducibleBase64Secret, mutateData } from 'generator-jhipster/utils';
8
+
9
+ import blueprintVersion from '../../cli/version.cjs';
10
+ import { SERVER_NODEJS_SRC_DIR } from '../generator-nodejs-constants.js';
11
+
12
+ import { entityFiles } from './entity-files.js';
13
+ import { serverFiles } from './files.js';
14
+ import {
15
+ MIGRATION_TIMESTAMP_OFFSET,
16
+ apiFakeEntity,
17
+ apiFakeValue,
18
+ columnTransformer,
19
+ constraintsMigration,
20
+ contentTypeColumnOptions,
21
+ entityMigration,
22
+ fieldColumnOptions,
23
+ fieldColumnTypeImports,
24
+ fieldTypeValidators,
25
+ getDatabasePort,
26
+ getNodeDevDatabaseType,
27
+ hasRuntimeColumnTypes,
28
+ joinTable,
29
+ mutateEntityAuthorities,
30
+ mutateEntityPaths,
31
+ mutateRelatedValues,
32
+ primaryKeyColumn,
33
+ serverEnumInfo,
34
+ thymeleafMailToHandlebars,
35
+ userAuthorityJoinTable,
36
+ } from './support/index.js';
37
+
38
+ /** The time the end-to-end tests wait for the server, like the WAIT_TIMEOUT of java:server, which JHipster does not export. */
39
+ const WAIT_TIMEOUT = 3 * 60000;
40
+
41
+ const fieldTypes = {
42
+ Boolean: 'boolean',
43
+ Integer: 'number',
44
+ Long: 'number',
45
+ Float: 'number',
46
+ Double: 'number',
47
+ BigDecimal: 'number',
48
+ String: 'string',
49
+ UUID: 'string',
50
+ // Without a column type, TypeORM gives a Date the date-time type of the database in use.
51
+ Instant: 'Date',
52
+ ZonedDateTime: 'Date',
53
+ // The values of the JSON of JHipster Spring Boot: yyyy-MM-dd, HH:mm:ss, ISO-8601 (PT1H30M), base64 or text.
54
+ LocalDate: 'string',
55
+ LocalTime: 'string',
56
+ Duration: 'string',
57
+ 'byte[]': 'string',
58
+ };
59
+
60
+ const dbTypes = {
61
+ Boolean: 'boolean',
62
+ Integer: 'integer',
63
+ Long: 'bigint',
64
+ Float: 'float',
65
+ Double: 'double precision',
66
+ BigDecimal: 'decimal',
67
+ LocalDate: 'date',
68
+ LocalTime: 'time',
69
+ // The nanoseconds of the duration, like the bigint column of JHipster Spring Boot (the duration transformer).
70
+ Duration: 'bigint',
71
+ AnyBlob: 'blob',
72
+ ImageBlob: 'blob',
73
+ Blob: 'blob',
74
+ TextBlob: 'blob',
75
+ 'byte[]': 'blob',
76
+ };
77
+
78
+ /**
79
+ * Column types replacing the ones of dbTypes for a prodDatabaseType: the entities are shared by the prod database and by
80
+ * better-sqlite3 (dev and test), so a type must be supported by TypeORM for both drivers. An undefined type omits it,
81
+ * TypeORM then gives the type of the database for the TypeScript type (Boolean: bit on SQL Server, number on Oracle).
82
+ * A byte[] field is an ImageBlob or an AnyBlob, a TextBlob is a byte[] field with a text content.
83
+ */
84
+ const prodDatabaseColumnTypes = {
85
+ // bytea is not a SQLite type: the blobs are kept as text, like the base64 strings the API exchanges.
86
+ postgresql: { 'byte[]': 'text', TextBlob: 'text' },
87
+ // SQL Server has no boolean type, and neither bit nor its binary types are SQLite ones.
88
+ mssql: { Boolean: undefined, 'byte[]': 'text', TextBlob: 'text' },
89
+ // Oracle has neither boolean nor bigint (integer is NUMBER(38)), nor a time type.
90
+ oracle: { Boolean: undefined, Long: 'integer', Duration: 'integer', LocalTime: 'varchar', TextBlob: 'clob' },
91
+ // A text, a longtext on MySQL and MariaDB at runtime like the blobs a longblob (src/common/database/column-types.ts).
92
+ mysql: { TextBlob: 'text' },
93
+ mariadb: { TextBlob: 'text' },
94
+ };
95
+
96
+ /** Enum column types by prodDatabaseType, simple-enum otherwise: Oracle has no simple-enum. */
97
+ const enumColumnTypes = {
98
+ postgresql: 'varchar',
99
+ oracle: 'varchar',
100
+ };
101
+
102
+ const databaseDrivers = {
103
+ mongodb: 'mongodb',
104
+ mysql: 'mysql2',
105
+ // TypeORM connects to MariaDB with the MySQL driver.
106
+ mariadb: 'mysql2',
107
+ postgresql: 'pg',
108
+ oracle: 'oracledb',
109
+ mssql: 'mssql',
110
+ };
111
+
112
+ const databaseDevDrivers = {
113
+ mongodb: 'mongodb-memory-server',
114
+ mysql: 'better-sqlite3',
115
+ mariadb: 'better-sqlite3',
116
+ postgresql: 'better-sqlite3',
117
+ oracle: 'better-sqlite3',
118
+ mssql: 'better-sqlite3',
119
+ };
120
+
121
+ export default class extends BaseApplicationGenerator {
122
+ oldNodejsVersion;
123
+ existingNodejsVersion;
124
+ nodejsPackageJson;
125
+
126
+ async beforeQueue() {
127
+ await this.dependsOnJHipster('jhipster-nodejs:node-server:bootstrap');
128
+ await this.dependsOnJHipster('server');
129
+ }
130
+
131
+ get [BaseApplicationGenerator.INITIALIZING]() {
132
+ return this.asInitializingTaskGroup({
133
+ async initializing() {
134
+ this.existingNodejsVersion = this.blueprintConfig.nodejsVersion;
135
+ this.oldNodejsVersion = this.existingNodejsVersion ?? '3.0.0';
136
+ // The version of the blueprint, the one of its build-info.json for a build published under another version.
137
+ this.nodejsPackageJson = {
138
+ ...JSON.parse((await readFile(this.templatePath('../../../package.json'), 'utf-8')).toString()),
139
+ version: blueprintVersion,
140
+ };
141
+ this.blueprintConfig.nodejsVersion = this.nodejsPackageJson.version;
142
+ },
143
+ });
144
+ }
145
+
146
+ get [BaseApplicationGenerator.CONFIGURING]() {
147
+ return this.asConfiguringTaskGroup({
148
+ async configuringTemplateTask() {
149
+ const { prodDatabaseType, databaseType } = this.jhipsterConfigWithDefaults;
150
+ if (!['sql', 'mongodb'].includes(databaseType)) {
151
+ throw new Error(
152
+ `The database type ${databaseType} is not supported by the JHipster NodeJS blueprint: use sql (with prodDatabaseType mysql, mariadb, postgresql, mssql or oracle) or mongodb.`,
153
+ );
154
+ }
155
+ const databaseTypeMongodb = (prodDatabaseType ?? databaseType) === 'mongodb';
156
+ this.jhipsterConfig.databaseType = databaseTypeMongodb ? 'mongodb' : 'sql';
157
+ if (databaseTypeMongodb) {
158
+ this.jhipsterConfig.prodDatabaseType = 'mongodb';
159
+ }
160
+ },
161
+ sqliteDevDatabase() {
162
+ // The embedded development database of the NodeJS server is SQLite, not the H2 of JHipster Spring Boot: the H2
163
+ // database of an application is migrated to SQLite, on disk or in memory like it.
164
+ const sqliteDevDatabaseTypes = { h2Disk: 'sqlite', h2Memory: 'sqliteMemory' };
165
+ const { devDatabaseType } = this.jhipsterConfig;
166
+ if (sqliteDevDatabaseTypes[devDatabaseType]) {
167
+ this.log.info(`The development database ${devDatabaseType} migrated to ${sqliteDevDatabaseTypes[devDatabaseType]}.`);
168
+ this.jhipsterConfig.devDatabaseType = sqliteDevDatabaseTypes[devDatabaseType];
169
+ }
170
+ },
171
+ unsupportedOptions() {
172
+ // Options of JHipster the NodeJS server does not implement: refused like the database types, instead of
173
+ // generating an application without what they ask for. The configuration as given, as the defaults of
174
+ // JHipster's spring-boot generator (cacheProvider ehcache) apply to every application.
175
+ const config = this.jhipsterConfig;
176
+ const enabled = value => value !== undefined && value !== null && value !== false && value !== 'no';
177
+ const unsupported = [
178
+ ...['searchEngine', 'cacheProvider', 'websocket', 'messageBroker']
179
+ .filter(option => enabled(config[option]))
180
+ .map(option => `${option} ${config[option]}`),
181
+ // The sessions of the users of the application, like JHipster Spring Boot, in a monolith with its user management.
182
+ ...(config.authenticationType === 'session' && (config.applicationType ?? 'monolith') !== 'monolith'
183
+ ? [`authenticationType session of a ${config.applicationType} (use jwt or oauth2)`]
184
+ : []),
185
+ ...(config.authenticationType === 'session' && config.skipUserManagement
186
+ ? ['authenticationType session with skipUserManagement']
187
+ : []),
188
+ ...(config.reactive ? ['reactive'] : []),
189
+ ];
190
+ if (unsupported.length > 0) {
191
+ throw new Error(`The JHipster NodeJS blueprint does not support ${unsupported.join(', ')}.`);
192
+ }
193
+ },
194
+ jwtSecretKey() {
195
+ // JHipster's spring-boot generator, which this blueprint replaces, creates the secret shared with JHipster's
196
+ // Spring Boot applications.
197
+ if (this.jhipsterConfigWithDefaults.authenticationType === 'jwt' && this.jhipsterConfig.jwtSecretKey === undefined) {
198
+ const { creationTimestamp } = this.jhipsterConfig;
199
+ // With --reproducible-secrets, derived from the creation timestamp like JHipster Spring Boot: the same
200
+ // application gives the same secret.
201
+ this.jhipsterConfig.jwtSecretKey =
202
+ this.options.reproducibleSecrets && creationTimestamp
203
+ ? createReproducibleBase64Secret(creationTimestamp, 'jwtSecretKey', 64)
204
+ : createBase64Secret(64, this.options.reproducibleTests);
205
+ }
206
+ },
207
+ keepSyncUserWithIdp() {
208
+ // OAuth2 applications generated before 4.1.1 always synchronized their users, keep it for them. Not for an
209
+ // application generated by this version itself (a development version records the version it will release).
210
+ if (
211
+ this.existingNodejsVersion &&
212
+ this.isVersionLessThan(this.existingNodejsVersion, '4.1.1') &&
213
+ this.isVersionLessThan(this.existingNodejsVersion, this.nodejsPackageJson.version) &&
214
+ this.jhipsterConfigWithDefaults.authenticationType === 'oauth2' &&
215
+ this.jhipsterConfig.syncUserWithIdp === undefined
216
+ ) {
217
+ this.jhipsterConfig.syncUserWithIdp = true;
218
+ }
219
+ },
220
+ });
221
+ }
222
+
223
+ get [BaseApplicationGenerator.COMPOSING]() {
224
+ return this.asComposingTaskGroup({
225
+ async composingTemplateTask() {
226
+ await this.composeWithJHipster('docker');
227
+ },
228
+ async composeLanguages() {
229
+ // Like the spring-boot generator: the languages of the application to generate (languagesToGenerate), the server
230
+ // messages of server:i18n among them, without a client composing it.
231
+ if (this.jhipsterConfigWithDefaults.enableTranslation) {
232
+ await this.composeWithJHipster('languages');
233
+ }
234
+ },
235
+ async composingServerI18n() {
236
+ // The messages of the account mails, written to the serverI18nDir of the application (common:bootstrap), the
237
+ // default ones without translation too. The languages generator composes it for the languages command.
238
+ if (this.jhipsterConfigWithDefaults.skipUserManagement) return;
239
+ await this.composeWithJHipster('jhipster:server:i18n');
240
+ },
241
+ });
242
+ }
243
+
244
+ get [BaseApplicationGenerator.LOADING]() {
245
+ return this.asLoadingTaskGroup({
246
+ async loadingTemplateTask({ application }) {
247
+ application.nodeServerDependencies = {};
248
+ this.loadNodeDependenciesFromPackageJson(application.nodeServerDependencies, this.templatePath('../resources/package.json'));
249
+ },
250
+ });
251
+ }
252
+
253
+ get [BaseApplicationGenerator.PREPARING]() {
254
+ return this.asPreparingTaskGroup({
255
+ migrations({ applicationDefaults }) {
256
+ applicationDefaults({
257
+ __override__: false,
258
+ // The offset of the timestamps of the migrations of the developers (see support/migrations.js).
259
+ nodejsMigrationTimestampOffset: MIGRATION_TIMESTAMP_OFFSET,
260
+ });
261
+ },
262
+ passwords({ applicationDefaults }) {
263
+ applicationDefaults({
264
+ __override__: false,
265
+ // The bcrypt rounds of the passwords of the users: the property of the JWT applications, kept, else the one of
266
+ // the session applications.
267
+ nodejsPasswordRoundsProperty: ({ authenticationTypeJwt }) =>
268
+ authenticationTypeJwt
269
+ ? 'jhipster.security.authentication.jwt.hash-salt-or-rounds'
270
+ : 'jhipster.security.authentication.hash-salt-or-rounds',
271
+ });
272
+ },
273
+ drivers({ applicationDefaults }) {
274
+ applicationDefaults({
275
+ __override__: false,
276
+ nodeProdDatabaseDriver: ({ databaseType, prodDatabaseType = databaseType }) => databaseDrivers[prodDatabaseType],
277
+ nodeDevDatabaseDriver: ({ databaseType, prodDatabaseType = databaseType }) => databaseDevDrivers[prodDatabaseType],
278
+ nodeProdDatabaseType: ({ databaseType, prodDatabaseType = databaseType }) =>
279
+ prodDatabaseType === 'postgresql' ? 'postgres' : prodDatabaseType,
280
+ nodeDevDatabaseType: getNodeDevDatabaseType,
281
+ // The SQLite development database: in memory for sqliteMemory, else a file of the temporary folder of the
282
+ // application, at its root, from the server folder the server runs in.
283
+ nodeDevSqliteDatabase: ({ devDatabaseType, nodeServerRootDir, temporaryDir }) =>
284
+ devDatabaseType === 'sqliteMemory' ? ':memory:' : `${this.relativeDir(nodeServerRootDir, temporaryDir)}db/sqlite-dev-db.sql`,
285
+ nodeDatabasePort: getDatabasePort,
286
+ nodejsRuntimeColumnTypes: hasRuntimeColumnTypes,
287
+ });
288
+ },
289
+ async source({ source }) {
290
+ source.addEntityToNodeConfig = ({ nodejsEntityPath, persistClass }) =>
291
+ this.editFile(
292
+ `${SERVER_NODEJS_SRC_DIR}/src/orm.config.ts`,
293
+ createNeedleCallback({
294
+ needle: 'add-entity-to-ormconfig-imports',
295
+ contentToAdd: `import { ${persistClass} } from './${nodejsEntityPath}';`,
296
+ }),
297
+ createNeedleCallback({
298
+ needle: 'add-entity-to-ormconfig-entities',
299
+ contentToAdd: `${persistClass},`,
300
+ }),
301
+ );
302
+ source.addMigrationToNodeConfig = ({ className, fileName }) =>
303
+ this.editFile(
304
+ `${SERVER_NODEJS_SRC_DIR}/src/orm.config.ts`,
305
+ createNeedleCallback({
306
+ needle: 'add-entity-to-ormconfig-imports',
307
+ contentToAdd: `import { ${className} } from './migrations/${fileName}.ts';`,
308
+ }),
309
+ createNeedleCallback({
310
+ needle: 'add-migration-to-ormconfig-migrations',
311
+ contentToAdd: `${className},`,
312
+ }),
313
+ );
314
+ source.addEntityToAppModule = ({ entityClass, nodejsModulePath }) =>
315
+ this.editFile(
316
+ `${SERVER_NODEJS_SRC_DIR}/src/app.module.ts`,
317
+ createNeedleCallback({
318
+ needle: 'jhipster-needle-add-entity-module-to-main-import',
319
+ contentToAdd: `import { ${entityClass}Module } from './${nodejsModulePath}';`,
320
+ }),
321
+ createNeedleCallback({
322
+ needle: 'jhipster-needle-add-entity-module-to-main',
323
+ contentToAdd: `${entityClass}Module,`,
324
+ }),
325
+ );
326
+ },
327
+ async preparing({ application }) {
328
+ application.typeormRelationsSupport = !application.databaseTypeMongodb;
329
+ },
330
+ });
331
+ }
332
+
333
+ get [BaseApplicationGenerator.LOADING_ENTITIES]() {
334
+ return this.asLoadingEntitiesTaskGroup({
335
+ async loadingEntitiesTemplateTask({ entitiesToLoad }) {
336
+ for (const entity of entitiesToLoad) {
337
+ entity.entityBootstrap.dto = true;
338
+ }
339
+ },
340
+ });
341
+ }
342
+
343
+ get [BaseApplicationGenerator.PREPARING_EACH_ENTITY]() {
344
+ return this.asPreparingEachEntityTaskGroup({
345
+ prepareMappedByRelationships({ entityDefaults }) {
346
+ entityDefaults({
347
+ // The relationships the other entity stores (its join column or its join table), never stored from this entity,
348
+ // like the mappedBy side of JHipster Spring Boot: the complement of the persistableRelationships of JHipster,
349
+ // delayed until the relationships are prepared.
350
+ nodejsMappedByRelationships: ({ relationships }, { delayMarker }) =>
351
+ delayMarker ?? relationships.filter(relationship => !relationship.persistableRelationship),
352
+ });
353
+ },
354
+ prepareEntityPaths({ entityDefaults }) {
355
+ // The files of the entity in its feature module (support/entity-paths.js).
356
+ entityDefaults(mutateEntityPaths);
357
+ },
358
+ prepareEntityAuthorities({ entityDefaults }) {
359
+ // The roles of the endpoints of the entity, like the @PreAuthorize of JHipster Spring Boot (support/entity-authorities.js).
360
+ entityDefaults(mutateEntityAuthorities);
361
+ },
362
+ });
363
+ }
364
+
365
+ get [BaseApplicationGenerator.PREPARING_EACH_ENTITY_RELATIONSHIP]() {
366
+ return this.asPreparingEachEntityRelationshipTaskGroup({
367
+ prepareRelatedValues({ entity, relationshipDefaults }) {
368
+ // The values of the related record of the relationship tests (support/api-fake-data.js).
369
+ relationshipDefaults(mutateRelatedValues(entity));
370
+ },
371
+ });
372
+ }
373
+
374
+ get [BaseApplicationGenerator.PREPARING_EACH_ENTITY_FIELD]() {
375
+ return this.asPreparingEachEntityFieldTaskGroup({
376
+ async preparingEachEntityTemplateTask({ application, field }) {
377
+ const { fieldType } = field;
378
+ if (field.skipServer) return;
379
+
380
+ if (field.fieldValues) {
381
+ mutateData(field, {
382
+ __override__: true,
383
+ nodejsFieldType: fieldType,
384
+ nodejsColumnType: enumColumnTypes[application.prodDatabaseType] ?? 'simple-enum',
385
+ });
386
+ } else {
387
+ const columnTypes = { ...dbTypes, ...prodDatabaseColumnTypes[application.prodDatabaseType] };
388
+ const nodejsColumnType = columnTypes[field.fieldTypeBlobContent === 'text' ? 'TextBlob' : fieldType];
389
+ mutateData(field, {
390
+ __override__: true,
391
+ nodejsFieldType: fieldTypes[fieldType] ?? 'any',
392
+ nodejsColumnType,
393
+ nodejsColumnTransformer: application.databaseTypeSql ? columnTransformer({ fieldType, nodejsColumnType }) : undefined,
394
+ });
395
+ }
396
+ mutateData(field, {
397
+ __override__: true,
398
+ nodejsColumnOptions: fieldColumnOptions(field, application),
399
+ nodejsColumnTypeImports: fieldColumnTypeImports(field, application),
400
+ nodejsTypeValidators: fieldTypeValidators(field),
401
+ nodejsContentTypeColumnOptions: contentTypeColumnOptions(field, application),
402
+ });
403
+ // The fake value of the field as the API exchanges it, generated when a template calls it (after its faker seed).
404
+ field.nodejsApiFakeValue = () => apiFakeValue(field);
405
+ },
406
+ });
407
+ }
408
+
409
+ get [BaseApplicationGenerator.DEFAULT]() {
410
+ return this.asDefaultTaskGroup({
411
+ prepareColumnTransformers({ entities }) {
412
+ // The transformers the columns of an entity use, imported by its entity.
413
+ for (const entity of entities.filter(entity => !entity.skipServer)) {
414
+ entity.nodejsColumnTransformers = [...new Set(entity.fields.map(field => field.nodejsColumnTransformer).filter(Boolean))];
415
+ // The helpers of the column types chosen at runtime the columns of an entity use.
416
+ entity.nodejsColumnTypeImports = [...new Set(entity.fields.flatMap(field => field.nodejsColumnTypeImports ?? []))];
417
+ // The fake values of the fields as the API exchanges them, generated when a template calls it (after its faker seed).
418
+ entity.nodejsApiFakeEntity = () => apiFakeEntity(entity);
419
+ }
420
+ },
421
+ prepareAuthorityAlertName({ application }) {
422
+ // The name of the built-in Authority in its alerts (adminAuthority), the key of its translations in the client.
423
+ application.nodejsAuthorityAlertName = application.authority?.entityAlertName ?? 'authority';
424
+ },
425
+ prepareUserLoginVm({ application }) {
426
+ // The class of the logged user's data: the DTO of the built-in User entity, prepared with the entities, else
427
+ // UserDTO (OAuth2 without syncUserWithIdp has no built-in User).
428
+ application.userLoginVmClass = application.user?.dtoClass ?? 'UserDTO';
429
+ },
430
+ prepareMigrations({ application, entities }) {
431
+ if (!application.databaseTypeSql) return;
432
+ // The migrations of the SQL databases, like the Liquibase changelogs of JHipster Spring Boot (see support/migrations.js).
433
+ if (application.generateBuiltInUserEntity) {
434
+ application.nodejsUserPrimaryKeyColumn = primaryKeyColumn(application.user);
435
+ application.nodejsUserAuthorityJoinTable = userAuthorityJoinTable(application);
436
+ }
437
+ for (const entity of entities.filter(entity => !entity.skipServer && !entity.builtIn)) {
438
+ entity.nodejsMigration = entityMigration(entity);
439
+ entity.nodejsConstraintsMigration = constraintsMigration(entity);
440
+ // The join tables of the entity, its @JoinTable the same as its constraints migration.
441
+ for (const relationship of entity.relationships.filter(relationship => relationship.shouldWriteJoinTable)) {
442
+ relationship.nodejsJoinTable = joinTable(entity, relationship);
443
+ }
444
+ }
445
+ },
446
+ });
447
+ }
448
+
449
+ get [BaseApplicationGenerator.WRITING]() {
450
+ return this.asWritingTaskGroup({
451
+ async cleanup({ application, control }) {
452
+ if (control.existingProject) {
453
+ await control.cleanupFiles(this.oldNodejsVersion, {
454
+ '3.0.1': [
455
+ '.server.eslintrc.json',
456
+ '.server.eslintignore',
457
+ 'server/src/repository/authority.repository.ts',
458
+ 'server/src/repository/user.repository.ts',
459
+ [application.authenticationTypeOauth2, 'node/src/security/password-util.ts'],
460
+ ],
461
+ '4.1.1': [
462
+ // The Dockerfile starts node itself, the database readiness comes from the compose healthchecks.
463
+ 'server/scripts/entrypoint.sh',
464
+ [!application.generateUserManagement, 'server/src/web/rest/user.controller.ts', 'server/e2e/user.e2e-spec.ts'],
465
+ [
466
+ !application.generateBuiltInUserEntity,
467
+ 'server/src/domain/user.entity.ts',
468
+ 'server/src/service/mapper/user.mapper.ts',
469
+ 'server/src/service/user.service.ts',
470
+ 'server/src/module/user.module.ts',
471
+ 'server/src/web/rest/public.user.controller.ts',
472
+ ],
473
+ [
474
+ !application.generateBuiltInAuthorityEntity,
475
+ 'server/src/domain/authority.entity.ts',
476
+ 'server/src/migrations/1570200490072-SeedUsersRoles.ts',
477
+ ],
478
+ ],
479
+ '4.3.1': [
480
+ // The HTTP helpers of the server moved from src/client (a name taken by the client workspace) to src/common.
481
+ 'server/src/client/header-util.ts',
482
+ 'server/src/client/request.ts',
483
+ 'server/src/client/interceptors/logging.interceptor.ts',
484
+ // The tests run with Vitest (vitest.config.e2e.ts) instead of Jest.
485
+ 'server/e2e/jest.e2e.config.json',
486
+ // The webpack bundle (webpack:prod) is removed: the server is built with tsc, like NestJS does by default.
487
+ 'server/webpack.server.prod.config.js',
488
+ // The Nest CLI builds and starts the server, and copies the configuration files (assets of nest-cli.json).
489
+ 'server/scripts/copy-resources.ts',
490
+ // The files of 4.2.0 moved to the feature modules (auth, users, management, common), their specs next to them.
491
+ 'server/src/domain/authority.entity.ts',
492
+ 'server/src/domain/user.entity.ts',
493
+ 'server/src/domain/base/base.entity.ts',
494
+ 'server/src/domain/base/pagination.entity.ts',
495
+ 'server/src/domain/base/pagination.entity.spec.ts',
496
+ 'server/src/module/auth.module.ts',
497
+ 'server/src/module/user.module.ts',
498
+ 'server/src/security/decorators/auth-user.decorator.ts',
499
+ 'server/src/security/decorators/roles.decorator.ts',
500
+ 'server/src/security/guards/auth.guard.ts',
501
+ 'server/src/security/guards/roles.guard.ts',
502
+ 'server/src/security/index.ts',
503
+ 'server/src/security/oauth2.authorities.ts',
504
+ 'server/src/security/oauth2.config.ts',
505
+ 'server/src/security/passport.jwt.strategy.ts',
506
+ 'server/src/security/passport.oauth2.strategy.ts',
507
+ 'server/src/security/password-util.ts',
508
+ 'server/src/security/payload.interface.ts',
509
+ 'server/src/security/role-type.ts',
510
+ 'server/src/service/auth.service.ts',
511
+ 'server/src/service/user.service.ts',
512
+ 'server/src/service/dto/base.dto.ts',
513
+ 'server/src/service/dto/password-change.dto.ts',
514
+ 'server/src/service/dto/user-login.dto.ts',
515
+ 'server/src/service/dto/user.dto.ts',
516
+ 'server/src/service/mapper/user.mapper.ts',
517
+ 'server/src/web/rest/account.controller.ts',
518
+ 'server/src/web/rest/management.controller.ts',
519
+ 'server/src/web/rest/public.user.controller.ts',
520
+ 'server/src/web/rest/user.controller.ts',
521
+ 'server/src/web/rest/user.jwt.controller.ts',
522
+ 'server/src/web/rest/user.oauth2.controller.ts',
523
+ 'server/test/admin/management.controller.spec.ts',
524
+ 'server/test/config.spec.ts',
525
+ 'server/test/security/oauth2.authorities.spec.ts',
526
+ ],
527
+ });
528
+ }
529
+ },
530
+ async writingTemplateTask({ application }) {
531
+ await this.writeFiles({
532
+ sections: serverFiles,
533
+ context: application,
534
+ });
535
+ },
536
+ writeSampleKeyStore({ application }) {
537
+ // The keystore of the tls-samples profile, written once like the one of JHipster Spring Boot.
538
+ const keyStoreFile = this.destinationPath(`${SERVER_NODEJS_SRC_DIR}/src/config/tls/keystore-samples.p12`);
539
+ if (this.fs.exists(keyStoreFile)) {
540
+ // A write once file, written back as it is: the KeyStore is told apart from the files no generator writes.
541
+ this.writeDestination(keyStoreFile, this.fs.read(keyStoreFile, { raw: true }), { metadata: { writeOnce: true } });
542
+ this.log.info(`KeyStore '${keyStoreFile}' already exists. Leaving unchanged.`);
543
+ } else {
544
+ // Created with node:crypto, without the keytool of a JDK, like JHipster Spring Boot: with --reproducible-secrets,
545
+ // derived from the creation timestamp, the same application gives the same file.
546
+ const creationTimestamp = this.options.reproducibleSecrets ? this.jhipsterConfig.creationTimestamp : undefined;
547
+ const packageName = application.packageName ?? application.baseName;
548
+ this.writeDestination(keyStoreFile, createKeyStore({ packageName, creationTimestamp }), {
549
+ metadata: { writeOnce: true },
550
+ });
551
+ this.log.info(`KeyStore '${keyStoreFile}' generated successfully.`);
552
+ }
553
+ },
554
+ async writingMailTemplates({ application }) {
555
+ if (!application.generateUserManagement) return;
556
+ // The mail templates of JHipster Spring Boot (Thymeleaf) converted to the Handlebars templates of the mail module.
557
+ for (const template of ['activationEmail', 'creationEmail', 'passwordResetEmail']) {
558
+ const destination = `${SERVER_NODEJS_SRC_DIR}/src/templates/mail/${template}.hbs`;
559
+ await this.writeFile(
560
+ this.fetchFromInstalledJHipster(`spring-boot/templates/src/main/resources/templates/mail/${template}.html.ejs`),
561
+ destination,
562
+ application,
563
+ );
564
+ this.editFile(destination, thymeleafMailToHandlebars);
565
+ }
566
+ },
567
+ });
568
+ }
569
+
570
+ get [BaseApplicationGenerator.WRITING_ENTITIES]() {
571
+ return this.asWritingEntitiesTaskGroup({
572
+ async cleanup({ control, entities }) {
573
+ if (control.existingProject) {
574
+ await control.cleanupFiles(this.oldNodejsVersion, {
575
+ '3.0.1': entities.filter(e => !e.skipServer).map(e => `server/src/repository/${e.entityFileName}.repository.ts`),
576
+ // The files of the entities, of 4.2.0, moved to their feature module (src/entities/<entity>).
577
+ '4.3.1': entities
578
+ .filter(entity => !entity.skipServer && !entity.builtIn)
579
+ .flatMap(({ entityFileName, fields }) => [
580
+ `server/src/domain/${entityFileName}.entity.ts`,
581
+ `server/src/module/${entityFileName}.module.ts`,
582
+ `server/src/service/${entityFileName}.service.ts`,
583
+ `server/src/service/dto/${entityFileName}.dto.ts`,
584
+ `server/src/service/mapper/${entityFileName}.mapper.ts`,
585
+ `server/src/web/rest/${entityFileName}.controller.ts`,
586
+ ...fields.filter(field => field.fieldIsEnum).map(field => `server/src/domain/enumeration/${field.enumFileName}.ts`),
587
+ ]),
588
+ });
589
+ }
590
+ },
591
+ async customEntityServerFiles({ application, entities }) {
592
+ for (const entity of entities.filter(entity => !entity.skipServer && !entity.builtIn)) {
593
+ if (application.databaseType === 'mongodb' && entity.relationships.length > 0) {
594
+ throw new Error('relationships not supported in mongodb!');
595
+ }
596
+
597
+ await this.writeFiles({
598
+ sections: entityFiles,
599
+ context: { ...application, ...entity },
600
+ });
601
+
602
+ const webappEnumerationsDir = `${SERVER_NODEJS_SRC_DIR}/src/entities/enumeration/`;
603
+ for (const field of entity.fields.filter(field => field.fieldIsEnum)) {
604
+ const enumInfo = serverEnumInfo(field, entity.clientRootFolder);
605
+ await this.writeFile(
606
+ this.fetchFromInstalledJHipster(
607
+ `client/templates/${TEMPLATES_WEBAPP_SOURCES_DIR}app/entities/enumerations/enum.model.ts.ejs`,
608
+ ),
609
+ `${webappEnumerationsDir}${field.enumFileName}.ts`,
610
+ enumInfo,
611
+ );
612
+ }
613
+ }
614
+ },
615
+ });
616
+ }
617
+
618
+ get [BaseApplicationGenerator.POST_WRITING]() {
619
+ return this.asPostWritingTaskGroup({
620
+ adjustWorkspacePackageJson({ application }) {
621
+ if (application.databaseTypeMongodb) {
622
+ // download the mongod binary at install time, into a directory shared by all workspaces
623
+ this.packageJson.merge({
624
+ allowScripts: {
625
+ 'mongodb-memory-server': true,
626
+ },
627
+ config: {
628
+ mongodbMemoryServer: {
629
+ downloadDir: 'node_modules/.cache/mongodb-memory-server',
630
+ },
631
+ },
632
+ });
633
+ } else {
634
+ // better-sqlite3 (dev and test database) downloads or builds its native binding at install time
635
+ this.packageJson.merge({
636
+ allowScripts: {
637
+ 'better-sqlite3': true,
638
+ },
639
+ });
640
+ }
641
+ if (application.clientFrameworkAngular) {
642
+ this.packageJson.merge({
643
+ overrides: {
644
+ 'browser-sync': application.nodeDependencies['browser-sync'],
645
+ },
646
+ });
647
+ }
648
+ },
649
+ packageJsonE2eScripts({ application }) {
650
+ if (!application.clientFrameworkAny) return;
651
+ // Like the packageJsonE2eScripts of JHipster Spring Boot (java:server): the end-to-end tests wait for a microservice
652
+ // through its gateway, which their microfrontend runs against (its own port is not published by a docker-compose
653
+ // deployment), for the other applications on their own port; longer for a gateway and with OAuth2.
654
+ let waitTimeout = WAIT_TIMEOUT * (application.applicationTypeGateway ? 2 : 1);
655
+ waitTimeout = application.authenticationTypeOauth2 ? waitTimeout * 2 : waitTimeout;
656
+ // With e2eTls, ci:e2e:run sets E2E_SERVER_PROTOCOL to https, the packaged server started with its tls profile.
657
+ const protocol = application.e2eTls ? '${E2E_SERVER_PROTOCOL:-http}' : 'http';
658
+ const endpoint = application.applicationTypeMicroservice
659
+ ? `http-get://127.0.0.1:${application.gatewayServerPort}/${application.endpointPrefix}/management/health/readiness`
660
+ : `${protocol}-get://127.0.0.1:$npm_package_config_backend_port/management/health`;
661
+ this.packageJson.merge({
662
+ scripts: {
663
+ 'ci:server:await': `echo "Waiting for server at port $npm_package_config_backend_port to start" && wait-on -t ${waitTimeout} ${endpoint} && echo "Server at port $npm_package_config_backend_port started"`,
664
+ },
665
+ });
666
+ },
667
+ ignoreClientIssues({ application }) {
668
+ if (application.clientFrameworkNo) return;
669
+ // TODO use source.addEslintConfig
670
+ this.editFile(
671
+ `${application.clientRootDir}/eslint.config.ts`,
672
+ createNeedleCallback({
673
+ needle: 'eslint-add-config',
674
+ contentToAdd: String.raw`{
675
+ files: ["${this.relativeDir(application.clientRootDir, application.clientSrcDir)}**/*"],
676
+ rules: { "@typescript-eslint/no-unsafe-return": "off" },
677
+ },`,
678
+ }),
679
+ );
680
+ },
681
+ });
682
+ }
683
+
684
+ get [BaseApplicationGenerator.POST_WRITING_ENTITIES]() {
685
+ return this.asPostWritingEntitiesTaskGroup({
686
+ async postWritingEntitiesTemplateTask({ entities, source }) {
687
+ for (const entity of entities.filter(entity => !entity.skipServer)) {
688
+ const { nodejsEntityPath, nodejsModulePath, persistClass, entityClass } = entity;
689
+ if (!entity.builtInUserManagement) {
690
+ source.addEntityToNodeConfig({ nodejsEntityPath, persistClass });
691
+ }
692
+ if (!entity.builtIn) {
693
+ source.addEntityToAppModule({ nodejsModulePath, entityClass });
694
+ }
695
+ for (const migration of [entity.nodejsMigration, entity.nodejsConstraintsMigration].filter(Boolean)) {
696
+ source.addMigrationToNodeConfig(migration);
697
+ }
698
+ }
699
+ },
700
+ });
701
+ }
702
+ }