@lenne.tech/nest-server 10.0.0 → 10.0.3

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 (214) hide show
  1. package/dist/config.env.js +29 -17
  2. package/dist/config.env.js.map +1 -1
  3. package/dist/core/common/args/filter.args.js +3 -3
  4. package/dist/core/common/args/filter.args.js.map +1 -1
  5. package/dist/core/common/args/pagination.args.js +6 -6
  6. package/dist/core/common/args/pagination.args.js.map +1 -1
  7. package/dist/core/common/decorators/restricted.decorator.js +15 -17
  8. package/dist/core/common/decorators/restricted.decorator.js.map +1 -1
  9. package/dist/core/common/filters/http-exception-log.filter.js +1 -3
  10. package/dist/core/common/filters/http-exception-log.filter.js.map +1 -1
  11. package/dist/core/common/helpers/db.helper.js +14 -14
  12. package/dist/core/common/helpers/db.helper.js.map +1 -1
  13. package/dist/core/common/helpers/file.helper.js +2 -2
  14. package/dist/core/common/helpers/file.helper.js.map +1 -1
  15. package/dist/core/common/helpers/filter.helper.d.ts +2 -2
  16. package/dist/core/common/helpers/filter.helper.js +1 -1
  17. package/dist/core/common/helpers/filter.helper.js.map +1 -1
  18. package/dist/core/common/helpers/graphql.helper.js +1 -1
  19. package/dist/core/common/helpers/graphql.helper.js.map +1 -1
  20. package/dist/core/common/helpers/input.helper.js +31 -38
  21. package/dist/core/common/helpers/input.helper.js.map +1 -1
  22. package/dist/core/common/helpers/model.helper.js +7 -7
  23. package/dist/core/common/helpers/model.helper.js.map +1 -1
  24. package/dist/core/common/helpers/service.helper.js +2 -2
  25. package/dist/core/common/helpers/service.helper.js.map +1 -1
  26. package/dist/core/common/inputs/combined-filter.input.js +3 -3
  27. package/dist/core/common/inputs/combined-filter.input.js.map +1 -1
  28. package/dist/core/common/inputs/core-input.input.js +1 -1
  29. package/dist/core/common/inputs/core-input.input.js.map +1 -1
  30. package/dist/core/common/inputs/filter.input.js +3 -3
  31. package/dist/core/common/inputs/filter.input.js.map +1 -1
  32. package/dist/core/common/inputs/single-filter.input.js +4 -4
  33. package/dist/core/common/inputs/single-filter.input.js.map +1 -1
  34. package/dist/core/common/inputs/sort.input.js +1 -1
  35. package/dist/core/common/inputs/sort.input.js.map +1 -1
  36. package/dist/core/common/interceptors/check-security.interceptor.d.ts +1 -1
  37. package/dist/core/common/interceptors/check-security.interceptor.js +2 -2
  38. package/dist/core/common/interceptors/check-security.interceptor.js.map +1 -1
  39. package/dist/core/common/interfaces/server-options.interface.d.ts +27 -0
  40. package/dist/core/common/models/core-model.model.js.map +1 -1
  41. package/dist/core/common/models/core-persistence.model.js +3 -3
  42. package/dist/core/common/models/core-persistence.model.js.map +1 -1
  43. package/dist/core/common/pipes/map-and-validate.pipe.d.ts +1 -1
  44. package/dist/core/common/pipes/map-and-validate.pipe.js +1 -1
  45. package/dist/core/common/pipes/map-and-validate.pipe.js.map +1 -1
  46. package/dist/core/common/scalars/any.scalar.js +2 -2
  47. package/dist/core/common/scalars/any.scalar.js.map +1 -1
  48. package/dist/core/common/scalars/date-timestamp.scalar.js +1 -1
  49. package/dist/core/common/scalars/date-timestamp.scalar.js.map +1 -1
  50. package/dist/core/common/scalars/date.scalar.js +1 -1
  51. package/dist/core/common/scalars/date.scalar.js.map +1 -1
  52. package/dist/core/common/scalars/json.scalar.js +2 -2
  53. package/dist/core/common/scalars/json.scalar.js.map +1 -1
  54. package/dist/core/common/services/config.service.js +7 -7
  55. package/dist/core/common/services/config.service.js.map +1 -1
  56. package/dist/core/common/services/core-cron-jobs.service.js +5 -5
  57. package/dist/core/common/services/core-cron-jobs.service.js.map +1 -1
  58. package/dist/core/common/services/crud.service.js +1 -1
  59. package/dist/core/common/services/crud.service.js.map +1 -1
  60. package/dist/core/common/services/mailjet.service.js +5 -5
  61. package/dist/core/common/services/mailjet.service.js.map +1 -1
  62. package/dist/core/common/services/module.service.js.map +1 -1
  63. package/dist/core/common/services/template.service.js +3 -3
  64. package/dist/core/common/services/template.service.js.map +1 -1
  65. package/dist/core/common/types/core-model-constructor.type.d.ts +2 -2
  66. package/dist/core/modules/auth/core-auth.module.js +3 -3
  67. package/dist/core/modules/auth/core-auth.module.js.map +1 -1
  68. package/dist/core/modules/auth/core-auth.resolver.js +5 -5
  69. package/dist/core/modules/auth/core-auth.resolver.js.map +1 -1
  70. package/dist/core/modules/auth/guards/auth.guard.js +4 -4
  71. package/dist/core/modules/auth/guards/auth.guard.js.map +1 -1
  72. package/dist/core/modules/auth/guards/roles.guard.js +1 -1
  73. package/dist/core/modules/auth/guards/roles.guard.js.map +1 -1
  74. package/dist/core/modules/auth/services/core-auth.service.js +5 -5
  75. package/dist/core/modules/auth/services/core-auth.service.js.map +1 -1
  76. package/dist/core/modules/auth/strategies/jwt.strategy.js.map +1 -1
  77. package/dist/core/modules/auth/tokens.decorator.js +2 -2
  78. package/dist/core/modules/auth/tokens.decorator.js.map +1 -1
  79. package/dist/core/modules/file/core-file-info.model.js +2 -2
  80. package/dist/core/modules/file/core-file-info.model.js.map +1 -1
  81. package/dist/core/modules/file/core-file.controller.d.ts +1 -2
  82. package/dist/core/modules/file/core-file.controller.js +3 -6
  83. package/dist/core/modules/file/core-file.controller.js.map +1 -1
  84. package/dist/core/modules/file/core-file.service.js +1 -1
  85. package/dist/core/modules/file/core-file.service.js.map +1 -1
  86. package/dist/core/modules/file/interfaces/file-upload.interface.d.ts +1 -1
  87. package/dist/core/modules/health-check/core-health-check-result.model.d.ts +8 -0
  88. package/dist/core/modules/health-check/core-health-check-result.model.js +53 -0
  89. package/dist/core/modules/health-check/core-health-check-result.model.js.map +1 -0
  90. package/dist/core/modules/health-check/core-health-check.controller.d.ts +6 -0
  91. package/dist/core/modules/health-check/core-health-check.controller.js +33 -0
  92. package/dist/core/modules/health-check/core-health-check.controller.js.map +1 -0
  93. package/dist/core/modules/health-check/core-health-check.module.d.ts +2 -0
  94. package/dist/core/modules/health-check/core-health-check.module.js +24 -0
  95. package/dist/core/modules/health-check/core-health-check.module.js.map +1 -0
  96. package/dist/core/modules/health-check/core-health-check.resolver.d.ts +6 -0
  97. package/dist/core/modules/health-check/core-health-check.resolver.js +38 -0
  98. package/dist/core/modules/health-check/core-health-check.resolver.js.map +1 -0
  99. package/dist/core/modules/health-check/core-health-check.service.d.ts +11 -0
  100. package/dist/core/modules/health-check/core-health-check.service.js +52 -0
  101. package/dist/core/modules/health-check/core-health-check.service.js.map +1 -0
  102. package/dist/core/modules/user/core-user.model.js +4 -4
  103. package/dist/core/modules/user/core-user.model.js.map +1 -1
  104. package/dist/core/modules/user/core-user.service.js +2 -2
  105. package/dist/core/modules/user/core-user.service.js.map +1 -1
  106. package/dist/core/modules/user/inputs/core-user.input.js +1 -1
  107. package/dist/core/modules/user/inputs/core-user.input.js.map +1 -1
  108. package/dist/core.module.js +10 -5
  109. package/dist/core.module.js.map +1 -1
  110. package/dist/index.d.ts +5 -0
  111. package/dist/index.js +5 -0
  112. package/dist/index.js.map +1 -1
  113. package/dist/main.js +1 -1
  114. package/dist/main.js.map +1 -1
  115. package/dist/server/modules/auth/auth.service.js +1 -1
  116. package/dist/server/modules/auth/auth.service.js.map +1 -1
  117. package/dist/server/modules/file/file.controller.js +1 -1
  118. package/dist/server/modules/file/file.controller.js.map +1 -1
  119. package/dist/server/modules/file/file.resolver.js +2 -2
  120. package/dist/server/modules/file/file.resolver.js.map +1 -1
  121. package/dist/server/modules/file/file.service.js +1 -1
  122. package/dist/server/modules/file/file.service.js.map +1 -1
  123. package/dist/server/modules/file/multer-config.service.js +1 -1
  124. package/dist/server/modules/file/multer-config.service.js.map +1 -1
  125. package/dist/server/modules/user/avatar.controller.js +1 -1
  126. package/dist/server/modules/user/avatar.controller.js.map +1 -1
  127. package/dist/server/modules/user/user.resolver.js +1 -1
  128. package/dist/server/modules/user/user.resolver.js.map +1 -1
  129. package/dist/server/modules/user/user.service.js +3 -3
  130. package/dist/server/modules/user/user.service.js.map +1 -1
  131. package/dist/templates/index.ejs +2 -0
  132. package/dist/templates/password-reset.ejs +3 -0
  133. package/dist/templates/welcome.ejs +3 -0
  134. package/dist/test/test.helper.d.ts +1 -1
  135. package/dist/test/test.helper.js +7 -7
  136. package/dist/test/test.helper.js.map +1 -1
  137. package/dist/tsconfig.build.tsbuildinfo +1 -1
  138. package/package.json +28 -25
  139. package/src/config.env.ts +32 -20
  140. package/src/core/common/args/filter.args.ts +4 -4
  141. package/src/core/common/args/pagination.args.ts +7 -7
  142. package/src/core/common/decorators/graphql-service-options.decorator.ts +2 -2
  143. package/src/core/common/decorators/graphql-user.decorator.ts +1 -1
  144. package/src/core/common/decorators/rest-user.decorator.ts +1 -1
  145. package/src/core/common/decorators/restricted.decorator.ts +18 -18
  146. package/src/core/common/filters/http-exception-log.filter.ts +4 -4
  147. package/src/core/common/helpers/db.helper.ts +35 -40
  148. package/src/core/common/helpers/decorator.helper.ts +1 -1
  149. package/src/core/common/helpers/file.helper.ts +2 -2
  150. package/src/core/common/helpers/filter.helper.ts +7 -8
  151. package/src/core/common/helpers/graphql.helper.ts +6 -6
  152. package/src/core/common/helpers/input.helper.ts +54 -61
  153. package/src/core/common/helpers/model.helper.ts +33 -41
  154. package/src/core/common/helpers/service.helper.ts +8 -8
  155. package/src/core/common/inputs/combined-filter.input.ts +4 -4
  156. package/src/core/common/inputs/core-input.input.ts +2 -2
  157. package/src/core/common/inputs/filter.input.ts +4 -4
  158. package/src/core/common/inputs/single-filter.input.ts +4 -4
  159. package/src/core/common/inputs/sort.input.ts +1 -1
  160. package/src/core/common/interceptors/check-response.interceptor.ts +1 -1
  161. package/src/core/common/interceptors/check-security.interceptor.ts +5 -5
  162. package/src/core/common/interfaces/server-options.interface.ts +31 -0
  163. package/src/core/common/models/core-model.model.ts +6 -4
  164. package/src/core/common/models/core-persistence.model.ts +3 -3
  165. package/src/core/common/pipes/map-and-validate.pipe.ts +2 -2
  166. package/src/core/common/scalars/any.scalar.ts +2 -2
  167. package/src/core/common/scalars/date-timestamp.scalar.ts +1 -2
  168. package/src/core/common/scalars/date.scalar.ts +1 -2
  169. package/src/core/common/scalars/json.scalar.ts +4 -4
  170. package/src/core/common/services/config.service.ts +16 -16
  171. package/src/core/common/services/core-cron-jobs.service.ts +7 -7
  172. package/src/core/common/services/crud.service.ts +22 -22
  173. package/src/core/common/services/email.service.ts +1 -1
  174. package/src/core/common/services/mailjet.service.ts +8 -8
  175. package/src/core/common/services/module.service.ts +5 -6
  176. package/src/core/common/services/template.service.ts +4 -4
  177. package/src/core/common/types/core-model-constructor.type.ts +2 -2
  178. package/src/core/modules/auth/core-auth.controller.ts +2 -2
  179. package/src/core/modules/auth/core-auth.module.ts +4 -4
  180. package/src/core/modules/auth/core-auth.resolver.ts +9 -9
  181. package/src/core/modules/auth/guards/auth.guard.ts +8 -7
  182. package/src/core/modules/auth/guards/roles.guard.ts +1 -1
  183. package/src/core/modules/auth/services/core-auth.service.ts +9 -9
  184. package/src/core/modules/auth/strategies/jwt-refresh.strategy.ts +1 -1
  185. package/src/core/modules/auth/strategies/jwt.strategy.ts +1 -1
  186. package/src/core/modules/auth/tokens.decorator.ts +6 -7
  187. package/src/core/modules/file/core-file-info.model.ts +2 -2
  188. package/src/core/modules/file/core-file.controller.ts +2 -4
  189. package/src/core/modules/file/core-file.service.ts +6 -5
  190. package/src/core/modules/file/interfaces/file-upload.interface.ts +1 -1
  191. package/src/core/modules/health-check/core-health-check-result.model.ts +46 -0
  192. package/src/core/modules/health-check/core-health-check.controller.ts +24 -0
  193. package/src/core/modules/health-check/core-health-check.module.ts +17 -0
  194. package/src/core/modules/health-check/core-health-check.resolver.ts +32 -0
  195. package/src/core/modules/health-check/core-health-check.service.ts +60 -0
  196. package/src/core/modules/user/core-user.model.ts +5 -5
  197. package/src/core/modules/user/core-user.service.ts +10 -9
  198. package/src/core/modules/user/inputs/core-user.input.ts +1 -2
  199. package/src/core.module.ts +16 -10
  200. package/src/index.ts +10 -0
  201. package/src/main.ts +2 -2
  202. package/src/server/modules/auth/auth.controller.ts +1 -1
  203. package/src/server/modules/auth/auth.resolver.ts +3 -3
  204. package/src/server/modules/auth/auth.service.ts +2 -2
  205. package/src/server/modules/file/file.controller.ts +1 -2
  206. package/src/server/modules/file/file.module.ts +1 -1
  207. package/src/server/modules/file/file.resolver.ts +4 -3
  208. package/src/server/modules/file/file.service.ts +1 -1
  209. package/src/server/modules/file/multer-config.service.ts +1 -1
  210. package/src/server/modules/user/avatar.controller.ts +3 -3
  211. package/src/server/modules/user/user.model.ts +1 -1
  212. package/src/server/modules/user/user.resolver.ts +4 -4
  213. package/src/server/modules/user/user.service.ts +4 -4
  214. package/src/test/test.helper.ts +11 -11
@@ -1,7 +1,7 @@
1
1
  import { NotFoundException } from '@nestjs/common';
2
2
  import { GridFSBucket, GridFSBucketReadStream, GridFSBucketReadStreamOptions } from 'mongodb';
3
3
  import { Connection, Types } from 'mongoose';
4
- import { createBucket, MongoGridFSOptions, MongooseGridFS } from 'mongoose-gridfs';
4
+ import { MongoGridFSOptions, MongooseGridFS, createBucket } from 'mongoose-gridfs';
5
5
  import { FilterArgs } from '../../common/args/filter.args';
6
6
  import { getObjectIds, getStringIds } from '../../common/helpers/db.helper';
7
7
  import { convertFilterArgsToQuery } from '../../common/helpers/filter.helper';
@@ -38,6 +38,7 @@ export abstract class CoreFileService {
38
38
  return null;
39
39
  }
40
40
  return await new Promise(async (resolve, reject) => {
41
+ // eslint-disable-next-line unused-imports/no-unused-vars
41
42
  const { filename, mimetype, encoding, createReadStream } = await file;
42
43
  const readStream = createReadStream();
43
44
  const options: MongoGridFSOptions = { filename, contentType: mimetype };
@@ -123,7 +124,7 @@ export abstract class CoreFileService {
123
124
  */
124
125
  async getFileStreamByName(
125
126
  filename: string,
126
- serviceOptions?: FileServiceOptions
127
+ serviceOptions?: FileServiceOptions,
127
128
  ): Promise<GridFSBucketReadStreamOptions> {
128
129
  if (!(await this.checkRights(filename, { ...serviceOptions, checkInputType: 'filename' }))) {
129
130
  return null;
@@ -182,7 +183,7 @@ export abstract class CoreFileService {
182
183
  }
183
184
  const fileInfo = await this.getFileInfoByName(filename);
184
185
  if (!fileInfo) {
185
- throw new NotFoundException('File not found with filename ' + filename);
186
+ throw new NotFoundException(`File not found with filename ${filename}`);
186
187
  }
187
188
  return await this.deleteFile(fileInfo.id, serviceOptions);
188
189
  }
@@ -196,8 +197,8 @@ export abstract class CoreFileService {
196
197
  * Can throw an exception if the rights do not fit
197
198
  */
198
199
  protected checkRights(
199
- input: any,
200
- options?: FileServiceOptions & { checkInputType: FileInputCheckType }
200
+ input: any, // eslint-disable-line unused-imports/no-unused-vars
201
+ options?: FileServiceOptions & { checkInputType: FileInputCheckType }, // eslint-disable-line unused-imports/no-unused-vars
201
202
  ): MaybePromise<boolean> {
202
203
  return true;
203
204
  }
@@ -1,5 +1,5 @@
1
- import { WriteStream } from 'fs-capacitor';
2
1
  import { Readable } from 'stream';
2
+ import { WriteStream } from 'fs-capacitor';
3
3
 
4
4
  /**
5
5
  * Interface for file uploads
@@ -0,0 +1,46 @@
1
+ import { Field, ObjectType } from '@nestjs/graphql';
2
+ import { CoreModel } from '../../common/models/core-model.model';
3
+ import { JSON } from '../../common/scalars/json.scalar';
4
+
5
+ /**
6
+ * User model
7
+ */
8
+ @ObjectType({ description: 'Health check result' })
9
+ export abstract class CoreHealthCheckResult extends CoreModel {
10
+ // ===================================================================================================================
11
+ // Properties
12
+ // ===================================================================================================================
13
+
14
+ /**
15
+ * The overall status of the Health Check
16
+ */
17
+ @Field({ description: 'The overall status of the Health Check', nullable: false })
18
+ status: 'error' | 'ok' | 'shutting_down' = undefined;
19
+
20
+ /**
21
+ * The info object contains information of each health indicator which is of status “up”
22
+ */
23
+ @Field(type => JSON, {
24
+ description: 'The info object contains information of each health indicator which is of status “up”',
25
+ nullable: true,
26
+ })
27
+ info: JSON = undefined;
28
+
29
+ /**
30
+ * The error object contains information of each health indicator which is of status “down”
31
+ */
32
+ @Field(type => JSON, {
33
+ description: 'The error object contains information of each health indicator which is of status “down”',
34
+ nullable: true,
35
+ })
36
+ error: JSON = undefined;
37
+
38
+ /**
39
+ * The details object contains information of every health indicator
40
+ */
41
+ @Field(type => JSON, {
42
+ description: 'The details object contains information of every health indicator',
43
+ nullable: false,
44
+ })
45
+ details: JSON = undefined;
46
+ }
@@ -0,0 +1,24 @@
1
+ import { Controller, Get } from '@nestjs/common';
2
+ import { CoreHealthCheckService } from './core-health-check.service';
3
+
4
+ /**
5
+ * The HealthController class checks the health of various components including the database, memory, and disk.
6
+ * Inspired by https://mobileappcircular.com/marketplace-backend-creating-a-health-check-endpoint-in-nestjs-app-using-terminus-25727e96c7d2
7
+ */
8
+ @Controller()
9
+ export class CoreHealthCheckController {
10
+ constructor(protected readonly healthCheckService: CoreHealthCheckService) {}
11
+
12
+ /**
13
+ * The function checks the health of various components including the database, memory, and storage.
14
+ * @returns The function is returning the result of calling the `healthCheck()` method
15
+ * with an array of functions as arguments. Each function in the array is a check for a different
16
+ * aspect of the system's health, including the status of the database, memory usage, and disk
17
+ * storage. The `healthCheck()` method will return a Promise that resolves with an array of objects
18
+ * representing the results of each check
19
+ */
20
+ @Get('health-check')
21
+ async healthCheck() {
22
+ return this.healthCheckService.healthCheck();
23
+ }
24
+ }
@@ -0,0 +1,17 @@
1
+ import { Module } from '@nestjs/common';
2
+ import { TerminusModule } from '@nestjs/terminus';
3
+ import { CoreHealthCheckController } from './core-health-check.controller';
4
+ import { CoreHealthCheckResolver } from './core-health-check.resolver';
5
+ import { CoreHealthCheckService } from './core-health-check.service';
6
+
7
+ /**
8
+ * This is a module that imports the TerminusModule and includes a HealthController.
9
+ * Inspired by https://mobileappcircular.com/marketplace-backend-creating-a-health-check-endpoint-in-nestjs-app-using-terminus-25727e96c7d2
10
+ */
11
+ @Module({
12
+ imports: [TerminusModule],
13
+ controllers: [CoreHealthCheckController],
14
+ providers: [CoreHealthCheckService, CoreHealthCheckResolver],
15
+ })
16
+ export class CoreHealthCheckModule {
17
+ }
@@ -0,0 +1,32 @@
1
+ import { Query, Resolver } from '@nestjs/graphql';
2
+ import { RoleEnum } from '../../common/enums/role.enum';
3
+ import { Roles } from '../../common/decorators/roles.decorator';
4
+ import { CoreHealthCheckResult } from './core-health-check-result.model';
5
+ import { CoreHealthCheckService } from './core-health-check.service';
6
+
7
+
8
+ /**
9
+ * Resolver to process with user data
10
+ */
11
+ @Resolver(() => CoreHealthCheckResult)
12
+ @Roles(RoleEnum.ADMIN)
13
+ export class CoreHealthCheckResolver {
14
+ /**
15
+ * Import services
16
+ */
17
+ constructor(protected readonly healthCheckService: CoreHealthCheckService) {
18
+ }
19
+
20
+ // ===========================================================================
21
+ // Queries
22
+ // ===========================================================================
23
+
24
+ /**
25
+ * Get heath check result
26
+ */
27
+ @Roles(RoleEnum.S_EVERYONE)
28
+ @Query(() => CoreHealthCheckResult, { description: 'Get health check result' })
29
+ async healthCheck() {
30
+ return this.healthCheckService.healthCheck();
31
+ }
32
+ }
@@ -0,0 +1,60 @@
1
+ import { Injectable } from '@nestjs/common';
2
+ import {
3
+ DiskHealthIndicator, HealthCheckResult,
4
+ HealthCheckService,
5
+ MemoryHealthIndicator,
6
+ MongooseHealthIndicator,
7
+ } from '@nestjs/terminus';
8
+ import { MongoosePingCheckSettings } from '@nestjs/terminus/dist/health-indicator/database/mongoose.health';
9
+ import { DiskHealthIndicatorOptions } from '@nestjs/terminus/dist/health-indicator/disk/disk-health-options.type';
10
+ import { ConfigService } from '../../common/services/config.service';
11
+
12
+ /**
13
+ * Core health check service
14
+ * Inspired by https://mobileappcircular.com/marketplace-backend-creating-a-health-check-endpoint-in-nestjs-app-using-terminus-25727e96c7d2
15
+ */
16
+ @Injectable()
17
+ export class CoreHealthCheckService {
18
+
19
+ constructor(
20
+ protected config: ConfigService,
21
+ protected db: MongooseHealthIndicator,
22
+ protected disk: DiskHealthIndicator,
23
+ protected health: HealthCheckService,
24
+ protected memory: MemoryHealthIndicator,
25
+ ) {
26
+ }
27
+
28
+ healthCheck(): Promise<HealthCheckResult> {
29
+ const healthIndicatorFunctions = [];
30
+ if (!this.config.get<boolean>('healthCheck.configs.database.disabled')) {
31
+ healthIndicatorFunctions.push(() =>
32
+ this.db.pingCheck(
33
+ this.config.get<string>('healthCheck.configs.database.key') ?? 'database',
34
+ this.config.get<MongoosePingCheckSettings>('healthCheck.configs.database.options') ?? { timeout: 300 },
35
+ ));
36
+ }
37
+ if (!this.config.get<boolean>('healthCheck.configs.memoryHeap.disabled')) {
38
+ healthIndicatorFunctions.push(() => this.memory.checkHeap(
39
+ this.config.get<string>('healthCheck.configs.memoryHeap.key') ?? 'memoryHeap',
40
+ this.config.get<number>('healthCheck.configs.memoryHeap.heapUsedThreshold') ?? 150 * 1024 * 1024,
41
+ ));
42
+ }
43
+ if (!this.config.get<boolean>('healthCheck.configs.memoryRss.disabled')) {
44
+ healthIndicatorFunctions.push(() => this.memory.checkRSS(
45
+ this.config.get<string>('healthCheck.configs.memoryRss.key') ?? 'memoryRss',
46
+ this.config.get<number>('healthCheck.configs.memoryRss.rssThreshold') ?? 150 * 1024 * 1024,
47
+ ));
48
+ }
49
+ if (!this.config.get<boolean>('healthCheck.configs.storage.disabled')) {
50
+ healthIndicatorFunctions.push(() => this.disk.checkStorage(
51
+ this.config.get<string>('healthCheck.configs.storage.key') ?? 'storage',
52
+ this.config.get<DiskHealthIndicatorOptions>('healthCheck.configs.storage.options') ?? {
53
+ thresholdPercent: 0.8,
54
+ path: '/',
55
+ },
56
+ ));
57
+ }
58
+ return this.health.check(healthIndicatorFunctions);
59
+ }
60
+ }
@@ -1,5 +1,5 @@
1
1
  import { Field, ObjectType } from '@nestjs/graphql';
2
- import { Prop, raw, Schema as MongooseSchema } from '@nestjs/mongoose';
2
+ import { Schema as MongooseSchema, Prop, raw } from '@nestjs/mongoose';
3
3
  import { IsEmail, IsOptional } from 'class-validator';
4
4
  import { Document } from 'mongoose';
5
5
  import { CorePersistenceModel } from '../../common/models/core-persistence.model';
@@ -50,7 +50,7 @@ export abstract class CoreUserModel extends CorePersistenceModel {
50
50
  /**
51
51
  * Roles of the user
52
52
  */
53
- @Field((type) => [String], { description: 'Roles of the user', nullable: true })
53
+ @Field(type => [String], { description: 'Roles of the user', nullable: true })
54
54
  @IsOptional()
55
55
  @Prop()
56
56
  roles: string[] = undefined;
@@ -89,7 +89,7 @@ export abstract class CoreUserModel extends CorePersistenceModel {
89
89
  /**
90
90
  * Verification of the user
91
91
  */
92
- @Field((type) => Boolean, { description: 'Verification state of the user', nullable: true })
92
+ @Field(type => Boolean, { description: 'Verification state of the user', nullable: true })
93
93
  @Prop({ type: Boolean })
94
94
  verified: boolean = undefined;
95
95
 
@@ -114,7 +114,7 @@ export abstract class CoreUserModel extends CorePersistenceModel {
114
114
  if (!this.roles || this.roles.length < 1) {
115
115
  return false;
116
116
  }
117
- return !roles || roles.length < 1 ? true : this.roles.some((role) => roles.includes(role));
117
+ return !roles || roles.length < 1 ? true : this.roles.some(role => roles.includes(role));
118
118
  }
119
119
 
120
120
  /**
@@ -127,7 +127,7 @@ export abstract class CoreUserModel extends CorePersistenceModel {
127
127
  if (!this.roles || this.roles.length < 1) {
128
128
  return false;
129
129
  }
130
- return !roles ? true : roles.every((role) => this.roles.includes(role));
130
+ return !roles ? true : roles.every(role => this.roles.includes(role));
131
131
  }
132
132
 
133
133
  /**
@@ -1,6 +1,6 @@
1
+ import crypto = require('crypto');
1
2
  import { BadRequestException, NotFoundException, UnprocessableEntityException } from '@nestjs/common';
2
3
  import bcrypt = require('bcrypt');
3
- import crypto = require('crypto');
4
4
  import { sha256 } from 'js-sha256';
5
5
  import { Document, Model } from 'mongoose';
6
6
  import { assignPlain, prepareServiceOptionsForCreate } from '../../common/helpers/input.helper';
@@ -19,13 +19,13 @@ import { CoreUserInput } from './inputs/core-user.input';
19
19
  export abstract class CoreUserService<
20
20
  TUser extends CoreUserModel,
21
21
  TUserInput extends CoreUserInput,
22
- TUserCreateInput extends CoreUserCreateInput
22
+ TUserCreateInput extends CoreUserCreateInput,
23
23
  > extends CrudService<TUser, TUserCreateInput, TUserInput> {
24
24
  protected constructor(
25
25
  protected override readonly configService: ConfigService,
26
26
  protected readonly emailService: EmailService,
27
27
  protected override readonly mainDbModel: Model<TUser & Document>,
28
- protected override readonly mainModelConstructor: CoreModelConstructor<TUser>
28
+ protected override readonly mainModelConstructor: CoreModelConstructor<TUser>,
29
29
  ) {
30
30
  super();
31
31
  }
@@ -64,7 +64,7 @@ export abstract class CoreUserService<
64
64
  // Return created user
65
65
  return createdUser;
66
66
  },
67
- { input, serviceOptions }
67
+ { input, serviceOptions },
68
68
  );
69
69
  }
70
70
 
@@ -82,6 +82,7 @@ export abstract class CoreUserService<
82
82
  /**
83
83
  * Get verified state of user by token
84
84
  */
85
+ // eslint-disable-next-line unused-imports/no-unused-vars
85
86
  async getVerifiedState(token: string, serviceOptions?: ServiceOptions): Promise<boolean> {
86
87
  const user = await this.mainDbModel.findOne({ verificationToken: token }).exec();
87
88
 
@@ -115,7 +116,7 @@ export abstract class CoreUserService<
115
116
  // Update and return user
116
117
  return await assignPlain(dbObject, { verified: true, verifiedAt: new Date() }).save();
117
118
  },
118
- { dbObject, serviceOptions }
119
+ { dbObject, serviceOptions },
119
120
  );
120
121
  }
121
122
 
@@ -143,7 +144,7 @@ export abstract class CoreUserService<
143
144
  passwordResetToken: null,
144
145
  }).save();
145
146
  },
146
- { dbObject, serviceOptions }
147
+ { dbObject, serviceOptions },
147
148
  );
148
149
  }
149
150
 
@@ -168,7 +169,7 @@ export abstract class CoreUserService<
168
169
  // Return new user
169
170
  return dbObject;
170
171
  },
171
- { dbObject, serviceOptions }
172
+ { dbObject, serviceOptions },
172
173
  );
173
174
  }
174
175
 
@@ -182,7 +183,7 @@ export abstract class CoreUserService<
182
183
  }
183
184
 
184
185
  // Check roles values
185
- if (roles.some((role) => typeof role !== 'string')) {
186
+ if (roles.some(role => typeof role !== 'string')) {
186
187
  throw new BadRequestException('Roles contains invalid values');
187
188
  }
188
189
 
@@ -191,7 +192,7 @@ export abstract class CoreUserService<
191
192
  async () => {
192
193
  return await this.mainDbModel.findByIdAndUpdate(userId, { roles }).exec();
193
194
  },
194
- { serviceOptions }
195
+ { serviceOptions },
195
196
  );
196
197
  }
197
198
  }
@@ -4,7 +4,6 @@ import { Restricted } from '../../../common/decorators/restricted.decorator';
4
4
  import { ProcessType } from '../../../common/enums/process-type.enum';
5
5
  import { RoleEnum } from '../../../common/enums/role.enum';
6
6
  import { CoreInput } from '../../../common/inputs/core-input.input';
7
- import { toLowerCase } from '../../../common/middlewares/to-lower-case.middleware';
8
7
 
9
8
  /**
10
9
  * User input to update a user
@@ -41,7 +40,7 @@ export abstract class CoreUserInput extends CoreInput {
41
40
  * Roles of the user
42
41
  */
43
42
  @Restricted({ roles: RoleEnum.ADMIN, processType: ProcessType.INPUT })
44
- @Field((type) => [String], { description: 'Roles of the user', nullable: true })
43
+ @Field(type => [String], { description: 'Roles of the user', nullable: true })
45
44
  @IsOptional()
46
45
  roles?: string[] = undefined;
47
46
 
@@ -13,6 +13,7 @@ import { ConfigService } from './core/common/services/config.service';
13
13
  import { EmailService } from './core/common/services/email.service';
14
14
  import { MailjetService } from './core/common/services/mailjet.service';
15
15
  import { TemplateService } from './core/common/services/template.service';
16
+ import { CoreHealthCheckModule } from './core/modules/health-check/core-health-check.module';
16
17
 
17
18
  /**
18
19
  * Core module (dynamic)
@@ -36,6 +37,7 @@ export class CoreModule implements NestModule {
36
37
  configure(consumer: MiddlewareConsumer) {
37
38
  consumer.apply(graphqlUploadExpress()).forRoutes('graphql');
38
39
  }
40
+
39
41
  /**
40
42
  * Dynamic module
41
43
  * see https://docs.nestjs.com/modules#dynamic-modules
@@ -75,7 +77,7 @@ export class CoreModule implements NestModule {
75
77
  const payload = authService.decodeJwt(authToken);
76
78
  const user = await authService.validateUser(payload);
77
79
  // the user/jwtPayload object found will be available as context.currentUser/jwtPayload in your GraphQL resolvers
78
- return { user: user, headers: connectionParams };
80
+ return { user, headers: connectionParams };
79
81
  }
80
82
 
81
83
  throw new UnauthorizedException('Missing authentication token');
@@ -105,7 +107,7 @@ export class CoreModule implements NestModule {
105
107
  },
106
108
  },
107
109
  },
108
- options?.graphQl?.driver
110
+ options?.graphQl?.driver,
109
111
  ),
110
112
  },
111
113
  enableSubscriptionAuth: true,
@@ -115,14 +117,13 @@ export class CoreModule implements NestModule {
115
117
  uri: 'mongodb://localhost/nest-server-default',
116
118
  options: {
117
119
  connectionFactory: (connection) => {
118
- // eslint-disable-next-line @typescript-eslint/no-var-requires
119
120
  connection.plugin(require('./core/common/plugins/mongoose-id.plugin'));
120
121
  return connection;
121
122
  },
122
123
  },
123
124
  },
124
125
  } as IServerOptions,
125
- options
126
+ options,
126
127
  );
127
128
 
128
129
  // Set providers
@@ -148,15 +149,20 @@ export class CoreModule implements NestModule {
148
149
  ComplexityPlugin,
149
150
  ];
150
151
 
152
+ const imports: any[] = [
153
+ MongooseModule.forRoot(config.mongoose.uri, config.mongoose.options),
154
+ GraphQLModule.forRootAsync<ApolloDriverConfig>(
155
+ Object.assign({ driver: ApolloDriver }, config.graphQl.driver, config.graphQl.options),
156
+ ),
157
+ ];
158
+ if (config.healthCheck) {
159
+ imports.push(CoreHealthCheckModule);
160
+ }
161
+
151
162
  // Return dynamic module
152
163
  return {
153
164
  module: CoreModule,
154
- imports: [
155
- MongooseModule.forRoot(config.mongoose.uri, config.mongoose.options),
156
- GraphQLModule.forRootAsync<ApolloDriverConfig>(
157
- Object.assign({ driver: ApolloDriver }, config.graphQl.driver, config.graphQl.options)
158
- ),
159
- ],
165
+ imports,
160
166
  providers,
161
167
  exports: [ConfigService, EmailService, TemplateService, MailjetService, ComplexityPlugin],
162
168
  };
package/src/index.ts CHANGED
@@ -125,6 +125,16 @@ export * from './core/modules/user/inputs/core-user-create.input';
125
125
  export * from './core/modules/user/core-user.model';
126
126
  export * from './core/modules/user/core-user.service';
127
127
 
128
+ // =====================================================================================================================
129
+ // Core - Modules - HealthCheck
130
+ // =====================================================================================================================
131
+
132
+ export * from './core/modules/health-check/core-health-check.controller';
133
+ export * from './core/modules/health-check/core-health-check.module';
134
+ export * from './core/modules/health-check/core-health-check.resolver';
135
+ export * from './core/modules/health-check/core-health-check.service';
136
+ export * from './core/modules/health-check/core-health-check-result.model';
137
+
128
138
  // =====================================================================================================================
129
139
  // Tests
130
140
  // =====================================================================================================================
package/src/main.ts CHANGED
@@ -1,6 +1,6 @@
1
+ import { exec } from 'child_process';
1
2
  import { NestFactory } from '@nestjs/core';
2
3
  import { NestExpressApplication } from '@nestjs/platform-express';
3
- import { exec } from 'child_process';
4
4
  import compression = require('compression');
5
5
  import cookieParser = require('cookie-parser');
6
6
  import envConfig from './config.env';
@@ -14,7 +14,7 @@ async function bootstrap() {
14
14
  // Create a new server based on express
15
15
  const server = await NestFactory.create<NestExpressApplication>(
16
16
  // Include server module, with all necessary modules for the project
17
- ServerModule
17
+ ServerModule,
18
18
  );
19
19
 
20
20
  // Log exceptions
@@ -10,7 +10,7 @@ export class AuthController extends CoreAuthController {
10
10
  */
11
11
  constructor(
12
12
  protected override readonly authService: AuthService,
13
- protected override readonly configService: ConfigService
13
+ protected override readonly configService: ConfigService,
14
14
  ) {
15
15
  super(authService, configService);
16
16
  }
@@ -19,7 +19,7 @@ export class AuthResolver extends CoreAuthResolver {
19
19
  */
20
20
  constructor(
21
21
  protected override readonly authService: AuthService,
22
- protected override readonly configService: ConfigService
22
+ protected override readonly configService: ConfigService,
23
23
  ) {
24
24
  super(authService, configService);
25
25
  }
@@ -31,7 +31,7 @@ export class AuthResolver extends CoreAuthResolver {
31
31
  override async signIn(
32
32
  @GraphQLServiceOptions({ gqlPath: 'signIn.user' }) serviceOptions: ServiceOptions,
33
33
  @Context() ctx: { res: ResponseType },
34
- @Args('input') input: AuthSignInInput
34
+ @Args('input') input: AuthSignInInput,
35
35
  ): Promise<Auth> {
36
36
  const result = await this.authService.signIn(input, {
37
37
  ...serviceOptions,
@@ -49,7 +49,7 @@ export class AuthResolver extends CoreAuthResolver {
49
49
  override async signUp(
50
50
  @GraphQLServiceOptions({ gqlPath: 'signUp.user' }) serviceOptions: ServiceOptions,
51
51
  @Context() ctx: { res: ResponseType },
52
- @Args('input') input: AuthSignUpInput
52
+ @Args('input') input: AuthSignUpInput,
53
53
  ): Promise<Auth> {
54
54
  const result = await this.authService.signUp(input, serviceOptions);
55
55
  return this.processCookies(ctx, result);
@@ -15,7 +15,7 @@ export class AuthService extends CoreAuthService {
15
15
  protected override readonly jwtService: JwtService,
16
16
  protected readonly emailService: EmailService,
17
17
  protected override readonly userService: UserService,
18
- protected override readonly configService: ConfigService
18
+ protected override readonly configService: ConfigService,
19
19
  ) {
20
20
  super(userService, jwtService, configService);
21
21
  }
@@ -43,7 +43,7 @@ export class AuthService extends CoreAuthService {
43
43
  htmlTemplate: 'welcome',
44
44
  templateData: {
45
45
  name: user.username,
46
- link: this.configService.configFastButReadOnly.email.verificationLink + '/' + user.verificationToken,
46
+ link: `${this.configService.configFastButReadOnly.email.verificationLink}/${user.verificationToken}`,
47
47
  },
48
48
  });
49
49
 
@@ -7,7 +7,6 @@ import {
7
7
  Param,
8
8
  Post,
9
9
  Res,
10
- UnprocessableEntityException,
11
10
  UploadedFile,
12
11
  UseInterceptors,
13
12
  } from '@nestjs/common';
@@ -57,7 +56,7 @@ export class FileController {
57
56
  }
58
57
  const filestream = await this.fileService.getFileStream(id);
59
58
  res.header('Content-Type', file.contentType);
60
- res.header('Content-Disposition', 'attachment; filename=' + file.filename);
59
+ res.header('Content-Disposition', `attachment; filename=${file.filename}`);
61
60
  res.header('Cache-Control', 'max-age=31536000');
62
61
  return filestream.pipe(res);
63
62
  }
@@ -1,4 +1,4 @@
1
- import { forwardRef, Module } from '@nestjs/common';
1
+ import { Module, forwardRef } from '@nestjs/common';
2
2
  import { MulterModule } from '@nestjs/platform-express';
3
3
  import { UserModule } from '../user/user.module';
4
4
  import { FileController } from './file.controller';
@@ -1,6 +1,6 @@
1
- import { Args, Mutation, Query, Resolver } from '@nestjs/graphql';
2
1
  import fs = require('fs');
3
2
  import { createWriteStream } from 'fs';
3
+ import { Args, Mutation, Query, Resolver } from '@nestjs/graphql';
4
4
  import GraphQLUpload = require('graphql-upload/GraphQLUpload.js');
5
5
  import { Roles } from '../../../core/common/decorators/roles.decorator';
6
6
  import { RoleEnum } from '../../../core/common/enums/role.enum';
@@ -63,6 +63,7 @@ export class FileResolver {
63
63
  // Save files in filesystem
64
64
  const promises: Promise<any>[] = [];
65
65
  for (const file of files) {
66
+ // eslint-disable-next-line unused-imports/no-unused-vars
66
67
  const { filename, mimetype, encoding, createReadStream } = await file;
67
68
  await fs.promises.mkdir('./uploads', { recursive: true });
68
69
  promises.push(
@@ -70,8 +71,8 @@ export class FileResolver {
70
71
  createReadStream()
71
72
  .pipe(createWriteStream(`./uploads/${filename}`))
72
73
  .on('finish', () => resolve(true))
73
- .on('error', (error) => reject(error))
74
- )
74
+ .on('error', error => reject(error)),
75
+ ),
75
76
  );
76
77
  }
77
78
  await Promise.allSettled(promises);
@@ -16,7 +16,7 @@ export class FileService extends CoreFileService {
16
16
  * Duplicate file by name
17
17
  */
18
18
  async duplicate(fileName: string, newName: string): Promise<any> {
19
- return new Promise(async (resolve, reject) => {
19
+ return new Promise(async (resolve) => {
20
20
  resolve(this.files.openDownloadStreamByName(fileName).pipe(this.files.openUploadStream(newName)));
21
21
  });
22
22
  }
@@ -14,7 +14,7 @@ export class GridFsMulterConfigService implements MulterOptionsFactory {
14
14
  return new Promise((resolve) => {
15
15
  const filename = file.originalname.trim();
16
16
  const fileInfo = {
17
- filename: filename,
17
+ filename,
18
18
  };
19
19
  resolve(fileInfo);
20
20
  });
@@ -28,9 +28,9 @@ export class AvatarController {
28
28
  FileInterceptor(
29
29
  'file',
30
30
  multerOptionsForImageUpload({
31
- destination: envConfig.staticAssets.path + '/avatars',
32
- })
33
- )
31
+ destination: `${envConfig.staticAssets.path}/avatars`,
32
+ }),
33
+ ),
34
34
  )
35
35
  uploadFile(@UploadedFile() file: Express.Multer.File, @CurrentUser() user: User): Promise<string> {
36
36
  return this.usersService.setAvatar(file, user);
@@ -1,5 +1,5 @@
1
1
  import { Field, ObjectType } from '@nestjs/graphql';
2
- import { Prop, Schema as MongooseSchema, SchemaFactory } from '@nestjs/mongoose';
2
+ import { Schema as MongooseSchema, Prop, SchemaFactory } from '@nestjs/mongoose';
3
3
  import { Document, Schema } from 'mongoose';
4
4
  import { RoleEnum } from '../../../core/common/enums/role.enum';
5
5
  import { CoreUserModel } from '../../../core/modules/user/core-user.model';