@lenne.tech/nest-server 8.6.19 → 8.6.22

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 (35) hide show
  1. package/dist/core/common/helpers/common.helper.d.ts +2 -0
  2. package/dist/core/common/helpers/common.helper.js +16 -0
  3. package/dist/core/common/helpers/common.helper.js.map +1 -0
  4. package/dist/core/common/helpers/model.helper.js +24 -18
  5. package/dist/core/common/helpers/model.helper.js.map +1 -1
  6. package/dist/core/common/services/mailjet.service.d.ts +7 -3
  7. package/dist/core/common/services/mailjet.service.js +4 -1
  8. package/dist/core/common/services/mailjet.service.js.map +1 -1
  9. package/dist/core/common/services/module.service.js +4 -1
  10. package/dist/core/common/services/module.service.js.map +1 -1
  11. package/dist/core/common/types/remove-methods.type.d.ts +3 -0
  12. package/dist/core/common/types/remove-methods.type.js +3 -0
  13. package/dist/core/common/types/remove-methods.type.js.map +1 -0
  14. package/dist/core/common/types/string-or-object-id.type.d.ts +1 -1
  15. package/dist/core/modules/file/core-file.service.d.ts +2 -2
  16. package/dist/core/modules/file/core-file.service.js.map +1 -1
  17. package/dist/core/modules/file/interfaces/file-service-options.interface.d.ts +1 -0
  18. package/dist/index.d.ts +2 -0
  19. package/dist/index.js +2 -0
  20. package/dist/index.js.map +1 -1
  21. package/dist/server/modules/file/file-info.model.d.ts +4 -2
  22. package/dist/server/modules/user/user.model.d.ts +4 -2
  23. package/dist/tsconfig.build.tsbuildinfo +1 -1
  24. package/package.json +12 -12
  25. package/src/core/common/helpers/common.helper.ts +18 -0
  26. package/src/core/common/helpers/db.helper.ts +1 -1
  27. package/src/core/common/helpers/model.helper.ts +22 -20
  28. package/src/core/common/services/mailjet.service.ts +14 -9
  29. package/src/core/common/services/module.service.ts +6 -1
  30. package/src/core/common/types/plain-input.type.ts +1 -1
  31. package/src/core/common/types/remove-methods.type.ts +4 -0
  32. package/src/core/common/types/string-or-object-id.type.ts +4 -1
  33. package/src/core/modules/file/core-file.service.ts +2 -2
  34. package/src/core/modules/file/interfaces/file-service-options.interface.ts +1 -0
  35. package/src/index.ts +2 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lenne.tech/nest-server",
3
- "version": "8.6.19",
3
+ "version": "8.6.22",
4
4
  "description": "Modern, fast, powerful Node.js web framework in TypeScript based on Nest with a GraphQL API and a connection to MongoDB (or other databases).",
5
5
  "keywords": [
6
6
  "node",
@@ -76,17 +76,17 @@
76
76
  "ejs": "3.1.8",
77
77
  "graphql": "16.5.0",
78
78
  "graphql-subscriptions": "2.0.0",
79
- "graphql-upload": "15.0.1",
79
+ "graphql-upload": "15.0.2",
80
80
  "json-to-graphql-query": "2.2.4",
81
81
  "light-my-request": "5.0.0",
82
82
  "lodash": "4.17.21",
83
83
  "mongodb": "4.7.0",
84
- "mongoose": "6.3.9",
84
+ "mongoose": "6.4.1",
85
85
  "mongoose-gridfs": "1.3.0",
86
- "multer": "1.4.4",
87
- "node-mailjet": "3.4.1",
88
- "nodemailer": "6.7.5",
89
- "nodemon": "2.0.16",
86
+ "multer": "1.4.5-lts.1",
87
+ "node-mailjet": "5.0.1",
88
+ "nodemailer": "6.7.6",
89
+ "nodemon": "2.0.18",
90
90
  "passport": "0.6.0",
91
91
  "passport-jwt": "4.0.0",
92
92
  "reflect-metadata": "0.1.13",
@@ -97,16 +97,16 @@
97
97
  "@nestjs/testing": "8.4.7",
98
98
  "@types/cron": "2.0.0",
99
99
  "@types/ejs": "3.1.1",
100
- "@types/jest": "28.1.3",
100
+ "@types/jest": "28.1.4",
101
101
  "@types/lodash": "4.14.182",
102
102
  "@types/multer": "1.4.7",
103
103
  "@types/node": "18.0.0",
104
- "@types/node-mailjet": "3.3.9",
104
+ "@types/node-mailjet": "^3.3.9",
105
105
  "@types/nodemailer": "6.4.4",
106
106
  "@types/passport": "1.0.9",
107
107
  "@types/supertest": "2.0.12",
108
- "@typescript-eslint/eslint-plugin": "5.29.0",
109
- "@typescript-eslint/parser": "5.29.0",
108
+ "@typescript-eslint/eslint-plugin": "5.30.0",
109
+ "@typescript-eslint/parser": "5.30.0",
110
110
  "coffeescript": "2.7.0",
111
111
  "eslint": "8.18.0",
112
112
  "eslint-config-prettier": "8.5.0",
@@ -117,7 +117,7 @@
117
117
  "grunt-contrib-watch": "1.1.0",
118
118
  "grunt-sync": "0.8.2",
119
119
  "husky": "8.0.1",
120
- "jest": "28.1.1",
120
+ "jest": "28.1.2",
121
121
  "pm2": "5.2.0",
122
122
  "prettier": "2.7.1",
123
123
  "pretty-quick": "3.1.3",
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Wait a certain number of milliseconds
3
+ */
4
+ export function sleep(ms: number) {
5
+ return new Promise<void>((resolve) => {
6
+ setTimeout(() => {
7
+ resolve();
8
+ }, ms);
9
+ });
10
+ }
11
+
12
+ /**
13
+ * Wait a certain number of milliseconds
14
+ * Alias of sleep
15
+ */
16
+ export function wait(ms: number) {
17
+ return sleep(ms);
18
+ }
@@ -597,7 +597,7 @@ function getStringId(element: any): string {
597
597
  return element;
598
598
  }
599
599
 
600
- // Sring handling
600
+ // String handling
601
601
  if (typeof element === 'string') {
602
602
  return element;
603
603
  }
@@ -175,9 +175,10 @@ export function mapClasses<T = Record<string, any>>(
175
175
  }
176
176
 
177
177
  // Process input
178
- for (const [prop, value] of Object.entries(input)) {
179
- if (prop in mapping) {
180
- const targetClass = mapping[prop] as any;
178
+ for (const [prop, mapTarget] of Object.entries(mapping)) {
179
+ if (prop in input) {
180
+ const targetClass = mapTarget as any;
181
+ const value = input[prop];
181
182
 
182
183
  // Process array
183
184
  if (Array.isArray(value)) {
@@ -185,13 +186,12 @@ export function mapClasses<T = Record<string, any>>(
185
186
  for (const item of value) {
186
187
  if (value instanceof targetClass) {
187
188
  arr.push(value);
188
- }
189
- if (value instanceof Types.ObjectId) {
189
+ } else if (value instanceof Types.ObjectId) {
190
190
  arr.push(value);
191
191
  } else if (typeof value === 'object') {
192
192
  if (targetClass.map) {
193
193
  arr.push(targetClass.map(item));
194
- } else if (typeof value === 'object') {
194
+ } else {
195
195
  arr.push(plainToInstance(targetClass, item));
196
196
  }
197
197
  } else {
@@ -210,11 +210,12 @@ export function mapClasses<T = Record<string, any>>(
210
210
  else if (typeof value === 'object') {
211
211
  if (value instanceof targetClass) {
212
212
  target[prop] = value as any;
213
- }
214
- if (targetClass.map) {
215
- target[prop] = targetClass.map(value);
216
213
  } else {
217
- target[prop] = plainToInstance(targetClass, value) as any;
214
+ if (targetClass.map) {
215
+ target[prop] = targetClass.map(value);
216
+ } else {
217
+ target[prop] = plainToInstance(targetClass, value) as any;
218
+ }
218
219
  }
219
220
  }
220
221
 
@@ -250,9 +251,10 @@ export async function mapClassesAsync<T = Record<string, any>>(
250
251
  }
251
252
 
252
253
  // Process input
253
- for (const [prop, value] of Object.entries(input)) {
254
- if (prop in mapping) {
255
- const targetClass = mapping[prop] as any;
254
+ for (const [prop, mapTarget] of Object.entries(mapping)) {
255
+ if (prop in input) {
256
+ const targetClass = mapTarget as any;
257
+ const value = input[prop];
256
258
 
257
259
  // Process array
258
260
  if (Array.isArray(value)) {
@@ -260,13 +262,12 @@ export async function mapClassesAsync<T = Record<string, any>>(
260
262
  for (const item of value) {
261
263
  if (value instanceof targetClass) {
262
264
  arr.push(value);
263
- }
264
- if (value instanceof Types.ObjectId) {
265
+ } else if (value instanceof Types.ObjectId) {
265
266
  arr.push(value);
266
267
  } else if (typeof value === 'object') {
267
268
  if (targetClass.map) {
268
269
  arr.push(await targetClass.map(item));
269
- } else if (typeof value === 'object') {
270
+ } else {
270
271
  arr.push(plainToInstance(targetClass, item));
271
272
  }
272
273
  } else {
@@ -285,11 +286,12 @@ export async function mapClassesAsync<T = Record<string, any>>(
285
286
  else if (typeof value === 'object') {
286
287
  if (value instanceof targetClass) {
287
288
  target[prop] = value as any;
288
- }
289
- if (targetClass.map) {
290
- target[prop] = await targetClass.map(value);
291
289
  } else {
292
- target[prop] = plainToInstance(targetClass, value) as any;
290
+ if (targetClass.map) {
291
+ target[prop] = await targetClass.map(value);
292
+ } else {
293
+ target[prop] = plainToInstance(targetClass, value) as any;
294
+ }
293
295
  }
294
296
  }
295
297
 
@@ -1,6 +1,6 @@
1
1
  import { Injectable } from '@nestjs/common';
2
2
  import { ConfigService } from './config.service';
3
- import mailjet from 'node-mailjet';
3
+ import Mailjet from 'node-mailjet';
4
4
 
5
5
  /**
6
6
  * Mailjet service
@@ -22,11 +22,16 @@ export class MailjetService {
22
22
  config: {
23
23
  senderEmail?: string;
24
24
  senderName?: string;
25
- attachments?: mailjet.Email.Attachment[];
25
+ attachments?: {
26
+ ContentID?: string;
27
+ ContentType: string;
28
+ Filename: string;
29
+ Base64Content: string;
30
+ }[];
26
31
  templateData?: { [key: string]: any };
27
32
  sandbox?: boolean;
28
33
  }
29
- ): Promise<mailjet.Email.PostResponse> {
34
+ ) {
30
35
  // Process config
31
36
  const { senderName, senderEmail, templateData, attachments, sandbox } = {
32
37
  senderEmail: this.configService.get('email.defaultSender.email'),
@@ -49,7 +54,7 @@ export class MailjetService {
49
54
  }
50
55
 
51
56
  // Parse body for mailjet request
52
- const body: mailjet.Email.SendParams = {
57
+ const body = {
53
58
  Messages: [
54
59
  {
55
60
  From: {
@@ -67,13 +72,13 @@ export class MailjetService {
67
72
  SandboxMode: sandbox,
68
73
  };
69
74
 
70
- let connection: mailjet.Email.Client;
75
+ let connection;
71
76
  try {
72
77
  // Connect to mailjet
73
- connection = await mailjet.connect(
74
- this.configService.get('email.mailjet.api_key_public'),
75
- this.configService.get('email.mailjet.api_key_private')
76
- );
78
+ connection = new Mailjet({
79
+ apiKey: this.configService.get('email.mailjet.api_key_public'),
80
+ apiSecret: this.configService.get('email.mailjet.api_key_private'),
81
+ });
77
82
  } catch (e) {
78
83
  throw new Error('Cannot connect to mailjet.');
79
84
  }
@@ -107,6 +107,11 @@ export abstract class ModuleService<T extends CoreModel = any> {
107
107
  config.input = await this.prepareInput(config.input, opts);
108
108
  }
109
109
 
110
+ // Check rights
111
+ if (config.checkRights && this.checkRights) {
112
+ await this.checkRights(undefined, config.currentUser as any, config);
113
+ }
114
+
110
115
  // Get DB object
111
116
  if (config.dbObject && config.checkRights && this.checkRights) {
112
117
  if (typeof config.dbObject === 'string' || config.dbObject instanceof Types.ObjectId) {
@@ -144,7 +149,7 @@ export abstract class ModuleService<T extends CoreModel = any> {
144
149
  }
145
150
 
146
151
  // Check output rights
147
- if (config.checkRights && this.checkRights) {
152
+ if (config.checkRights && (await this.checkRights(undefined, config.currentUser as any, config))) {
148
153
  const opts: any = {
149
154
  dbObject: config.dbObject,
150
155
  processType: ProcessType.OUTPUT,
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Type for plain Inputs
2
+ * Type for plain inputs with only optional properties
3
3
  */
4
4
  export type PlainInput<T> = {
5
5
  [P in keyof T]?: Partial<T[P]> | Partial<PlainInput<T[P]>>;
@@ -0,0 +1,4 @@
1
+ /**
2
+ * Type for plain object with only properties and no methods
3
+ */
4
+ export type RemoveMethods<T> = { [P in keyof T as T[P] extends (...args: any) => any ? never : P]: T[P] };
@@ -1,3 +1,6 @@
1
1
  import { Types } from 'mongoose';
2
2
 
3
- export type StringOrObjectId = string | Types.ObjectId | any;
3
+ /**
4
+ * Everything which will be used by getStringIds or getObjectIds (see helpers/db.helper.ts)
5
+ */
6
+ export type StringOrObjectId<T = any> = string | Types.ObjectId | T;
@@ -1,5 +1,5 @@
1
1
  import { NotFoundException } from '@nestjs/common';
2
- import { GridFSBucket, GridFSBucketReadStreamOptions } from 'mongodb';
2
+ import { GridFSBucket, GridFSBucketReadStream, GridFSBucketReadStreamOptions } from 'mongodb';
3
3
  import { Connection, Types } from 'mongoose';
4
4
  import { createBucket, MongoGridFSOptions, MongooseGridFS } from 'mongoose-gridfs';
5
5
  import { FilterArgs } from '../../common/args/filter.args';
@@ -115,7 +115,7 @@ export abstract class CoreFileService {
115
115
  if (!(await this.checkRights(id, { ...serviceOptions, checkInputType: 'id' }))) {
116
116
  return null;
117
117
  }
118
- return this.files.openDownloadStream(getObjectIds(id));
118
+ return this.files.openDownloadStream(getObjectIds(id)) as GridFSBucketReadStream;
119
119
  }
120
120
 
121
121
  /**
@@ -3,5 +3,6 @@
3
3
  */
4
4
  export interface FileServiceOptions {
5
5
  currentUser?: { id: any; hasRole: (roles: string[]) => boolean };
6
+ force?: boolean;
6
7
  roles?: string | string[];
7
8
  }
package/src/index.ts CHANGED
@@ -18,6 +18,7 @@ export * from './core/common/enums/logical-operator.enum';
18
18
  export * from './core/common/enums/process-type.enum';
19
19
  export * from './core/common/enums/role.enum';
20
20
  export * from './core/common/enums/sort-order.emum';
21
+ export * from './core/common/helpers/common.helper';
21
22
  export * from './core/common/helpers/config.helper';
22
23
  export * from './core/common/helpers/context.helper';
23
24
  export * from './core/common/helpers/db.helper';
@@ -61,6 +62,7 @@ export * from './core/common/types/field-selection.type';
61
62
  export * from './core/common/types/ids.type';
62
63
  export * from './core/common/types/maybe-promise.type';
63
64
  export * from './core/common/types/plain-input.type';
65
+ export * from './core/common/types/remove-methods.type';
64
66
  export * from './core/common/types/require-only-one.type';
65
67
  export * from './core/common/types/required-at-least-one.type';
66
68
  export * from './core/common/types/string-or-object-id.type';