@lenne.tech/nest-server 10.3.4 → 10.4.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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lenne.tech/nest-server",
3
- "version": "10.3.4",
3
+ "version": "10.4.1",
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",
@@ -63,19 +63,19 @@
63
63
  "node": ">= 20"
64
64
  },
65
65
  "dependencies": {
66
- "@apollo/gateway": "2.8.4",
66
+ "@apollo/gateway": "2.9.2",
67
67
  "@getbrevo/brevo": "1.0.1",
68
68
  "@lenne.tech/mongoose-gridfs": "1.4.2",
69
69
  "@lenne.tech/multer-gridfs-storage": "5.0.6",
70
70
  "@nestjs/apollo": "12.2.0",
71
- "@nestjs/common": "10.4.1",
72
- "@nestjs/core": "10.4.1",
71
+ "@nestjs/common": "10.4.4",
72
+ "@nestjs/core": "10.4.4",
73
73
  "@nestjs/graphql": "12.2.0",
74
74
  "@nestjs/jwt": "10.2.0",
75
75
  "@nestjs/mongoose": "10.0.10",
76
76
  "@nestjs/passport": "10.0.3",
77
- "@nestjs/platform-express": "10.4.1",
78
- "@nestjs/schedule": "4.1.0",
77
+ "@nestjs/platform-express": "10.4.4",
78
+ "@nestjs/schedule": "4.1.1",
79
79
  "@nestjs/terminus": "10.2.3",
80
80
  "apollo-server-core": "3.13.0",
81
81
  "apollo-server-express": "3.13.0",
@@ -90,15 +90,15 @@
90
90
  "graphql-subscriptions": "2.0.0",
91
91
  "graphql-upload": "15.0.2",
92
92
  "js-sha256": "0.11.0",
93
- "json-to-graphql-query": "2.2.5",
94
- "light-my-request": "5.13.0",
93
+ "json-to-graphql-query": "2.3.0",
94
+ "light-my-request": "6.0.0",
95
95
  "lodash": "4.17.21",
96
- "mongodb": "6.8.0",
97
- "mongoose": "7.8.1",
96
+ "mongodb": "6.9.0",
97
+ "mongoose": "7.8.2",
98
98
  "multer": "1.4.5-lts.1",
99
- "node-mailjet": "4.0.1",
100
- "nodemailer": "6.9.14",
101
- "nodemon": "3.1.4",
99
+ "node-mailjet": "6.0.6",
100
+ "nodemailer": "6.9.15",
101
+ "nodemon": "3.1.7",
102
102
  "passport": "0.7.0",
103
103
  "passport-jwt": "4.0.1",
104
104
  "reflect-metadata": "0.2.2",
@@ -111,43 +111,43 @@
111
111
  "@babel/plugin-proposal-private-methods": "7.18.6",
112
112
  "@compodoc/compodoc": "1.1.25",
113
113
  "@lenne.tech/eslint-config-ts": "0.0.16",
114
- "@nestjs/cli": "10.4.4",
114
+ "@nestjs/cli": "10.4.5",
115
115
  "@nestjs/schematics": "10.1.4",
116
- "@nestjs/testing": "10.4.1",
116
+ "@nestjs/testing": "10.4.4",
117
117
  "@swc/cli": "0.4.0",
118
- "@swc/core": "1.7.14",
118
+ "@swc/core": "1.7.28",
119
119
  "@swc/jest": "0.2.36",
120
120
  "@types/compression": "1.7.5",
121
121
  "@types/cookie-parser": "1.4.7",
122
122
  "@types/ejs": "3.1.5",
123
123
  "@types/express": "4.17.21",
124
- "@types/jest": "29.5.12",
125
- "@types/lodash": "4.17.7",
126
- "@types/multer": "1.4.11",
127
- "@types/node": "20.16.1",
128
- "@types/nodemailer": "6.4.15",
124
+ "@types/jest": "29.5.13",
125
+ "@types/lodash": "4.17.9",
126
+ "@types/multer": "1.4.12",
127
+ "@types/node": "20.16.9",
128
+ "@types/nodemailer": "6.4.16",
129
129
  "@types/passport": "1.0.16",
130
130
  "@types/supertest": "6.0.2",
131
131
  "@typescript-eslint/eslint-plugin": "6.21.0",
132
132
  "@typescript-eslint/parser": "6.21.0",
133
133
  "coffeescript": "2.7.0",
134
- "eslint": "8.57.0",
134
+ "eslint": "8.57.1",
135
135
  "eslint-config-prettier": "9.1.0",
136
- "eslint-plugin-unused-imports": "4.1.3",
136
+ "eslint-plugin-unused-imports": "4.1.4",
137
137
  "find-file-up": "2.0.1",
138
138
  "grunt": "1.6.1",
139
139
  "grunt-bg-shell": "2.3.3",
140
140
  "grunt-contrib-clean": "2.0.1",
141
141
  "grunt-contrib-watch": "1.1.0",
142
142
  "grunt-sync": "0.8.2",
143
- "husky": "9.1.5",
143
+ "husky": "9.1.6",
144
144
  "jest": "29.7.0",
145
145
  "npm-watch": "0.13.0",
146
146
  "pm2": "5.4.2",
147
147
  "prettier": "3.3.3",
148
148
  "pretty-quick": "4.0.0",
149
149
  "supertest": "7.0.0",
150
- "ts-jest": "29.2.4",
150
+ "ts-jest": "29.2.5",
151
151
  "ts-loader": "9.5.1",
152
152
  "ts-morph": "21.0.1",
153
153
  "ts-node": "10.9.2",
@@ -793,7 +793,7 @@ export function prepareServiceOptionsForCreate(serviceOptions: any) {
793
793
  serviceOptions.prepareInput = {};
794
794
  }
795
795
  if (serviceOptions.prepareInput.create === undefined) {
796
- serviceOptions.prepareInput.create;
796
+ serviceOptions.prepareInput.create = true;
797
797
  }
798
798
  return serviceOptions;
799
799
  }
@@ -25,61 +25,54 @@ export class CheckSecurityInterceptor implements NestInterceptor {
25
25
  }
26
26
  }
27
27
 
28
- // Check response
29
- return next.handle().pipe(
30
- map((data) => {
31
- // Check data
32
- if (data && typeof data === 'object' && typeof data.securityCheck === 'function') {
33
- const dataJson = JSON.stringify(data);
34
- const response = data.securityCheck(user, force);
35
- new Promise(() => {
36
- if (dataJson !== JSON.stringify(response)) {
37
- const id = getStringIds(data);
38
- console.debug(
39
- 'CheckSecurityInterceptor: securityCheck changed data of type',
40
- data.constructor.name,
41
- id && !Array.isArray(id) ? `with ID: ${id}` : '',
42
- );
43
- }
44
- });
45
- return response;
28
+ const check = (data) => {
29
+ // Check data
30
+ if (data && typeof data === 'object' && typeof data.securityCheck === 'function') {
31
+ const dataJson = JSON.stringify(data);
32
+ const response = data.securityCheck(user, force);
33
+ new Promise(() => {
34
+ if (dataJson !== JSON.stringify(response)) {
35
+ const id = getStringIds(data);
36
+ console.debug(
37
+ 'CheckSecurityInterceptor: securityCheck changed data of type',
38
+ data.constructor.name,
39
+ id && !Array.isArray(id) ? `with ID: ${id}` : '',
40
+ );
41
+ }
42
+ });
43
+ if (response && !data._doNotCheckSecurityDeep) {
44
+ for (const key of Object.keys(response)) {
45
+ response[key] = check(response[key]);
46
+ }
46
47
  }
48
+ return response;
49
+ }
47
50
 
48
- // Check if data is writeable (e.g. objects from direct access to json files via http are not writable)
49
- if (data && typeof data === 'object') {
50
- const writeable = !Object.keys(data).find(key => !Object.getOwnPropertyDescriptor(data, key).writable);
51
- if (!writeable) {
52
- return data;
53
- }
51
+ // Check if data is writeable (e.g. objects from direct access to json files via http are not writable)
52
+ if (data && typeof data === 'object') {
53
+ const writeable = !Object.keys(data).find(key => !Object.getOwnPropertyDescriptor(data, key).writable);
54
+ if (!writeable) {
55
+ return data;
54
56
  }
57
+ }
55
58
 
56
- // Check deep
57
- return processDeep(
58
- data,
59
- (item) => {
60
- if (!item || typeof item !== 'object' || typeof item.securityCheck !== 'function') {
61
- if (Array.isArray(item)) {
62
- return item.filter(i => i !== undefined);
63
- }
64
- return item;
59
+ // Check deep
60
+ return processDeep(
61
+ data,
62
+ (item) => {
63
+ if (!item || typeof item !== 'object' || typeof item.securityCheck !== 'function') {
64
+ if (Array.isArray(item)) {
65
+ return item.filter(i => i !== undefined);
65
66
  }
66
- const itemJson = JSON.stringify(item);
67
- const response = item.securityCheck(user, force);
68
- new Promise(() => {
69
- if (itemJson !== JSON.stringify(response)) {
70
- const id = getStringIds(item);
71
- console.debug(
72
- 'CheckSecurityInterceptor: securityCheck changed item of type',
73
- item.constructor.name,
74
- id && !Array.isArray(id) ? `with ID: ${id}` : '',
75
- );
76
- }
77
- });
78
- return response;
79
- },
80
- { specialFunctions: ['securityCheck'] },
81
- );
82
- }),
83
- );
67
+ return item;
68
+ }
69
+ return check(item);
70
+ },
71
+ { specialFunctions: ['securityCheck'] },
72
+ );
73
+ };
74
+
75
+ // Check response
76
+ return next.handle().pipe(map(check));
84
77
  }
85
78
  }
@@ -97,7 +97,7 @@ export abstract class ModuleService<T extends CoreModel = any> {
97
97
  processFieldSelection: {},
98
98
  pubSub: true,
99
99
  setCreateOrUpdateUserId: true,
100
- ...options?.serviceOptions,
100
+ ...(options?.serviceOptions || {}),
101
101
  };
102
102
 
103
103
  // Note raw configuration
@@ -204,15 +204,19 @@ export class TestHelper {
204
204
 
205
205
  // Init
206
206
  let query = '';
207
+ let name: string = undefined;
207
208
 
208
209
  // Convert string to TestGraphQLConfig
209
- if ((typeof graphql === 'string' || graphql instanceof String) && /^[a-zA-Z]+$/.test(graphql as string)) {
210
+ if (
211
+ (typeof graphql === 'string' || graphql instanceof String)
212
+ && /^(?![a-zA-Z]+$).*$/.test((graphql as string).trim())
213
+ ) {
210
214
  // Use input as query
211
- query = graphql as string;
215
+ query = (graphql as string).trim();
212
216
  } else {
213
217
  // Use input as name
214
218
  if (typeof graphql === 'string' || graphql instanceof String) {
215
- graphql = { name: graphql } as any;
219
+ graphql = { name: (graphql as string).trim() } as any;
216
220
  }
217
221
 
218
222
  // Prepare config
@@ -225,6 +229,7 @@ export class TestHelper {
225
229
  },
226
230
  graphql,
227
231
  ) as TestGraphQLConfig;
232
+ name = graphql.name;
228
233
 
229
234
  // Init request
230
235
  const queryObj = {};
@@ -248,7 +253,11 @@ export class TestHelper {
248
253
  }
249
254
 
250
255
  // Create request payload query
251
- query = jsonToGraphQLQuery(queryObj, { pretty: true });
256
+ if (!graphql.fields?.length && !graphql.arguments) {
257
+ query = `${graphql.type} { ${graphql.name} }`;
258
+ } else {
259
+ query = jsonToGraphQLQuery(queryObj, { pretty: true });
260
+ }
252
261
  }
253
262
 
254
263
  if ((graphql as TestGraphQLConfig).type === TestGraphQLType.SUBSCRIPTION) {
@@ -298,7 +307,21 @@ export class TestHelper {
298
307
  expect(response.headers['content-type']).toMatch('application/json');
299
308
 
300
309
  // return data
301
- return response.body.data ? response.body.data[(graphql as TestGraphQLConfig).name] : response.body;
310
+ if (response.body) {
311
+ if (response.body.data) {
312
+ return name ? response.body.data[(graphql as TestGraphQLConfig).name] : response.body.data;
313
+ }
314
+ return response.body;
315
+ }
316
+ if (response.text) {
317
+ if (JSON.parse(response.text).data) {
318
+ return name
319
+ ? JSON.parse(response.text).data[(graphql as TestGraphQLConfig).name]
320
+ : JSON.parse(response.text).data;
321
+ }
322
+ return JSON.parse(response.text);
323
+ }
324
+ return undefined;
302
325
  }
303
326
 
304
327
  /**