@lenne.tech/nest-server 11.1.5 → 11.1.6
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/core/common/decorators/translatable.decorator.d.ts +1 -0
- package/dist/core/common/decorators/translatable.decorator.js +17 -0
- package/dist/core/common/decorators/translatable.decorator.js.map +1 -1
- package/dist/server/modules/user/inputs/user-create.input.d.ts +1 -0
- package/dist/server/modules/user/inputs/user-create.input.js +17 -0
- package/dist/server/modules/user/inputs/user-create.input.js.map +1 -1
- package/dist/server/modules/user/inputs/user.input.d.ts +1 -0
- package/dist/server/modules/user/inputs/user.input.js +17 -0
- package/dist/server/modules/user/inputs/user.input.js.map +1 -1
- package/dist/server/modules/user/user.model.d.ts +2 -0
- package/dist/server/modules/user/user.model.js +18 -0
- package/dist/server/modules/user/user.model.js.map +1 -1
- package/dist/server/modules/user/user.service.d.ts +1 -0
- package/dist/server/modules/user/user.service.js +8 -0
- package/dist/server/modules/user/user.service.js.map +1 -1
- package/dist/test/test.helper.d.ts +1 -0
- package/dist/test/test.helper.js +5 -1
- package/dist/test/test.helper.js.map +1 -1
- package/dist/tsconfig.build.tsbuildinfo +1 -1
- package/package.json +1 -1
- package/src/core/common/decorators/translatable.decorator.ts +25 -0
- package/src/server/modules/user/inputs/user-create.input.ts +9 -1
- package/src/server/modules/user/inputs/user.input.ts +9 -1
- package/src/server/modules/user/user.model.ts +14 -0
- package/src/server/modules/user/user.service.ts +9 -0
- package/src/test/test.helper.ts +11 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lenne.tech/nest-server",
|
|
3
|
-
"version": "11.1.
|
|
3
|
+
"version": "11.1.6",
|
|
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",
|
|
@@ -22,3 +22,28 @@ export function Translatable(): PropertyDecorator {
|
|
|
22
22
|
Reflect.defineMetadata(TRANSLATABLE_KEY, [...existingProperties, propertyKey], target.constructor);
|
|
23
23
|
};
|
|
24
24
|
}
|
|
25
|
+
|
|
26
|
+
export function updateLanguage<T extends Record<string, any>, K extends readonly (keyof T)[]>(
|
|
27
|
+
language: string,
|
|
28
|
+
input: any,
|
|
29
|
+
oldValue: T,
|
|
30
|
+
translatableFields: string[],
|
|
31
|
+
): T {
|
|
32
|
+
const changedFields: Partial<Pick<T, K[number]>> = {};
|
|
33
|
+
|
|
34
|
+
for (const key of translatableFields) {
|
|
35
|
+
const k = key as keyof T;
|
|
36
|
+
|
|
37
|
+
if (input[k] !== oldValue[k] && input[k] !== undefined) {
|
|
38
|
+
changedFields[k] = input[k];
|
|
39
|
+
input[k] = oldValue[k] as T[typeof k];
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
input._translations = input._translations ?? {};
|
|
44
|
+
input._translations[language] = {
|
|
45
|
+
...(input._translations[language] ?? {}),
|
|
46
|
+
...changedFields,
|
|
47
|
+
};
|
|
48
|
+
return input;
|
|
49
|
+
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { InputType } from '@nestjs/graphql';
|
|
1
|
+
import { Field, InputType } from '@nestjs/graphql';
|
|
2
|
+
import { IsOptional } from 'class-validator';
|
|
2
3
|
|
|
3
4
|
import { Restricted } from '../../../../core/common/decorators/restricted.decorator';
|
|
4
5
|
import { RoleEnum } from '../../../../core/common/enums/role.enum';
|
|
@@ -11,4 +12,11 @@ import { CoreUserCreateInput } from '../../../../core/modules/user/inputs/core-u
|
|
|
11
12
|
@Restricted(RoleEnum.ADMIN)
|
|
12
13
|
export class UserCreateInput extends CoreUserCreateInput {
|
|
13
14
|
// Extend UserCreateInput here
|
|
15
|
+
@Field(() => String, {
|
|
16
|
+
description: 'Job Title of the user',
|
|
17
|
+
nullable: true,
|
|
18
|
+
})
|
|
19
|
+
@IsOptional()
|
|
20
|
+
@Restricted(RoleEnum.ADMIN)
|
|
21
|
+
jobTitle?: string = undefined;
|
|
14
22
|
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { InputType } from '@nestjs/graphql';
|
|
1
|
+
import { Field, InputType } from '@nestjs/graphql';
|
|
2
|
+
import { IsOptional } from 'class-validator';
|
|
2
3
|
|
|
3
4
|
import { Restricted } from '../../../../core/common/decorators/restricted.decorator';
|
|
4
5
|
import { RoleEnum } from '../../../../core/common/enums/role.enum';
|
|
@@ -11,4 +12,11 @@ import { CoreUserInput } from '../../../../core/modules/user/inputs/core-user.in
|
|
|
11
12
|
@Restricted(RoleEnum.ADMIN)
|
|
12
13
|
export class UserInput extends CoreUserInput {
|
|
13
14
|
// Extend UserInput here
|
|
15
|
+
@Field(() => String, {
|
|
16
|
+
description: 'Job Title of the user',
|
|
17
|
+
nullable: true,
|
|
18
|
+
})
|
|
19
|
+
@IsOptional()
|
|
20
|
+
@Restricted(RoleEnum.ADMIN)
|
|
21
|
+
jobTitle?: string = undefined;
|
|
14
22
|
}
|
|
@@ -4,6 +4,7 @@ import { IsEmail, IsOptional } from 'class-validator';
|
|
|
4
4
|
import { Document, Schema } from 'mongoose';
|
|
5
5
|
|
|
6
6
|
import { Restricted } from '../../../core/common/decorators/restricted.decorator';
|
|
7
|
+
import { Translatable } from '../../../core/common/decorators/translatable.decorator';
|
|
7
8
|
import { RoleEnum } from '../../../core/common/enums/role.enum';
|
|
8
9
|
import { CoreUserModel } from '../../../core/modules/user/core-user.model';
|
|
9
10
|
import { PersistenceModel } from '../../common/models/persistence.model';
|
|
@@ -60,6 +61,15 @@ export class User extends CoreUserModel implements PersistenceModel {
|
|
|
60
61
|
@Restricted(RoleEnum.S_EVERYONE)
|
|
61
62
|
override roles: string[] = undefined;
|
|
62
63
|
|
|
64
|
+
@Field(() => String, {
|
|
65
|
+
description: 'Job title of user',
|
|
66
|
+
nullable: true,
|
|
67
|
+
})
|
|
68
|
+
@Prop()
|
|
69
|
+
@Restricted(RoleEnum.S_EVERYONE)
|
|
70
|
+
@Translatable()
|
|
71
|
+
jobTitle?: string = undefined;
|
|
72
|
+
|
|
63
73
|
/**
|
|
64
74
|
* ID of the user who updated the object
|
|
65
75
|
*
|
|
@@ -73,6 +83,10 @@ export class User extends CoreUserModel implements PersistenceModel {
|
|
|
73
83
|
@Restricted(RoleEnum.S_USER)
|
|
74
84
|
updatedBy: string = undefined;
|
|
75
85
|
|
|
86
|
+
@Prop({ default: {}, type: Schema.Types.Mixed })
|
|
87
|
+
@Restricted(RoleEnum.S_EVERYONE)
|
|
88
|
+
_translations?: Record<string, Partial<User>> = undefined;
|
|
89
|
+
|
|
76
90
|
// ===================================================================================================================
|
|
77
91
|
// Methods
|
|
78
92
|
// ===================================================================================================================
|
|
@@ -4,6 +4,7 @@ import fs = require('fs');
|
|
|
4
4
|
import { PubSub } from 'graphql-subscriptions';
|
|
5
5
|
import { Model } from 'mongoose';
|
|
6
6
|
|
|
7
|
+
import { getTranslatablePropertyKeys, updateLanguage } from '../../../core/common/decorators/translatable.decorator';
|
|
7
8
|
import { ServiceOptions } from '../../../core/common/interfaces/service-options.interface';
|
|
8
9
|
import { ConfigService } from '../../../core/common/services/config.service';
|
|
9
10
|
import { EmailService } from '../../../core/common/services/email.service';
|
|
@@ -62,6 +63,14 @@ export class UserService extends CoreUserService<User, UserInput, UserCreateInpu
|
|
|
62
63
|
return user;
|
|
63
64
|
}
|
|
64
65
|
|
|
66
|
+
override async update(id: string, input: UserInput, serviceOptions?: ServiceOptions): Promise<User> {
|
|
67
|
+
const dbObject = await super.get(id, serviceOptions);
|
|
68
|
+
if (serviceOptions.language && serviceOptions.language !== 'de') {
|
|
69
|
+
input = updateLanguage(serviceOptions.language, input, dbObject as UserInput, getTranslatablePropertyKeys(User));
|
|
70
|
+
}
|
|
71
|
+
return super.update(id, input, serviceOptions);
|
|
72
|
+
}
|
|
73
|
+
|
|
65
74
|
/**
|
|
66
75
|
* Request password reset mail
|
|
67
76
|
*/
|
package/src/test/test.helper.ts
CHANGED
|
@@ -83,6 +83,11 @@ export interface TestGraphQLOptions {
|
|
|
83
83
|
*/
|
|
84
84
|
countOfSubscriptionMessages?: number;
|
|
85
85
|
|
|
86
|
+
/**
|
|
87
|
+
* Language selected by user
|
|
88
|
+
*/
|
|
89
|
+
language?: string;
|
|
90
|
+
|
|
86
91
|
/**
|
|
87
92
|
* Output information in the console
|
|
88
93
|
*/
|
|
@@ -225,6 +230,7 @@ export class TestHelper {
|
|
|
225
230
|
const config = {
|
|
226
231
|
convertEnums: true,
|
|
227
232
|
countOfSubscriptionMessages: 1,
|
|
233
|
+
language: null,
|
|
228
234
|
log: false,
|
|
229
235
|
logError: false,
|
|
230
236
|
prepareArguments: true,
|
|
@@ -234,7 +240,7 @@ export class TestHelper {
|
|
|
234
240
|
};
|
|
235
241
|
|
|
236
242
|
// Init vars
|
|
237
|
-
const { log, logError, statusCode, token, variables } = config;
|
|
243
|
+
const { language, log, logError, statusCode, token, variables } = config;
|
|
238
244
|
|
|
239
245
|
// Init
|
|
240
246
|
let query = '';
|
|
@@ -337,6 +343,10 @@ export class TestHelper {
|
|
|
337
343
|
requestConfig.headers = { authorization: `Bearer ${token}` };
|
|
338
344
|
}
|
|
339
345
|
|
|
346
|
+
if (language) {
|
|
347
|
+
requestConfig.headers = { ...requestConfig.headers, 'accept-language': language };
|
|
348
|
+
}
|
|
349
|
+
|
|
340
350
|
// Get response
|
|
341
351
|
const response = await this.getResponse(token, requestConfig, statusCode, log, logError, variables);
|
|
342
352
|
|