@lenne.tech/nest-server 2.0.0-alpha8 → 2.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.
- package/dist/core/common/services/config.service.d.ts +1 -1
- package/dist/core/common/services/config.service.js +3 -3
- package/dist/core/common/services/config.service.js.map +1 -1
- package/dist/core/modules/auth/core-auth.module.js +5 -0
- package/dist/core/modules/auth/core-auth.module.js.map +1 -1
- package/dist/core/modules/auth/guards/auth.guard.js +7 -3
- package/dist/core/modules/auth/guards/auth.guard.js.map +1 -1
- package/dist/core/modules/user/core-user.service.js +2 -1
- package/dist/core/modules/user/core-user.service.js.map +1 -1
- package/dist/core.module.js +7 -0
- package/dist/core.module.js.map +1 -1
- package/dist/server/modules/user/user.module.js +10 -1
- package/dist/server/modules/user/user.module.js.map +1 -1
- package/dist/server/modules/user/user.resolver.d.ts +4 -2
- package/dist/server/modules/user/user.resolver.js +11 -8
- package/dist/server/modules/user/user.resolver.js.map +1 -1
- package/dist/server/modules/user/user.service.d.ts +3 -1
- package/dist/server/modules/user/user.service.js +9 -5
- package/dist/server/modules/user/user.service.js.map +1 -1
- package/dist/server/server.module.js.map +1 -1
- package/dist/tsconfig.build.tsbuildinfo +1 -1
- package/package.json +3 -3
- package/src/core/common/services/config.service.ts +7 -5
- package/src/core/modules/auth/core-auth.module.ts +5 -0
- package/src/core/modules/auth/guards/auth.guard.ts +5 -0
- package/src/core/modules/user/core-user.service.ts +2 -1
- package/src/core.module.ts +8 -0
- package/src/server/modules/user/user.module.ts +10 -1
- package/src/server/modules/user/user.resolver.ts +7 -8
- package/src/server/modules/user/user.service.ts +7 -7
- package/src/server/server.module.ts +1 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lenne.tech/nest-server",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.3",
|
|
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",
|
|
@@ -114,8 +114,7 @@
|
|
|
114
114
|
"supertest": "6.1.6",
|
|
115
115
|
"ts-morph": "11.0.3",
|
|
116
116
|
"ts-node": "9.1.1",
|
|
117
|
-
"tsconfig-paths": "3.10.1"
|
|
118
|
-
"ts-jest": "27.0.5"
|
|
117
|
+
"tsconfig-paths": "3.10.1"
|
|
119
118
|
},
|
|
120
119
|
"devDependencies": {
|
|
121
120
|
"eslint": "7.32.0",
|
|
@@ -124,6 +123,7 @@
|
|
|
124
123
|
"pm2": "5.1.0",
|
|
125
124
|
"prettier": "2.3.2",
|
|
126
125
|
"pretty-quick": "3.1.1",
|
|
126
|
+
"ts-jest": "27.0.5",
|
|
127
127
|
"typescript": "4.3.5"
|
|
128
128
|
},
|
|
129
129
|
"jest": {
|
|
@@ -14,20 +14,22 @@ export class ConfigService {
|
|
|
14
14
|
* Create config service
|
|
15
15
|
*/
|
|
16
16
|
constructor(config: { [key: string]: any } & Partial<IServerOptions>) {
|
|
17
|
-
this._config = config;
|
|
17
|
+
this._config = config || {};
|
|
18
18
|
}
|
|
19
19
|
|
|
20
20
|
/**
|
|
21
|
-
* Get config
|
|
21
|
+
* Get config (deep cloned to avoid unwanted side effects)
|
|
22
22
|
*/
|
|
23
23
|
get config() {
|
|
24
24
|
return _.cloneDeep(this._config);
|
|
25
25
|
}
|
|
26
26
|
|
|
27
27
|
/**
|
|
28
|
-
* Get data from config
|
|
28
|
+
* Get data from config (deep cloned to avoid unwanted side effects)
|
|
29
|
+
* @param key Property name of config object, which is to be returned
|
|
30
|
+
* @param defaultValue Default value which is to be returned if property doesn't exist
|
|
29
31
|
*/
|
|
30
|
-
get(key: string) {
|
|
31
|
-
return _.cloneDeep(_.get(this._config, key,
|
|
32
|
+
get(key: string, defaultValue: any = undefined) {
|
|
33
|
+
return _.cloneDeep(_.get(this._config, key, defaultValue));
|
|
32
34
|
}
|
|
33
35
|
}
|
|
@@ -6,6 +6,7 @@ import { RolesGuard } from './guards/roles.guard';
|
|
|
6
6
|
import { JwtStrategy } from './jwt.strategy';
|
|
7
7
|
import { CoreAuthUserService } from './services/core-auth-user.service';
|
|
8
8
|
import { CoreAuthService } from './services/core-auth.service';
|
|
9
|
+
import { PubSub } from 'graphql-subscriptions';
|
|
9
10
|
|
|
10
11
|
/**
|
|
11
12
|
* CoreAuthModule to handle user authentication and enables Roles
|
|
@@ -34,6 +35,10 @@ export class CoreAuthModule {
|
|
|
34
35
|
provide: CoreAuthUserService,
|
|
35
36
|
useClass: UserService,
|
|
36
37
|
},
|
|
38
|
+
{
|
|
39
|
+
provide: 'PUB_SUB',
|
|
40
|
+
useValue: new PubSub(),
|
|
41
|
+
},
|
|
37
42
|
|
|
38
43
|
// Standard services
|
|
39
44
|
CoreAuthService,
|
|
@@ -58,6 +58,11 @@ function createAuthGuard(type?: string): Type<CanActivate> {
|
|
|
58
58
|
* Integrate options
|
|
59
59
|
*/
|
|
60
60
|
async canActivate(context: ExecutionContext): Promise<boolean> {
|
|
61
|
+
const args = context.getArgs();
|
|
62
|
+
if (args.length > 0 && args[args.length - 1]?.operation?.operation === 'subscription') {
|
|
63
|
+
return true;
|
|
64
|
+
}
|
|
65
|
+
|
|
61
66
|
const options = { ...defaultOptions, ...this.options };
|
|
62
67
|
const response = context?.switchToHttp()?.getResponse();
|
|
63
68
|
let request = this.getRequest(context);
|
|
@@ -97,10 +97,11 @@ export abstract class CoreUserService<
|
|
|
97
97
|
* Get users via filter
|
|
98
98
|
*/
|
|
99
99
|
async find(filterArgs?: FilterArgs, ...args: any[]): Promise<TUser[]> {
|
|
100
|
+
const filterQuery = Filter.convertFilterArgsToQuery(filterArgs);
|
|
100
101
|
// Return found users
|
|
101
102
|
return await Promise.all(
|
|
102
103
|
(
|
|
103
|
-
await this.userModel.find(
|
|
104
|
+
await this.userModel.find(filterQuery[0], null, filterQuery[1]).exec()
|
|
104
105
|
).map((user) => {
|
|
105
106
|
return this.prepareOutput(user, args[0]);
|
|
106
107
|
})
|
package/src/core.module.ts
CHANGED
|
@@ -41,6 +41,14 @@ export class CoreModule {
|
|
|
41
41
|
autoSchemaFile: 'schema.gql',
|
|
42
42
|
context: ({ req }) => ({ req }),
|
|
43
43
|
installSubscriptionHandlers: true,
|
|
44
|
+
subscriptions: {
|
|
45
|
+
'subscriptions-transport-ws': {
|
|
46
|
+
onConnect: (connectionParams) => {
|
|
47
|
+
// TODO: Handle Authorization
|
|
48
|
+
const authToken = connectionParams.Authorization;
|
|
49
|
+
},
|
|
50
|
+
},
|
|
51
|
+
},
|
|
44
52
|
},
|
|
45
53
|
port: 3000,
|
|
46
54
|
mongoose: {
|
|
@@ -5,6 +5,7 @@ import { User, UserSchema } from './user.model';
|
|
|
5
5
|
import { UserResolver } from './user.resolver';
|
|
6
6
|
import { UserService } from './user.service';
|
|
7
7
|
import { MongooseModule } from '@nestjs/mongoose';
|
|
8
|
+
import { PubSub } from 'graphql-subscriptions';
|
|
8
9
|
|
|
9
10
|
/**
|
|
10
11
|
* User module
|
|
@@ -12,7 +13,15 @@ import { MongooseModule } from '@nestjs/mongoose';
|
|
|
12
13
|
@Module({
|
|
13
14
|
imports: [MongooseModule.forFeature([{ name: User.name, schema: UserSchema }])],
|
|
14
15
|
controllers: [AvatarController],
|
|
15
|
-
providers: [
|
|
16
|
+
providers: [
|
|
17
|
+
JSON,
|
|
18
|
+
UserResolver,
|
|
19
|
+
UserService,
|
|
20
|
+
{
|
|
21
|
+
provide: 'PUB_SUB',
|
|
22
|
+
useValue: new PubSub(),
|
|
23
|
+
},
|
|
24
|
+
],
|
|
16
25
|
exports: [MongooseModule, UserResolver, UserService],
|
|
17
26
|
})
|
|
18
27
|
export class UserModule {}
|
|
@@ -10,9 +10,7 @@ import { UserCreateInput } from './inputs/user-create.input';
|
|
|
10
10
|
import { UserInput } from './inputs/user.input';
|
|
11
11
|
import { User } from './user.model';
|
|
12
12
|
import { UserService } from './user.service';
|
|
13
|
-
|
|
14
|
-
// Subscription
|
|
15
|
-
const pubSub = new PubSub();
|
|
13
|
+
import { Inject } from '@nestjs/common';
|
|
16
14
|
|
|
17
15
|
/**
|
|
18
16
|
* Resolver to process with user data
|
|
@@ -22,7 +20,7 @@ export class UserResolver {
|
|
|
22
20
|
/**
|
|
23
21
|
* Import services
|
|
24
22
|
*/
|
|
25
|
-
constructor(protected readonly usersService: UserService) {}
|
|
23
|
+
constructor(protected readonly usersService: UserService, @Inject('PUB_SUB') protected readonly pubSub: PubSub) {}
|
|
26
24
|
|
|
27
25
|
// ===========================================================================
|
|
28
26
|
// Queries
|
|
@@ -96,9 +94,10 @@ export class UserResolver {
|
|
|
96
94
|
/**
|
|
97
95
|
* Subscritption for create user
|
|
98
96
|
*/
|
|
99
|
-
@
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
97
|
+
@Subscription((returns) => User, {
|
|
98
|
+
resolve: (value) => value,
|
|
99
|
+
})
|
|
100
|
+
async userCreated() {
|
|
101
|
+
return this.pubSub.asyncIterator('userCreated');
|
|
103
102
|
}
|
|
104
103
|
}
|
|
@@ -1,7 +1,6 @@
|
|
|
1
|
-
import { Injectable, UnauthorizedException, UnprocessableEntityException } from '@nestjs/common';
|
|
1
|
+
import { Inject, Injectable, UnauthorizedException, UnprocessableEntityException } from '@nestjs/common';
|
|
2
2
|
import * as fs from 'fs';
|
|
3
3
|
import { GraphQLResolveInfo } from 'graphql';
|
|
4
|
-
import { PubSub } from 'graphql-subscriptions';
|
|
5
4
|
import envConfig from '../../../config.env';
|
|
6
5
|
import { FilterArgs } from '../../../core/common/args/filter.args';
|
|
7
6
|
import { Filter } from '../../../core/common/helpers/filter.helper';
|
|
@@ -15,9 +14,7 @@ import { User } from './user.model';
|
|
|
15
14
|
import { InjectModel } from '@nestjs/mongoose';
|
|
16
15
|
import { Model } from 'mongoose';
|
|
17
16
|
import { ICorePersistenceModel } from '../../../core/common/interfaces/core-persistence-model.interface';
|
|
18
|
-
|
|
19
|
-
// Subscription
|
|
20
|
-
const pubSub = new PubSub();
|
|
17
|
+
import { PubSub } from 'graphql-subscriptions';
|
|
21
18
|
|
|
22
19
|
/**
|
|
23
20
|
* User service
|
|
@@ -42,7 +39,8 @@ export class UserService extends CoreUserService<User, UserInput, UserCreateInpu
|
|
|
42
39
|
constructor(
|
|
43
40
|
protected readonly configService: ConfigService,
|
|
44
41
|
protected readonly emailService: EmailService,
|
|
45
|
-
@InjectModel('User') protected readonly userModel: Model<User
|
|
42
|
+
@InjectModel('User') protected readonly userModel: Model<User>,
|
|
43
|
+
@Inject('PUB_SUB') protected readonly pubSub: PubSub
|
|
46
44
|
) {
|
|
47
45
|
super(userModel);
|
|
48
46
|
this.model = User;
|
|
@@ -58,6 +56,7 @@ export class UserService extends CoreUserService<User, UserInput, UserCreateInpu
|
|
|
58
56
|
async create(input: UserCreateInput, currentUser?: User, ...args: any[]): Promise<User> {
|
|
59
57
|
const user = await super.create(input, currentUser);
|
|
60
58
|
const text = `Welcome ${user.firstName}, this is plain text from server.`;
|
|
59
|
+
await this.pubSub.publish('userCreated', User.map(user));
|
|
61
60
|
await this.emailService.sendMail(user.email, 'Welcome', {
|
|
62
61
|
htmlTemplate: 'welcome',
|
|
63
62
|
templateData: user,
|
|
@@ -71,8 +70,9 @@ export class UserService extends CoreUserService<User, UserInput, UserCreateInpu
|
|
|
71
70
|
* Get users via filter
|
|
72
71
|
*/
|
|
73
72
|
find(filterArgs?: FilterArgs, ...args: any[]): Promise<User[]> {
|
|
73
|
+
const filterQuery = Filter.convertFilterArgsToQuery(filterArgs);
|
|
74
74
|
// Return found users
|
|
75
|
-
return this.userModel.find(
|
|
75
|
+
return this.userModel.find(filterQuery[0], null, filterQuery[1]).exec();
|
|
76
76
|
}
|
|
77
77
|
|
|
78
78
|
/**
|
|
@@ -4,6 +4,7 @@ import { CoreModule } from '../core.module';
|
|
|
4
4
|
import { AuthModule } from './modules/auth/auth.module';
|
|
5
5
|
import { FileController } from './modules/file/file.controller';
|
|
6
6
|
import { ServerController } from './server.controller';
|
|
7
|
+
import { PubSub } from 'graphql-subscriptions';
|
|
7
8
|
|
|
8
9
|
/**
|
|
9
10
|
* Server module (dynamic)
|