@lenne.tech/nest-server 10.1.0 → 10.2.0
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/dist/config.env.js +1 -1
- package/dist/core/common/interceptors/check-security.interceptor.js +19 -2
- package/dist/core/common/interceptors/check-security.interceptor.js.map +1 -1
- package/dist/core/common/interfaces/cron-job-config-with-time-zone.interface.d.ts +6 -0
- package/dist/core/common/interfaces/cron-job-config-with-time-zone.interface.js +3 -0
- package/dist/core/common/interfaces/cron-job-config-with-time-zone.interface.js.map +1 -0
- package/dist/core/common/interfaces/cron-job-config-with-utc-offset.interface.d.ts +6 -0
- package/dist/core/common/interfaces/cron-job-config-with-utc-offset.interface.js +3 -0
- package/dist/core/common/interfaces/cron-job-config-with-utc-offset.interface.js.map +1 -0
- package/dist/core/common/interfaces/cron-job-config.interface.d.ts +9 -11
- package/dist/core/common/interfaces/server-options.interface.d.ts +3 -2
- package/dist/core/common/services/core-cron-jobs.service.d.ts +4 -3
- package/dist/core/common/services/core-cron-jobs.service.js +1 -1
- package/dist/core/common/services/core-cron-jobs.service.js.map +1 -1
- package/dist/core/common/services/crud.service.d.ts +10 -1
- package/dist/core/common/services/crud.service.js +16 -0
- package/dist/core/common/services/crud.service.js.map +1 -1
- package/dist/core/common/services/module.service.js +9 -1
- package/dist/core/common/services/module.service.js.map +1 -1
- package/dist/core/common/types/array-element.type.d.ts +1 -0
- package/dist/core/common/types/array-element.type.js +3 -0
- package/dist/core/common/types/array-element.type.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -1
- package/dist/tsconfig.build.tsbuildinfo +1 -1
- package/package.json +41 -42
- package/src/config.env.ts +1 -1
- package/src/core/common/interceptors/check-security.interceptor.ts +19 -2
- package/src/core/common/interfaces/cron-job-config-with-time-zone.interface.ts +23 -0
- package/src/core/common/interfaces/cron-job-config-with-utc-offset.interface.ts +24 -0
- package/src/core/common/interfaces/cron-job-config.interface.ts +10 -11
- package/src/core/common/interfaces/server-options.interface.ts +3 -2
- package/src/core/common/services/core-cron-jobs.service.ts +10 -7
- package/src/core/common/services/crud.service.ts +40 -2
- package/src/core/common/services/module.service.ts +9 -1
- package/src/core/common/types/array-element.type.ts +5 -0
- package/src/index.ts +3 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lenne.tech/nest-server",
|
|
3
|
-
"version": "10.
|
|
3
|
+
"version": "10.2.0",
|
|
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",
|
|
@@ -33,10 +33,10 @@
|
|
|
33
33
|
"start:prod": "./node_modules/.bin/grunt production",
|
|
34
34
|
"start:nodemon": "ts-node -r tsconfig-paths/register src/main.ts",
|
|
35
35
|
"start:debug": "nodemon --config nodemon-debug.json",
|
|
36
|
-
"start:dev": "
|
|
37
|
-
"start:dev:
|
|
38
|
-
"start:local": "NODE_ENV=local
|
|
39
|
-
"start:local:
|
|
36
|
+
"start:dev": "nodemon",
|
|
37
|
+
"start:dev:swc": "nest start -b swc -w --type-check",
|
|
38
|
+
"start:local": "NODE_ENV=local nodemon",
|
|
39
|
+
"start:local:swc": "NODE_ENV=local nest start -b swc -w --type-check",
|
|
40
40
|
"test": "NODE_ENV=local jest",
|
|
41
41
|
"test:cov": "NODE_ENV=local jest --coverage",
|
|
42
42
|
"test:debug": "NODE_ENV=local node --inspect-brk -r tsconfig-paths/register -r ts-node/register node_modules/.bin/jest --runInBand",
|
|
@@ -62,21 +62,21 @@
|
|
|
62
62
|
"node": ">= 16.13.0"
|
|
63
63
|
},
|
|
64
64
|
"dependencies": {
|
|
65
|
-
"@apollo/gateway": "2.5.
|
|
65
|
+
"@apollo/gateway": "2.5.7",
|
|
66
66
|
"@lenne.tech/mongoose-gridfs": "1.4.2",
|
|
67
67
|
"@lenne.tech/multer-gridfs-storage": "5.0.6",
|
|
68
|
-
"@nestjs/apollo": "12.0.
|
|
69
|
-
"@nestjs/common": "10.2.
|
|
70
|
-
"@nestjs/core": "10.2.
|
|
71
|
-
"@nestjs/graphql": "12.0.
|
|
72
|
-
"@nestjs/jwt": "10.
|
|
73
|
-
"@nestjs/mongoose": "10.0.
|
|
68
|
+
"@nestjs/apollo": "12.0.11",
|
|
69
|
+
"@nestjs/common": "10.2.9",
|
|
70
|
+
"@nestjs/core": "10.2.9",
|
|
71
|
+
"@nestjs/graphql": "12.0.11",
|
|
72
|
+
"@nestjs/jwt": "10.2.0",
|
|
73
|
+
"@nestjs/mongoose": "10.0.2",
|
|
74
74
|
"@nestjs/passport": "10.0.2",
|
|
75
|
-
"@nestjs/platform-express": "10.2.
|
|
76
|
-
"@nestjs/schedule": "
|
|
75
|
+
"@nestjs/platform-express": "10.2.9",
|
|
76
|
+
"@nestjs/schedule": "4.0.0",
|
|
77
77
|
"@nestjs/terminus": "10.1.1",
|
|
78
|
-
"apollo-server-core": "3.
|
|
79
|
-
"apollo-server-express": "3.
|
|
78
|
+
"apollo-server-core": "3.13.0",
|
|
79
|
+
"apollo-server-express": "3.13.0",
|
|
80
80
|
"bcrypt": "5.1.1",
|
|
81
81
|
"class-transformer": "0.5.1",
|
|
82
82
|
"class-validator": "0.14.0",
|
|
@@ -91,11 +91,11 @@
|
|
|
91
91
|
"json-to-graphql-query": "2.2.5",
|
|
92
92
|
"light-my-request": "5.11.0",
|
|
93
93
|
"lodash": "4.17.21",
|
|
94
|
-
"mongodb": "6.
|
|
95
|
-
"mongoose": "7.6.
|
|
94
|
+
"mongodb": "6.3.0",
|
|
95
|
+
"mongoose": "7.6.5",
|
|
96
96
|
"multer": "1.4.5-lts.1",
|
|
97
97
|
"node-mailjet": "6.0.4",
|
|
98
|
-
"nodemailer": "6.9.
|
|
98
|
+
"nodemailer": "6.9.7",
|
|
99
99
|
"nodemon": "3.0.1",
|
|
100
100
|
"passport": "0.6.0",
|
|
101
101
|
"passport-jwt": "4.0.1",
|
|
@@ -109,28 +109,27 @@
|
|
|
109
109
|
"@babel/plugin-proposal-private-methods": "7.18.6",
|
|
110
110
|
"@compodoc/compodoc": "1.1.22",
|
|
111
111
|
"@lenne.tech/eslint-config-ts": "0.0.10",
|
|
112
|
-
"@nestjs/cli": "10.1
|
|
113
|
-
"@nestjs/schematics": "10.0.
|
|
114
|
-
"@nestjs/testing": "10.2.
|
|
115
|
-
"@swc/cli": "0.1.
|
|
116
|
-
"@swc/core": "1.3.
|
|
112
|
+
"@nestjs/cli": "10.2.1",
|
|
113
|
+
"@nestjs/schematics": "10.0.3",
|
|
114
|
+
"@nestjs/testing": "10.2.9",
|
|
115
|
+
"@swc/cli": "0.1.63",
|
|
116
|
+
"@swc/core": "1.3.96",
|
|
117
117
|
"@swc/jest": "0.2.29",
|
|
118
|
-
"@types/compression": "1.7.
|
|
119
|
-
"@types/cookie-parser": "1.4.
|
|
120
|
-
"@types/
|
|
121
|
-
"@types/
|
|
122
|
-
"@types/
|
|
123
|
-
"@types/
|
|
124
|
-
"@types/
|
|
125
|
-
"@types/
|
|
126
|
-
"@types/
|
|
127
|
-
"@types/
|
|
128
|
-
"@types/
|
|
129
|
-
"@
|
|
130
|
-
"@typescript-eslint/
|
|
131
|
-
"@typescript-eslint/parser": "6.8.0",
|
|
118
|
+
"@types/compression": "1.7.5",
|
|
119
|
+
"@types/cookie-parser": "1.4.6",
|
|
120
|
+
"@types/ejs": "3.1.5",
|
|
121
|
+
"@types/express": "4.17.21",
|
|
122
|
+
"@types/jest": "29.5.8",
|
|
123
|
+
"@types/lodash": "4.14.201",
|
|
124
|
+
"@types/multer": "1.4.10",
|
|
125
|
+
"@types/node": "20.9.1",
|
|
126
|
+
"@types/nodemailer": "6.4.14",
|
|
127
|
+
"@types/passport": "1.0.15",
|
|
128
|
+
"@types/supertest": "2.0.16",
|
|
129
|
+
"@typescript-eslint/eslint-plugin": "6.11.0",
|
|
130
|
+
"@typescript-eslint/parser": "6.11.0",
|
|
132
131
|
"coffeescript": "2.7.0",
|
|
133
|
-
"eslint": "8.
|
|
132
|
+
"eslint": "8.54.0",
|
|
134
133
|
"eslint-config-prettier": "9.0.0",
|
|
135
134
|
"eslint-plugin-unused-imports": "3.0.0",
|
|
136
135
|
"find-file-up": "2.0.1",
|
|
@@ -143,12 +142,12 @@
|
|
|
143
142
|
"jest": "29.7.0",
|
|
144
143
|
"npm-watch": "0.11.0",
|
|
145
144
|
"pm2": "5.3.0",
|
|
146
|
-
"prettier": "3.0
|
|
145
|
+
"prettier": "3.1.0",
|
|
147
146
|
"pretty-quick": "3.1.3",
|
|
148
147
|
"supertest": "6.3.3",
|
|
149
148
|
"ts-jest": "29.1.1",
|
|
150
|
-
"ts-loader": "9.5.
|
|
151
|
-
"ts-morph": "
|
|
149
|
+
"ts-loader": "9.5.1",
|
|
150
|
+
"ts-morph": "20.0.0",
|
|
152
151
|
"ts-node": "10.9.1",
|
|
153
152
|
"tsconfig-paths": "4.2.0",
|
|
154
153
|
"typescript": "5.2.2",
|
package/src/config.env.ts
CHANGED
|
@@ -2,6 +2,7 @@ import { CallHandler, ExecutionContext, Injectable, NestInterceptor } from '@nes
|
|
|
2
2
|
import { Observable } from 'rxjs';
|
|
3
3
|
import { map } from 'rxjs/operators';
|
|
4
4
|
import { getContextData } from '../helpers/context.helper';
|
|
5
|
+
import { getStringIds } from '../helpers/db.helper';
|
|
5
6
|
import { processDeep } from '../helpers/input.helper';
|
|
6
7
|
|
|
7
8
|
/**
|
|
@@ -28,7 +29,15 @@ export class CheckSecurityInterceptor implements NestInterceptor {
|
|
|
28
29
|
map((data) => {
|
|
29
30
|
// Check data
|
|
30
31
|
if (data && typeof data === 'object' && typeof data.securityCheck === 'function') {
|
|
31
|
-
|
|
32
|
+
const dataJson = JSON.stringify(data);
|
|
33
|
+
const response = data.securityCheck(user, force);
|
|
34
|
+
new Promise(() => {
|
|
35
|
+
if (dataJson !== JSON.stringify(response)) {
|
|
36
|
+
const id = getStringIds(data);
|
|
37
|
+
console.debug('CheckSecurityInterceptor: securityCheck changed data of type', data.constructor.name, id && !Array.isArray(id) ? `with ID: ${id}` : '');
|
|
38
|
+
}
|
|
39
|
+
});
|
|
40
|
+
return response;
|
|
32
41
|
}
|
|
33
42
|
|
|
34
43
|
// Check if data is writeable (e.g. objects from direct access to json files via http are not writable)
|
|
@@ -49,7 +58,15 @@ export class CheckSecurityInterceptor implements NestInterceptor {
|
|
|
49
58
|
}
|
|
50
59
|
return item;
|
|
51
60
|
}
|
|
52
|
-
|
|
61
|
+
const itemJson = JSON.stringify(item);
|
|
62
|
+
const response = item.securityCheck(user, force);
|
|
63
|
+
new Promise(() => {
|
|
64
|
+
if (itemJson !== JSON.stringify(response)) {
|
|
65
|
+
const id = getStringIds(item);
|
|
66
|
+
console.debug('CheckSecurityInterceptor: securityCheck changed item of type', item.constructor.name, id && !Array.isArray(id) ? `with ID: ${id}` : '');
|
|
67
|
+
}
|
|
68
|
+
});
|
|
69
|
+
return response;
|
|
53
70
|
},
|
|
54
71
|
{ specialFunctions: ['securityCheck'] },
|
|
55
72
|
);
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { CronJobParams, CronOnCompleteCommand } from 'cron';
|
|
2
|
+
import { CronJobConfig } from './cron-job-config.interface';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Interface for cron job configuration
|
|
6
|
+
*
|
|
7
|
+
* This config can define timezone but not utcOffset,
|
|
8
|
+
* if you want to use utcOffset, you have to use the CronJobConfigWithUtcOffset
|
|
9
|
+
*/
|
|
10
|
+
export interface CronJobConfigWithTimeZone<OC extends CronOnCompleteCommand | null = null, C = null> extends CronJobConfig {
|
|
11
|
+
/**
|
|
12
|
+
* Specify the timezone for the execution. This will modify the actual time relative to your timezone.
|
|
13
|
+
* If the timezone is invalid, an error is thrown. Can be any string accepted by luxon's `DateTime.setZone()`
|
|
14
|
+
* (https://moment.github.io/luxon/api-docs/index.html#datetimesetzone).
|
|
15
|
+
*/
|
|
16
|
+
timeZone?: CronJobParams<OC, C>['timeZone'];
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* This allows you to specify the offset of the timezone rather than using the `timeZone` parameter.
|
|
20
|
+
* Probably don't use both `timeZone` and `utcOffset` together or weird things may happen.
|
|
21
|
+
*/
|
|
22
|
+
utcOffset?: null;
|
|
23
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { CronJobParams, CronOnCompleteCommand } from 'cron';
|
|
2
|
+
import { CronJobConfig } from './cron-job-config.interface';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Interface for cron job configuration
|
|
6
|
+
*
|
|
7
|
+
* This config can define utcOffset but not timezone,
|
|
8
|
+
* if you want to use timezone, you have to use the CronJobConfigWithTimezone
|
|
9
|
+
*/
|
|
10
|
+
export interface CronJobConfigWithUtcOffset<OC extends CronOnCompleteCommand | null = null, C = null> extends CronJobConfig {
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Specify the timezone for the execution. This will modify the actual time relative to your timezone.
|
|
14
|
+
* If the timezone is invalid, an error is thrown. Can be any string accepted by luxon's `DateTime.setZone()`
|
|
15
|
+
* (https://moment.github.io/luxon/api-docs/index.html#datetimesetzone).
|
|
16
|
+
*/
|
|
17
|
+
timeZone?: null;
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* This allows you to specify the offset of the timezone rather than using the `timeZone` parameter.
|
|
21
|
+
* Probably don't use both `timeZone` and `utcOffset` together or weird things may happen.
|
|
22
|
+
*/
|
|
23
|
+
utcOffset?: CronJobParams<OC, C>['unrefTimeout'];
|
|
24
|
+
}
|
|
@@ -1,22 +1,21 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { CronCommand } from 'cron';
|
|
3
|
-
import { Falsy } from '../types/falsy.type';
|
|
1
|
+
import { CronJobParams, CronOnCompleteCommand } from 'cron';
|
|
4
2
|
|
|
5
3
|
/**
|
|
6
4
|
* Interface for cron job configuration
|
|
5
|
+
* @deprecated Use CronJobConfigWithTimeZone or CronJobConfigWithUtcOffset instead
|
|
7
6
|
*/
|
|
8
|
-
export interface CronJobConfig {
|
|
7
|
+
export interface CronJobConfig<OC extends CronOnCompleteCommand | null = null, C = null> {
|
|
9
8
|
/**
|
|
10
9
|
* The context within which to execute the onTick method. This defaults to the cronjob itself allowing you to call
|
|
11
10
|
* `this.stop()`. However, if you change this you'll have access to the functions and values within your context
|
|
12
11
|
* object.
|
|
13
12
|
*/
|
|
14
|
-
context?:
|
|
13
|
+
context?: CronJobParams<OC, C>['context'];
|
|
15
14
|
|
|
16
15
|
/**
|
|
17
16
|
* The time to fire off your job. This can be in the form of cron syntax or a JS `Date` object.
|
|
18
17
|
*/
|
|
19
|
-
cronTime:
|
|
18
|
+
cronTime: CronJobParams<OC, C>['cronTime'];
|
|
20
19
|
|
|
21
20
|
/**
|
|
22
21
|
* Whether the cron job is disabled or not.
|
|
@@ -27,13 +26,13 @@ export interface CronJobConfig {
|
|
|
27
26
|
/**
|
|
28
27
|
* A function that will fire when the job is complete, when it is stopped.
|
|
29
28
|
*/
|
|
30
|
-
onComplete?:
|
|
29
|
+
onComplete?: CronJobParams<OC, C>['onComplete'];
|
|
31
30
|
|
|
32
31
|
/**
|
|
33
32
|
* This will immediately fire the `onTick` function as soon as the requisite initialization has happened.
|
|
34
33
|
* This option is set to `true` by default.
|
|
35
34
|
*/
|
|
36
|
-
runOnInit?:
|
|
35
|
+
runOnInit?: CronJobParams<OC, C>['runOnInit'];
|
|
37
36
|
|
|
38
37
|
/**
|
|
39
38
|
* Depending on how long the execution of a job takes, it may happen that several executions take place at the
|
|
@@ -53,7 +52,7 @@ export interface CronJobConfig {
|
|
|
53
52
|
* If the timezone is invalid, an error is thrown. Can be any string accepted by luxon's `DateTime.setZone()`
|
|
54
53
|
* (https://moment.github.io/luxon/api-docs/index.html#datetimesetzone).
|
|
55
54
|
*/
|
|
56
|
-
timeZone?:
|
|
55
|
+
timeZone?: CronJobParams<OC, C>['timeZone'] | null;
|
|
57
56
|
|
|
58
57
|
/**
|
|
59
58
|
* If you have code that keeps the event loop running and want to stop the node process when that finishes
|
|
@@ -61,11 +60,11 @@ export interface CronJobConfig {
|
|
|
61
60
|
* cron will run as if it needs to control the event loop. For more information take a look at
|
|
62
61
|
* timers#timers_timeout_unref from the NodeJS docs.
|
|
63
62
|
*/
|
|
64
|
-
unrefTimeout?:
|
|
63
|
+
unrefTimeout?: CronJobParams<OC, C>['unrefTimeout'];
|
|
65
64
|
|
|
66
65
|
/**
|
|
67
66
|
* This allows you to specify the offset of the timezone rather than using the `timeZone` parameter.
|
|
68
67
|
* Probably don't use both `timeZone` and `utcOffset` together or weird things may happen.
|
|
69
68
|
*/
|
|
70
|
-
utcOffset?:
|
|
69
|
+
utcOffset?: CronJobParams<OC, C>['unrefTimeout'] | null;
|
|
71
70
|
}
|
|
@@ -11,7 +11,8 @@ import * as SMTPTransport from 'nodemailer/lib/smtp-transport';
|
|
|
11
11
|
import { MongoosePingCheckSettings } from '@nestjs/terminus/dist/health-indicator/database/mongoose.health';
|
|
12
12
|
import { DiskHealthIndicatorOptions } from '@nestjs/terminus/dist/health-indicator/disk/disk-health-options.type';
|
|
13
13
|
import { Falsy } from '../types/falsy.type';
|
|
14
|
-
import {
|
|
14
|
+
import { CronJobConfigWithTimeZone } from './cron-job-config-with-time-zone.interface';
|
|
15
|
+
import { CronJobConfigWithUtcOffset } from './cron-job-config-with-utc-offset.interface';
|
|
15
16
|
import { MailjetOptions } from './mailjet-options.interface';
|
|
16
17
|
|
|
17
18
|
/**
|
|
@@ -85,7 +86,7 @@ export interface IServerOptions {
|
|
|
85
86
|
* Cron jobs configuration object with the name of the cron job function as key
|
|
86
87
|
* and the cron expression or config as value
|
|
87
88
|
*/
|
|
88
|
-
cronJobs?: Record<string, CronExpression | string | Date | Falsy |
|
|
89
|
+
cronJobs?: Record<string, CronExpression | string | Date | Falsy | CronJobConfigWithTimeZone | CronJobConfigWithUtcOffset>;
|
|
89
90
|
|
|
90
91
|
/**
|
|
91
92
|
* SMTP and template configuration for sending emails
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { OnApplicationBootstrap } from '@nestjs/common';
|
|
2
2
|
import { CronExpression, SchedulerRegistry } from '@nestjs/schedule';
|
|
3
3
|
import { CronJob } from 'cron';
|
|
4
|
-
import {
|
|
4
|
+
import { CronJobConfigWithTimeZone } from '../interfaces/cron-job-config-with-time-zone.interface';
|
|
5
|
+
import { CronJobConfigWithUtcOffset } from '../interfaces/cron-job-config-with-utc-offset.interface';
|
|
5
6
|
import { Falsy } from '../types/falsy.type';
|
|
6
7
|
|
|
7
8
|
/**
|
|
@@ -30,7 +31,7 @@ export abstract class CoreCronJobs implements OnApplicationBootstrap {
|
|
|
30
31
|
*/
|
|
31
32
|
protected constructor(
|
|
32
33
|
protected schedulerRegistry: SchedulerRegistry,
|
|
33
|
-
protected cronJobs: Record<string, CronExpression | string | Date | Falsy |
|
|
34
|
+
protected cronJobs: Record<string, CronExpression | string | Date | Falsy | CronJobConfigWithTimeZone | CronJobConfigWithUtcOffset>,
|
|
34
35
|
options?: { log?: boolean },
|
|
35
36
|
) {
|
|
36
37
|
this.config = {
|
|
@@ -64,13 +65,14 @@ export abstract class CoreCronJobs implements OnApplicationBootstrap {
|
|
|
64
65
|
// Check config
|
|
65
66
|
if (
|
|
66
67
|
!CronExpressionOrConfig
|
|
67
|
-
|| (typeof CronExpressionOrConfig === 'object' && (CronExpressionOrConfig as
|
|
68
|
+
|| (typeof CronExpressionOrConfig === 'object' && (CronExpressionOrConfig as CronJobConfigWithTimeZone).disabled)
|
|
68
69
|
) {
|
|
69
70
|
continue;
|
|
70
71
|
}
|
|
71
72
|
|
|
72
73
|
// Prepare config
|
|
73
|
-
let conf:
|
|
74
|
+
let conf: CronJobConfigWithTimeZone | CronJobConfigWithUtcOffset
|
|
75
|
+
= CronExpressionOrConfig as CronJobConfigWithTimeZone | CronJobConfigWithUtcOffset;
|
|
74
76
|
if (typeof CronExpressionOrConfig === 'string' || CronExpressionOrConfig instanceof Date) {
|
|
75
77
|
conf = {
|
|
76
78
|
cronTime: CronExpressionOrConfig as string | Date,
|
|
@@ -78,13 +80,14 @@ export abstract class CoreCronJobs implements OnApplicationBootstrap {
|
|
|
78
80
|
}
|
|
79
81
|
|
|
80
82
|
// Set defaults
|
|
81
|
-
|
|
83
|
+
// Declared as CronJobConfigWithTimeZone to avoid type errors, but it can also be CronJobConfigWithUtcOffset
|
|
84
|
+
const config: CronJobConfigWithTimeZone = {
|
|
82
85
|
runOnInit: true,
|
|
83
86
|
runParallel: true,
|
|
84
87
|
throwException: true,
|
|
85
|
-
timeZone: 'Europe/Berlin',
|
|
88
|
+
timeZone: conf.utcOffset ? null : 'Europe/Berlin',
|
|
86
89
|
...conf,
|
|
87
|
-
};
|
|
90
|
+
} as unknown as CronJobConfigWithTimeZone;
|
|
88
91
|
|
|
89
92
|
// Check if cron job should be activated
|
|
90
93
|
if (!config?.cronTime) {
|
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
import { NotFoundException } from '@nestjs/common';
|
|
2
|
-
import { FilterQuery, PipelineStage, QueryOptions } from 'mongoose';
|
|
2
|
+
import { Document, FilterQuery, Model as MongooseModel, PipelineStage, Query, QueryOptions } from 'mongoose';
|
|
3
3
|
import { FilterArgs } from '../args/filter.args';
|
|
4
|
-
import { getStringIds } from '../helpers/db.helper';
|
|
4
|
+
import { getStringIds, popAndMap } from '../helpers/db.helper';
|
|
5
5
|
import { convertFilterArgsToQuery } from '../helpers/filter.helper';
|
|
6
6
|
import { mergePlain, prepareServiceOptionsForCreate } from '../helpers/input.helper';
|
|
7
7
|
import { ServiceOptions } from '../interfaces/service-options.interface';
|
|
8
8
|
import { CoreModel } from '../models/core-model.model';
|
|
9
|
+
import { ArrayElement } from '../types/array-element.type';
|
|
10
|
+
import { FieldSelection } from '../types/field-selection.type';
|
|
9
11
|
import { PlainObject } from '../types/plain-object.type';
|
|
10
12
|
import { ConfigService } from './config.service';
|
|
11
13
|
import { ModuleService } from './module.service';
|
|
@@ -474,4 +476,40 @@ export abstract class CrudService<
|
|
|
474
476
|
serviceOptions.prepareOutput = null;
|
|
475
477
|
return this.deleteForce(id, serviceOptions);
|
|
476
478
|
}
|
|
479
|
+
|
|
480
|
+
/**
|
|
481
|
+
* Populate, exec and map Mongoose query or document(s) with serviceOptions
|
|
482
|
+
* Generic T is the type of the returned object(s)
|
|
483
|
+
*
|
|
484
|
+
* @example const user = await this.populateAndProcessQuery<User>(User.findById(id), serviceOptions);
|
|
485
|
+
* @example const users = await this.populateAndProcessQuery<User[]>(User.find({name: {'$regex': 'ma'}}), serviceOptions);
|
|
486
|
+
*/
|
|
487
|
+
async populateAndProcessQuery<T extends CoreModel | CoreModel[] = CoreModel>(
|
|
488
|
+
queryOrDocument: Query<unknown, unknown> | Document | Document[],
|
|
489
|
+
options?: {
|
|
490
|
+
fieldSelection?: FieldSelection;
|
|
491
|
+
ignoreSelections?: boolean;
|
|
492
|
+
modelClass?: new (...args: any[]) => ArrayElement<T>;
|
|
493
|
+
populate?: FieldSelection;
|
|
494
|
+
mongooseModel?: MongooseModel<any>;
|
|
495
|
+
},
|
|
496
|
+
): Promise<T> {
|
|
497
|
+
const config = {
|
|
498
|
+
modelClass: this.mainModelConstructor,
|
|
499
|
+
mongooseModel: this.mainDbModel,
|
|
500
|
+
...options,
|
|
501
|
+
};
|
|
502
|
+
let result: T;
|
|
503
|
+
if (config.fieldSelection || config.populate) {
|
|
504
|
+
result = (await popAndMap<ArrayElement<T>>(
|
|
505
|
+
queryOrDocument,
|
|
506
|
+
config.populate || config.fieldSelection,
|
|
507
|
+
config.modelClass as new (...args: any[]) => ArrayElement<T>,
|
|
508
|
+
config.mongooseModel)
|
|
509
|
+
) as T;
|
|
510
|
+
} else if (queryOrDocument instanceof Query) {
|
|
511
|
+
result = (await queryOrDocument.exec()) as T;
|
|
512
|
+
}
|
|
513
|
+
return result;
|
|
514
|
+
}
|
|
477
515
|
}
|
|
@@ -131,7 +131,15 @@ export abstract class ModuleService<T extends CoreModel = any> {
|
|
|
131
131
|
if (!opts.targetModel && config.inputType) {
|
|
132
132
|
opts.targetModel = config.inputType;
|
|
133
133
|
}
|
|
134
|
-
|
|
134
|
+
const originalInput = config.input;
|
|
135
|
+
const inputJSON = JSON.stringify(originalInput);
|
|
136
|
+
const preparedInput = await this.prepareInput(config.input, config);
|
|
137
|
+
new Promise(() => {
|
|
138
|
+
if (inputJSON?.replace(/"password":\s*"[^"]*"/, '') !== JSON.stringify(preparedInput)?.replace(/"password":\s*"[^"]*"/, '')) {
|
|
139
|
+
console.debug('CheckSecurityInterceptor: securityCheck changed input of type', originalInput.constructor.name, 'to type', preparedInput.constructor.name);
|
|
140
|
+
}
|
|
141
|
+
});
|
|
142
|
+
config.input = preparedInput;
|
|
135
143
|
}
|
|
136
144
|
|
|
137
145
|
// Get DB object
|
package/src/index.ts
CHANGED
|
@@ -42,6 +42,8 @@ export * from './core/common/interceptors/check-response.interceptor';
|
|
|
42
42
|
export * from './core/common/interceptors/check-security.interceptor';
|
|
43
43
|
export * from './core/common/interfaces/core-persistence-model.interface';
|
|
44
44
|
export * from './core/common/interfaces/cron-job-config.interface';
|
|
45
|
+
export * from './core/common/interfaces/cron-job-config-with-time-zone.interface';
|
|
46
|
+
export * from './core/common/interfaces/cron-job-config-with-utc-offset.interface';
|
|
45
47
|
export * from './core/common/interfaces/mailjet-options.interface';
|
|
46
48
|
export * from './core/common/interfaces/prepare-input-options.interface';
|
|
47
49
|
export * from './core/common/interfaces/prepare-output-options.interface';
|
|
@@ -67,6 +69,7 @@ export * from './core/common/services/mailjet.service';
|
|
|
67
69
|
export * from './core/common/services/model-doc.service';
|
|
68
70
|
export * from './core/common/services/module.service';
|
|
69
71
|
export * from './core/common/services/template.service';
|
|
72
|
+
export * from './core/common/types/array-element.type';
|
|
70
73
|
export * from './core/common/types/core-model-constructor.type';
|
|
71
74
|
export * from './core/common/types/falsy.type';
|
|
72
75
|
export * from './core/common/types/field-selection.type';
|