@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,5 @@
1
+ import { asCommand } from 'generator-jhipster';
2
+
3
+ export default asCommand({
4
+ configs: {},
5
+ });
@@ -0,0 +1,83 @@
1
+ import BaseApplicationGenerator from 'generator-jhipster/generators/base-application';
2
+ import { hibernateSnakeCase } from 'generator-jhipster/generators/server/support';
3
+ import { prepareSqlApplicationProperties } from 'generator-jhipster/generators/spring-boot/generators/data-relational/support';
4
+
5
+ import { SERVER_NODEJS_SRC_DIR } from '../../../generator-nodejs-constants.js';
6
+
7
+ export default class extends BaseApplicationGenerator {
8
+ constructor(args, opts, features) {
9
+ super(args, opts, { ...features, sbsBlueprint: true });
10
+ }
11
+
12
+ async beforeQueue() {
13
+ // Node server is a Typescript server, we need typescript preparation.
14
+ await this.dependsOnBootstrap('client');
15
+ await this.dependsOnBootstrap('server');
16
+ }
17
+
18
+ get [BaseApplicationGenerator.LOADING]() {
19
+ return this.asLoadingTaskGroup({
20
+ async loadingTemplateTask({ applicationDefaults }) {
21
+ applicationDefaults({
22
+ temporaryDir: 'tmp/',
23
+ dockerServicesDir: 'docker/',
24
+ nodeServerRootDir: `${SERVER_NODEJS_SRC_DIR}/`,
25
+ jhiTablePrefix: ({ jhiPrefix }) => hibernateSnakeCase(jhiPrefix),
26
+ clientPackageManager: 'npm',
27
+ dbPortValue: undefined,
28
+ // As in JHipster's Spring Boot application, syncUserWithIdp is disabled by default, enabled for a gateway or
29
+ // when an entity has a relationship with User (JHipster only derives it for a Java backend). Delayed until
30
+ // anyEntityHasRelationshipWithUser is defined, before JHipster derives the built-in entities from it.
31
+ syncUserWithIdp: ({ authenticationType, applicationType, anyEntityHasRelationshipWithUser }) =>
32
+ authenticationType === 'oauth2' && (applicationType === 'gateway' || anyEntityHasRelationshipWithUser),
33
+ // The scripts of the client run from the root package.json with --prefix, not -w (the e2e default): an application
34
+ // of a JHipster workspace is itself a workspace, and npm resolves -w from the root of the outer one.
35
+ clientNpmRun: ({ clientRootDir }) => (clientRootDir ? `npm --prefix ${clientRootDir} run` : 'npm run'),
36
+ clientNgCommand: ({ clientRootDir }) => (clientRootDir ? `npm --prefix ${clientRootDir} exec -- ng` : 'ng'),
37
+ });
38
+ },
39
+ });
40
+ }
41
+
42
+ get [BaseApplicationGenerator.PREPARING]() {
43
+ return this.asPreparingTaskGroup({
44
+ prettierFolders({ application }) {
45
+ // The prettier:check and prettier:format scripts of the root package.json cover the server and the client
46
+ // workspaces (JHipster only adds the client sources, and the build plugins of Angular at the root).
47
+ const { nodeServerRootDir, clientRootDir } = application;
48
+ const folders = [nodeServerRootDir, ...['src', 'test', 'e2e', 'scripts'].map(dir => `${nodeServerRootDir}${dir}/**/`)];
49
+ if (application.clientFrameworkAny) {
50
+ folders.push(clientRootDir);
51
+ if (application.clientFrameworkAngular) {
52
+ folders.push(`${clientRootDir}build-plugins/**/`);
53
+ }
54
+ }
55
+ application.prettierFolders.push(...folders.filter(folder => !application.prettierFolders.includes(folder)));
56
+ },
57
+ preparing({ application, applicationDefaults }) {
58
+ if (application.databaseTypeSql) {
59
+ prepareSqlApplicationProperties({ application });
60
+ } else {
61
+ applicationDefaults({
62
+ prodDatabaseName: undefined,
63
+ prodDatabaseUsername: undefined,
64
+ prodDatabasePassword: undefined,
65
+ devDatabaseName: undefined,
66
+ devDatabaseUsername: undefined,
67
+ devDatabasePassword: undefined,
68
+ });
69
+ }
70
+ },
71
+ });
72
+ }
73
+
74
+ get [BaseApplicationGenerator.DEFAULT]() {
75
+ return this.asDefaultTaskGroup({
76
+ postPreparing({ application }) {
77
+ if (application.authority) {
78
+ application.authority.skipClient = !application.clientFrameworkAngular;
79
+ }
80
+ },
81
+ });
82
+ }
83
+ }
@@ -0,0 +1,2 @@
1
+ export { default } from './generator.js';
2
+ export { default as command } from './command.js';
@@ -0,0 +1,2 @@
1
+ export { default } from './generator.js';
2
+ export { default as command } from './command.js';
@@ -0,0 +1,76 @@
1
+ {
2
+ "dependencies": {
3
+ "@nestjs-modules/mailer": "3.0.2",
4
+ "@nestjs/axios": "12.0.1",
5
+ "@nestjs/common": "12.2.0",
6
+ "@nestjs/config": "12.0.1",
7
+ "@nestjs/core": "12.2.0",
8
+ "@nestjs/jwt": "12.0.3",
9
+ "@nestjs/passport": "12.0.0",
10
+ "@nestjs/platform-express": "12.2.0",
11
+ "@nestjs/schedule": "12.0.2",
12
+ "@nestjs/serve-static": "12.0.0",
13
+ "@nestjs/swagger": "12.0.4",
14
+ "@nestjs/terminus": "12.1.0",
15
+ "@nestjs/typeorm": "12.0.2",
16
+ "@rocketsoftware/eureka-js-client": "4.5.9",
17
+ "bcrypt": "6.0.0",
18
+ "better-sqlite3": "13.0.3",
19
+ "class-transformer": "0.5.1",
20
+ "class-validator": "0.15.1",
21
+ "cloud-config-client": "1.6.2",
22
+ "consul": "2.0.1",
23
+ "dotenv": "18.0.9",
24
+ "express": "5.3.0",
25
+ "express-session": "1.19.0",
26
+ "handlebars": "4.7.10",
27
+ "js-yaml": "5.5.0",
28
+ "jwks-rsa": "4.1.0",
29
+ "jwt-decode": "4.0.0",
30
+ "mongodb": "7.7.0",
31
+ "mongodb-memory-server": "11.3.0",
32
+ "mssql": "12.7.11",
33
+ "mysql2": "3.24.6",
34
+ "oracledb": "7.0.1",
35
+ "passport": "0.7.0",
36
+ "passport-jwt": "4.0.1",
37
+ "passport-oauth2": "1.8.0",
38
+ "pg": "8.23.1",
39
+ "prom-client": "15.1.3",
40
+ "qs": "6.16.1",
41
+ "reflect-metadata": "0.2.2",
42
+ "rxjs": "7.8.2",
43
+ "swagger-ui-express": "5.0.1",
44
+ "typeorm": "1.1.2"
45
+ },
46
+ "devDependencies": {
47
+ "@eslint/js": "10.0.1",
48
+ "@nestjs/cli": "12.0.10",
49
+ "@nestjs/schematics": "12.0.9",
50
+ "@nestjs/testing": "12.2.0",
51
+ "@types/bcrypt": "6.0.0",
52
+ "@types/express": "5.0.6",
53
+ "@types/express-serve-static-core": "5.1.3",
54
+ "@types/express-session": "1.19.0",
55
+ "@types/node": "24.19.2",
56
+ "@types/passport": "1.0.17",
57
+ "@types/passport-jwt": "4.0.1",
58
+ "@types/passport-oauth2": "1.8.0",
59
+ "@types/qs": "6.15.1",
60
+ "@types/superagent": "8.1.11",
61
+ "@types/supertest": "7.2.1",
62
+ "@vitest/coverage-v8": "5.0.5",
63
+ "eslint": "10.13.0",
64
+ "eslint-config-prettier": "10.1.8",
65
+ "eslint-plugin-prettier": "5.5.7",
66
+ "globals": "17.13.0",
67
+ "rimraf": "5.0.10",
68
+ "sonarqube-scanner": "5.0.2",
69
+ "supertest": "7.3.1",
70
+ "typescript": "6.0.3",
71
+ "typescript-eslint": "8.72.0",
72
+ "vite": "8.3.5",
73
+ "vitest": "5.0.5"
74
+ },
75
+ "packageManager": "npm@11"
76
+ }
@@ -0,0 +1,54 @@
1
+ /**
2
+ * The fake values of the fields of an entity as the API exchanges them, the values of the JSON of JHipster Spring Boot,
3
+ * for the tests storing an entity in the database and reading it back.
4
+ */
5
+
6
+ /** The value of a field in a request and in the response reading it back. */
7
+ export const apiFakeValue = field => {
8
+ // An ISO-8601 duration (PT10M), the JSON of a Duration of JHipster Spring Boot.
9
+ if (field.fieldType === 'Duration') return field.generateFakeData('cypress');
10
+ const value = field.generateFakeData('json-serializable');
11
+ // The text of a TextBlob, a String of JHipster Spring Boot: json-serializable gives the base64 of any byte[].
12
+ if (field.fieldTypeBlobContent === 'text' && typeof value === 'string') return Buffer.from(value, 'base64').toString();
13
+ // Seconds without milliseconds: the datetime columns of MySQL do not keep them.
14
+ if (value instanceof Date) return `${value.toISOString().slice(0, 19)}.000Z`;
15
+ return value;
16
+ };
17
+
18
+ /** The content type of a binary blob, like the JHipster clients send it. */
19
+ const contentTypeOf = field => (field.fieldTypeBlobContent === 'image' ? 'image/png' : 'application/octet-stream');
20
+
21
+ /**
22
+ * The values of the fields of an entity in a request (and their content types), and the fields compared approximately:
23
+ * a Float is a single precision number of some databases (MySQL).
24
+ */
25
+ export const apiFakeEntity = entity => {
26
+ const values = {};
27
+ for (const field of entity.fields.filter(field => !field.id && !field.transient && !field.autoGenerate)) {
28
+ const value = apiFakeValue(field);
29
+ if (value === undefined || value === null) continue;
30
+ values[field.fieldName] = value;
31
+ if (['byte[]', 'ByteBuffer'].includes(field.fieldType) && field.fieldTypeBlobContent !== 'text') {
32
+ values[`${field.fieldName}ContentType`] = contentTypeOf(field);
33
+ }
34
+ }
35
+ const approximateFields = entity.fields
36
+ .filter(field => field.fieldType === 'Float' && field.fieldName in values)
37
+ .map(field => field.fieldName);
38
+ return { values, approximateFields };
39
+ };
40
+
41
+ /**
42
+ * The mutations of a relationship of an entity: the values of the related record its relationship test of the database
43
+ * end-to-end tests posts, as the API exchanges them, drawn with a seed of that test. JHipster keeps the unique values of a
44
+ * field for the whole generation: the same seed in every test would draw them again, until a unique field is left without
45
+ * one (from the fifth relationship to the same entity).
46
+ */
47
+ export const mutateRelatedValues = entity => ({
48
+ __override__: false,
49
+ nodejsRelatedValues: ({ otherEntity, propertyName }) => {
50
+ if (otherEntity.builtIn) return undefined;
51
+ otherEntity.resetFakerSeed(`nodejs-database-e2e-${entity.entityInstance}-${propertyName}`);
52
+ return apiFakeEntity(otherEntity).values;
53
+ },
54
+ });
@@ -0,0 +1,73 @@
1
+ /** The precision and the scale of a BigDecimal column of JHipster Spring Boot (decimal(21,2)). */
2
+ export const bigDecimalPrecision = { precision: 21, scale: 2 };
3
+
4
+ /**
5
+ * The transformer of the column of a field (src/common/database/column-transformers.ts), so the API gives the values of the
6
+ * JSON of JHipster Spring Boot whatever the SQL database: undefined when the driver gives them already.
7
+ * - number: a bigint or a decimal, which the PostgreSQL and MySQL drivers give as a string;
8
+ * - duration: the nanoseconds of a bigint column, an ISO-8601 duration (PT1H30M) in the API;
9
+ * - blob: a blob column, which the drivers give as a Buffer, the base64 or text string the API received.
10
+ */
11
+ export const columnTransformer = ({ fieldType, nodejsColumnType }) => {
12
+ if (fieldType === 'Duration') return 'duration';
13
+ if (['Long', 'BigDecimal'].includes(fieldType)) return 'number';
14
+ if (nodejsColumnType === 'blob') return 'blob';
15
+ return undefined;
16
+ };
17
+
18
+ /**
19
+ * The databases with column types of JHipster Spring Boot better-sqlite3 (dev and test) has not, chosen at runtime by
20
+ * src/common/database/column-types.ts: the long blobs and texts and the microseconds of MySQL and MariaDB.
21
+ */
22
+ const runtimeColumnTypeDatabases = ['mysql', 'mariadb'];
23
+
24
+ /** Whether the columns of an application get their types at runtime (see runtimeColumnTypeDatabases). */
25
+ export const hasRuntimeColumnTypes = ({ databaseTypeSql, prodDatabaseType }) =>
26
+ Boolean(databaseTypeSql) && runtimeColumnTypeDatabases.includes(prodDatabaseType);
27
+
28
+ /** Whether the column of a field has a type chosen at runtime: a blob, a text, or the precision of an instant. */
29
+ const runtimeColumnType = field => ['blob', 'text'].includes(field.nodejsColumnType);
30
+ const runtimeDatetimePrecision = field => ['Instant', 'ZonedDateTime'].includes(field.fieldType);
31
+
32
+ /** The helpers of src/common/database/column-types.ts the @Column decorator of a field uses. */
33
+ export const fieldColumnTypeImports = (field, application) => {
34
+ if (!hasRuntimeColumnTypes(application)) return [];
35
+ return [runtimeColumnType(field) && 'columnType', runtimeDatetimePrecision(field) && 'datetimePrecision'].filter(Boolean);
36
+ };
37
+
38
+ /**
39
+ * The options of the @Column decorator of a field. A MongoDB column has no name: TypeORM writes the documents by the names
40
+ * of the properties and reads them by the names of the columns, so a document would be read without its fields.
41
+ */
42
+ export const fieldColumnOptions = (field, application) => {
43
+ const { databaseTypeSql } = application;
44
+ const { fieldValidationRequired: required, fieldValidationUnique: unique, fieldValidationMaxlength: maxlength } = field;
45
+ const runtime = hasRuntimeColumnTypes(application);
46
+ const options = [];
47
+ if (field.nodejsColumnType) {
48
+ options.push(
49
+ runtime && runtimeColumnType(field) ? `type: columnType('${field.nodejsColumnType}')` : `type: '${field.nodejsColumnType}'`,
50
+ );
51
+ }
52
+ if (runtime && runtimeDatetimePrecision(field)) options.push('precision: datetimePrecision()');
53
+ if (databaseTypeSql) options.push(`name: '${field.fieldNameAsDatabaseColumn}'`);
54
+ if (field.fieldIsEnum) {
55
+ options.push(`enum: ${field.fieldType}`);
56
+ } else if (field.fieldType === 'BigDecimal') {
57
+ options.push(`precision: ${bigDecimalPrecision.precision}`, `scale: ${bigDecimalPrecision.scale}`);
58
+ } else if (!['Instant', 'ZonedDateTime', 'LocalDate'].includes(field.fieldType) && maxlength) {
59
+ options.push(`length: ${field.fieldValidateRulesMaxlength}`);
60
+ }
61
+ if (!required) options.push('nullable: true');
62
+ if (unique) options.push('unique: true');
63
+ if (field.nodejsColumnTransformer) options.push(`transformer: ${field.nodejsColumnTransformer}Transformer`);
64
+ return options;
65
+ };
66
+
67
+ /** The options of the @Column decorator of the content type of a binary blob. */
68
+ export const contentTypeColumnOptions = (field, { databaseTypeSql }) => {
69
+ return [
70
+ databaseTypeSql && `name: '${field.fieldNameAsDatabaseColumn}_content_type'`,
71
+ !field.fieldValidationRequired && 'nullable: true',
72
+ ].filter(Boolean);
73
+ };
@@ -0,0 +1,24 @@
1
+ /**
2
+ * The default port of each production database type of JHipster, the port of its docker service: the database of the
3
+ * application-dev.yml and application-prod.yml files.
4
+ */
5
+ export const databasePorts = {
6
+ postgresql: 5432,
7
+ mysql: 3306,
8
+ mariadb: 3306,
9
+ mssql: 1433,
10
+ oracle: 1521,
11
+ mongodb: 27017,
12
+ };
13
+
14
+ /** The default port of the production database of an application. */
15
+ export const getDatabasePort = ({ databaseType, prodDatabaseType = databaseType }) => databasePorts[prodDatabaseType];
16
+
17
+ /** The embedded development databases of the NodeJS server: SQLite, on disk or in memory. */
18
+ const embeddedDevDatabaseTypes = ['sqlite', 'sqliteMemory'];
19
+
20
+ /** The TypeORM type of the development database: better-sqlite3 for an embedded one, else the server type. */
21
+ export const getNodeDevDatabaseType = ({ databaseType, devDatabaseType = databaseType }) => {
22
+ if (embeddedDevDatabaseTypes.includes(devDatabaseType)) return 'better-sqlite3';
23
+ return devDatabaseType === 'postgresql' ? 'postgres' : devDatabaseType;
24
+ };
@@ -0,0 +1,32 @@
1
+ /**
2
+ * The roles of the entities, like the @PreAuthorize of the resources of JHipster Spring Boot (entitySpringPreAuthorize and
3
+ * entitySpringReadPreAuthorize of its spring-boot generator): the roles of entityAuthority (@EntityAuthority of the JDL,
4
+ * ROLE_ADMIN for an admin entity, like the built-in User and Authority) write and read, the roles of entityReadAuthority
5
+ * (@EntityReadAuthority) only read. Without them, any authenticated user.
6
+ */
7
+
8
+ /** The roles of a comma separated authority of JHipster. */
9
+ const rolesOf = authority =>
10
+ String(authority ?? '')
11
+ .split(',')
12
+ .map(role => role.trim())
13
+ .filter(Boolean);
14
+
15
+ /** The TypeScript of the arguments of a @Roles decorator, undefined without roles. */
16
+ const rolesLiteral = roles => (roles.length > 0 ? roles.map(role => `'${role}'`).join(', ') : undefined);
17
+
18
+ /** The mutations of an entity (entityDefaults), delayed until the entity is prepared. */
19
+ export const mutateEntityAuthorities = {
20
+ __override__: false,
21
+ // The roles of the creations, the updates and the deletions.
22
+ nodejsWriteRoles: ({ entityAuthority }, { delayMarker }) => delayMarker ?? rolesLiteral(rolesOf(entityAuthority)),
23
+ // The roles of the reads: the ones of the writes and the ones of entityReadAuthority.
24
+ nodejsReadRoles: ({ entityAuthority, entityReadAuthority }, { delayMarker }) =>
25
+ delayMarker ?? rolesLiteral([...new Set([...rolesOf(entityAuthority), ...rolesOf(entityReadAuthority)])]),
26
+ // The roles that only read, which the tests check refused on the writes.
27
+ nodejsReadOnlyRoles: ({ entityAuthority, entityReadAuthority }, { delayMarker }) => {
28
+ if (delayMarker) return delayMarker;
29
+ const writeRoles = rolesOf(entityAuthority);
30
+ return rolesLiteral(rolesOf(entityReadAuthority).filter(role => !writeRoles.includes(role)));
31
+ },
32
+ };
@@ -0,0 +1,13 @@
1
+ /**
2
+ * The files of an entity, from the src folder of the server, in its feature module: an entity of the JDL in its own folder
3
+ * of src/entities, the built-in User and Authority in src/users, with the users module.
4
+ */
5
+ const entityFolder = ({ builtIn, entityFileName }) => (builtIn ? 'users' : `entities/${entityFileName}`);
6
+
7
+ /** The mutations of an entity (entityDefaults): the paths its imports, its needles and its cleanups use. */
8
+ export const mutateEntityPaths = {
9
+ __override__: false,
10
+ nodejsEntityPath: entity => `${entityFolder(entity)}/${entity.entityFileName}.entity.ts`,
11
+ nodejsDtoPath: entity => `${entityFolder(entity)}/dto/${entity.entityFileName}.dto.ts`,
12
+ nodejsModulePath: entity => `${entityFolder(entity)}/${entity.entityFileName}.module.ts`,
13
+ };
@@ -0,0 +1,11 @@
1
+ import { getEnumInfo } from 'generator-jhipster/generators/base-application/support';
2
+
3
+ /**
4
+ * The enum of a field as the server exchanges and stores it, like JHipster Spring Boot: a Java enum is written in JSON
5
+ * and stored (`@Enumerated(EnumType.STRING)`) by its name, its custom value (`LOW (low_level)`) being only a label of the
6
+ * client. Each value of the TypeScript enum is its name.
7
+ */
8
+ export const serverEnumInfo = (field, clientRootFolder) => {
9
+ const enumInfo = getEnumInfo(field, clientRootFolder);
10
+ return { ...enumInfo, enumValues: enumInfo.enumValues.map(enumValue => ({ ...enumValue, value: enumValue.name })) };
11
+ };
@@ -0,0 +1,9 @@
1
+ export * from './database.js';
2
+ export * from './mail-templates.js';
3
+ export * from './columns.js';
4
+ export * from './api-fake-data.js';
5
+ export * from './migrations.js';
6
+ export * from './entity-paths.js';
7
+ export * from './entity-authorities.js';
8
+ export * from './enums.js';
9
+ export * from './validators.js';
@@ -0,0 +1,82 @@
1
+ /**
2
+ * A Thymeleaf expression of the mail templates of JHipster Spring Boot as Handlebars: a message (#{key(${a.b})}) as the
3
+ * message helper of the server, a variable (${a.b}), a link with literal substitutions (@{|${baseUrl}/path|}), the
4
+ * language of the mail (${#locale.language}). The variables of a th:with give their converted value.
5
+ */
6
+ const toHandlebarsValue = (expression, variables) => {
7
+ const value = expression.trim();
8
+ if (value === '${#locale.language}') return '{{langKey}}';
9
+ let match = /^\$\{([\w.]+)\}$/.exec(value);
10
+ if (match) {
11
+ return variables[match[1]] ?? `{{${match[1]}}}`;
12
+ }
13
+ match = /^#\{([\w.]+)(?:\((.*)\))?\}$/.exec(value);
14
+ if (match) {
15
+ const parameters = (match[2] ?? '')
16
+ .split(',')
17
+ .map(parameter => parameter.trim())
18
+ .filter(Boolean)
19
+ .map(parameter => {
20
+ const variable = /^\$\{([\w.]+)\}$/.exec(parameter);
21
+ if (!variable) throw new Error(`Unsupported message parameter ${parameter}`);
22
+ return ` ${variable[1]}`;
23
+ });
24
+ return `{{message '${match[1]}'${parameters.join('')}}}`;
25
+ }
26
+ match = /^\(?@\{\|(.*)\|\}\)?$/.exec(value);
27
+ if (match) {
28
+ return match[1].replace(/\$\{([\w.]+)\}/g, (_, variable) => variables[variable] ?? `{{${variable}}}`);
29
+ }
30
+ throw new Error(`Unsupported Thymeleaf expression ${value}`);
31
+ };
32
+
33
+ /** The attributes of a tag with their th: attributes converted, and the converted th:text if any. */
34
+ const convertAttributes = attributesText => {
35
+ const attributes = [...attributesText.matchAll(/([\w:-]+)="([^"]*)"/g)].map(([, name, value]) => ({ name, value }));
36
+ const variables = {};
37
+ for (const { value } of attributes.filter(attribute => attribute.name === 'th:with')) {
38
+ for (const definition of value.split(/,(?![^(]*\))/)) {
39
+ const [, variable, expression] = /^\s*(\w+)\s*=\s*(.*)$/.exec(definition) ?? [];
40
+ if (!variable) throw new Error(`Unsupported th:with ${value}`);
41
+ variables[variable] = toHandlebarsValue(expression, variables);
42
+ }
43
+ }
44
+ let text;
45
+ const kept = [];
46
+ for (const { name, value } of attributes) {
47
+ if (name === 'th:with' || name.startsWith('xmlns:th')) continue;
48
+ if (name === 'th:text') {
49
+ text = toHandlebarsValue(value, variables);
50
+ } else if (name.startsWith('th:')) {
51
+ kept.push({ name: name.substring(3), value: toHandlebarsValue(value, variables) });
52
+ } else if (!attributes.some(attribute => attribute.name === `th:${name}`)) {
53
+ kept.push({ name, value });
54
+ }
55
+ }
56
+ return { attributes: kept.map(({ name, value }) => ` ${name}="${value}"`).join(''), text };
57
+ };
58
+
59
+ /**
60
+ * Converts a mail template of JHipster Spring Boot (Thymeleaf) to a Handlebars template of the mail module, for the
61
+ * subset its account mails use: th:text on the elements without children, the other th: attributes (th:href, th:lang)
62
+ * and the th:with variables. The output only interpolates values, escaped, and calls the message helper: it runs no
63
+ * code. An expression or an attribute out of that subset fails the generation instead of giving a broken template.
64
+ */
65
+ export const thymeleafMailToHandlebars = content => {
66
+ const result = content
67
+ // The leaf elements with a th:text, their content replaced by its value.
68
+ .replace(/<(\w+)((?:\s+[\w:-]+="[^"]*")*)\s*>[^<]*<\/\1>/g, (element, tag, attributesText) => {
69
+ if (!attributesText.includes('th:text=')) return element;
70
+ const { attributes, text } = convertAttributes(attributesText);
71
+ return `<${tag}${attributes}>${text}</${tag}>`;
72
+ })
73
+ // The other tags with th: attributes.
74
+ .replace(/<(\w+)((?:\s+[\w:-]+="[^"]*")*)\s*(\/?)>/g, (tag, name, attributesText, selfClosing) => {
75
+ if (!attributesText.includes('th:')) return tag;
76
+ const { attributes, text } = convertAttributes(attributesText);
77
+ if (text !== undefined) throw new Error(`Unsupported th:text on the element ${name} with children`);
78
+ return `<${name}${attributes}${selfClosing ? ' /' : ''}>`;
79
+ });
80
+ if (/\sth:|xmlns:th/.test(result)) throw new Error('Unsupported Thymeleaf attribute left in the mail template');
81
+ return result;
82
+ };