@tsed/socketio 8.0.1 → 8.0.2
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 +16 -15
- package/src/SocketIOModule.spec.ts +87 -0
- package/src/SocketIOModule.ts +113 -0
- package/src/class/SocketHandlersBuilder.spec.ts +988 -0
- package/src/class/SocketHandlersBuilder.ts +266 -0
- package/src/class/SocketProviderMetadata.ts +57 -0
- package/src/class/SocketSessionData.spec.ts +190 -0
- package/src/class/SocketSessionData.ts +81 -0
- package/src/constants/constants.ts +1 -0
- package/src/decorators/args.spec.ts +57 -0
- package/src/decorators/args.ts +60 -0
- package/src/decorators/broadcast.spec.ts +23 -0
- package/src/decorators/broadcast.ts +28 -0
- package/src/decorators/broadcastOthers.spec.ts +23 -0
- package/src/decorators/broadcastOthers.ts +28 -0
- package/src/decorators/emit.spec.ts +23 -0
- package/src/decorators/emit.ts +28 -0
- package/src/decorators/input.spec.ts +22 -0
- package/src/decorators/input.ts +33 -0
- package/src/decorators/inputAndBroadcast.spec.ts +25 -0
- package/src/decorators/inputAndBroadcast.ts +28 -0
- package/src/decorators/inputAndBroadcastOthers.spec.ts +24 -0
- package/src/decorators/inputAndBroadcastOthers.ts +28 -0
- package/src/decorators/inputAndEmit.spec.ts +24 -0
- package/src/decorators/inputAndEmit.ts +28 -0
- package/src/decorators/io.ts +34 -0
- package/src/decorators/nsp.spec.ts +70 -0
- package/src/decorators/nsp.ts +101 -0
- package/src/decorators/reason.spec.ts +26 -0
- package/src/decorators/reason.ts +30 -0
- package/src/decorators/socket.spec.ts +26 -0
- package/src/decorators/socket.ts +32 -0
- package/src/decorators/socketErr.spec.ts +25 -0
- package/src/decorators/socketErr.ts +26 -0
- package/src/decorators/socketEventName.spec.ts +25 -0
- package/src/decorators/socketEventName.ts +26 -0
- package/src/decorators/socketFilter.ts +27 -0
- package/src/decorators/socketMiddleware.spec.ts +21 -0
- package/src/decorators/socketMiddleware.ts +72 -0
- package/src/decorators/socketMiddlewareError.spec.ts +22 -0
- package/src/decorators/socketMiddlewareError.ts +70 -0
- package/src/decorators/socketNsp.spec.ts +26 -0
- package/src/decorators/socketNsp.ts +32 -0
- package/src/decorators/socketReturns.ts +25 -0
- package/src/decorators/socketService.spec.ts +44 -0
- package/src/decorators/socketService.ts +24 -0
- package/src/decorators/socketSession.spec.ts +47 -0
- package/src/decorators/socketSession.ts +53 -0
- package/src/decorators/socketUseAfter.spec.ts +38 -0
- package/src/decorators/socketUseAfter.ts +69 -0
- package/src/decorators/socketUseBefore.spec.ts +34 -0
- package/src/decorators/socketUseBefore.ts +73 -0
- package/src/index.ts +41 -0
- package/src/interfaces/OnNamespaceInit.ts +8 -0
- package/src/interfaces/SocketFilters.ts +14 -0
- package/src/interfaces/SocketHandlerMetadata.ts +17 -0
- package/src/interfaces/SocketInjectableNsp.ts +4 -0
- package/src/interfaces/SocketParamMetadata.ts +9 -0
- package/src/interfaces/SocketProviderTypes.ts +7 -0
- package/src/interfaces/SocketReturnsTypes.ts +8 -0
- package/src/interfaces/interfaces.ts +9 -0
- package/src/services/SocketIOServer.spec.ts +33 -0
- package/src/services/SocketIOServer.ts +15 -0
- package/src/services/SocketIOService.spec.ts +54 -0
- package/src/services/SocketIOService.ts +69 -0
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import {SocketFilters} from "../interfaces/SocketFilters.js";
|
|
2
|
+
import {SocketFilter} from "./socketFilter.js";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Inject the disconnection reason into the decorated parameter.
|
|
6
|
+
*
|
|
7
|
+
* This decorator is used in conjunction with the `$onDisconnect` event handler to handle disconnection reasons in SocketIO services.
|
|
8
|
+
* It allows you to access the reason for the disconnection in your method implementation. For details please refer to the [Socket.io documentation](https://socket.io/docs/v4/server-api/#event-disconnect).
|
|
9
|
+
*
|
|
10
|
+
* @example
|
|
11
|
+
* ```typescript
|
|
12
|
+
* @SocketService("/nsp")
|
|
13
|
+
* export class MyWS {
|
|
14
|
+
* public async $onDisconnect(
|
|
15
|
+
* @Reason reason: string = ''
|
|
16
|
+
* ) {
|
|
17
|
+
* // your implementation
|
|
18
|
+
* }
|
|
19
|
+
* }
|
|
20
|
+
* ```
|
|
21
|
+
*
|
|
22
|
+
* @experimental This decorator is experimental and may change or be removed in future versions.
|
|
23
|
+
* @param target
|
|
24
|
+
* @param {string} propertyKey
|
|
25
|
+
* @param {number} index
|
|
26
|
+
* @decorator
|
|
27
|
+
*/
|
|
28
|
+
export function Reason(target: unknown, propertyKey: string, index: number) {
|
|
29
|
+
return SocketFilter(SocketFilters.REASON)(target, propertyKey, index);
|
|
30
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import {Store} from "@tsed/core";
|
|
2
|
+
|
|
3
|
+
import {Socket} from "../index.js";
|
|
4
|
+
|
|
5
|
+
describe("Socket", () => {
|
|
6
|
+
it("should set metadata", () => {
|
|
7
|
+
class Test {}
|
|
8
|
+
|
|
9
|
+
Socket(Test, "test", 0);
|
|
10
|
+
|
|
11
|
+
const store = Store.from(Test);
|
|
12
|
+
|
|
13
|
+
expect(store.get("socketIO")).toEqual({
|
|
14
|
+
handlers: {
|
|
15
|
+
test: {
|
|
16
|
+
parameters: {
|
|
17
|
+
"0": {
|
|
18
|
+
filter: "socket",
|
|
19
|
+
mapIndex: undefined
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
});
|
|
25
|
+
});
|
|
26
|
+
});
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import {Socket as SocketType} from "socket.io";
|
|
2
|
+
|
|
3
|
+
import {SocketFilters} from "../interfaces/SocketFilters.js";
|
|
4
|
+
import {SocketFilter} from "./socketFilter.js";
|
|
5
|
+
|
|
6
|
+
export type Socket = SocketType;
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Inject the Socket instance in the decorated parameter.
|
|
10
|
+
*
|
|
11
|
+
* ### Example
|
|
12
|
+
*
|
|
13
|
+
* ```typescript
|
|
14
|
+
* @SocketService("/nsp")
|
|
15
|
+
* export class MyWS {
|
|
16
|
+
*
|
|
17
|
+
* @Input("event")
|
|
18
|
+
* myMethod(@Socket socket) {
|
|
19
|
+
*
|
|
20
|
+
* }
|
|
21
|
+
* }
|
|
22
|
+
* ```
|
|
23
|
+
*
|
|
24
|
+
* @experimental
|
|
25
|
+
* @param target
|
|
26
|
+
* @param {string} propertyKey
|
|
27
|
+
* @param {number} index
|
|
28
|
+
* @decorator
|
|
29
|
+
*/
|
|
30
|
+
export function Socket(target: any, propertyKey: string, index: number): any {
|
|
31
|
+
return SocketFilter(SocketFilters.SOCKET)(target, propertyKey, index);
|
|
32
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import {Store} from "@tsed/core";
|
|
2
|
+
|
|
3
|
+
import {SocketErr} from "../index.js";
|
|
4
|
+
|
|
5
|
+
describe("@SocketErr", () => {
|
|
6
|
+
it("should set metadata", () => {
|
|
7
|
+
class Test {}
|
|
8
|
+
|
|
9
|
+
SocketErr(Test, "test", 0);
|
|
10
|
+
const store = Store.from(Test);
|
|
11
|
+
|
|
12
|
+
expect(store.get("socketIO")).toEqual({
|
|
13
|
+
handlers: {
|
|
14
|
+
test: {
|
|
15
|
+
parameters: {
|
|
16
|
+
"0": {
|
|
17
|
+
filter: "error",
|
|
18
|
+
mapIndex: undefined
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
});
|
|
24
|
+
});
|
|
25
|
+
});
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import {SocketFilters} from "../interfaces/SocketFilters.js";
|
|
2
|
+
import {SocketFilter} from "./socketFilter.js";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Inject the error in the parameters
|
|
6
|
+
*
|
|
7
|
+
* ### Example
|
|
8
|
+
*
|
|
9
|
+
* ```typescript
|
|
10
|
+
* @SocketMiddlewareError()
|
|
11
|
+
* export class MyMiddleware {
|
|
12
|
+
*
|
|
13
|
+
* myMethod(@SocketErr err: any, @Args() arguments: any[]) {
|
|
14
|
+
*
|
|
15
|
+
* }
|
|
16
|
+
* }
|
|
17
|
+
* ```
|
|
18
|
+
*
|
|
19
|
+
* @decorator
|
|
20
|
+
* @param target
|
|
21
|
+
* @param propertyKey
|
|
22
|
+
* @param index
|
|
23
|
+
*/
|
|
24
|
+
export function SocketErr(target: any, propertyKey: string, index: number): any {
|
|
25
|
+
return SocketFilter(SocketFilters.ERR)(target, propertyKey, index);
|
|
26
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import {Store} from "@tsed/core";
|
|
2
|
+
|
|
3
|
+
import {SocketEventName} from "../index.js";
|
|
4
|
+
|
|
5
|
+
describe("@SocketEventName", () => {
|
|
6
|
+
it("should set metadata", () => {
|
|
7
|
+
class Test {}
|
|
8
|
+
|
|
9
|
+
SocketEventName(Test, "test", 0);
|
|
10
|
+
const store = Store.from(Test);
|
|
11
|
+
|
|
12
|
+
expect(store.get("socketIO")).toEqual({
|
|
13
|
+
handlers: {
|
|
14
|
+
test: {
|
|
15
|
+
parameters: {
|
|
16
|
+
"0": {
|
|
17
|
+
filter: "eventName",
|
|
18
|
+
mapIndex: undefined
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
});
|
|
24
|
+
});
|
|
25
|
+
});
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import {SocketFilters} from "../interfaces/SocketFilters.js";
|
|
2
|
+
import {SocketFilter} from "./socketFilter.js";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Inject the Socket instance in the decorated parameter.
|
|
6
|
+
*
|
|
7
|
+
* ### Example
|
|
8
|
+
*
|
|
9
|
+
* ```typescript
|
|
10
|
+
* @SocketMiddleware("/nsp")
|
|
11
|
+
* export class MyMiddleware {
|
|
12
|
+
* use(@SocketEventName eventName: string) {
|
|
13
|
+
*
|
|
14
|
+
* }
|
|
15
|
+
* }
|
|
16
|
+
* ```
|
|
17
|
+
*
|
|
18
|
+
* @experimental
|
|
19
|
+
* @param target
|
|
20
|
+
* @param {string} propertyKey
|
|
21
|
+
* @param {number} index
|
|
22
|
+
* @decorator
|
|
23
|
+
*/
|
|
24
|
+
export function SocketEventName(target: any, propertyKey: string, index: number): any {
|
|
25
|
+
return SocketFilter(SocketFilters.EVENT_NAME)(target, propertyKey, index);
|
|
26
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import {Store} from "@tsed/core";
|
|
2
|
+
|
|
3
|
+
import {SocketFilters} from "../interfaces/SocketFilters.js";
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
*
|
|
7
|
+
* @param {SocketFilters} filter
|
|
8
|
+
* @param {number} mapIndex
|
|
9
|
+
* @returns {(target: any, propertyKey: string, index: number) => Store}
|
|
10
|
+
* @decorator
|
|
11
|
+
*/
|
|
12
|
+
export function SocketFilter(filter: SocketFilters, mapIndex?: number) {
|
|
13
|
+
return (target: any, propertyKey: string, index: number) => {
|
|
14
|
+
Store.from(target).merge("socketIO", {
|
|
15
|
+
handlers: {
|
|
16
|
+
[propertyKey]: {
|
|
17
|
+
parameters: {
|
|
18
|
+
[index]: {
|
|
19
|
+
filter,
|
|
20
|
+
mapIndex
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
});
|
|
26
|
+
};
|
|
27
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import {Store} from "@tsed/core";
|
|
2
|
+
|
|
3
|
+
import {SocketMiddleware, SocketProviderTypes} from "../index.js";
|
|
4
|
+
|
|
5
|
+
describe("@SocketMiddleware", () => {
|
|
6
|
+
it("should register the middleware", () => {
|
|
7
|
+
@SocketMiddleware()
|
|
8
|
+
class Test {
|
|
9
|
+
use() {}
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
expect(Store.from(Test).get("socketIO")).toEqual({
|
|
13
|
+
type: SocketProviderTypes.MIDDLEWARE,
|
|
14
|
+
handlers: {
|
|
15
|
+
use: {
|
|
16
|
+
methodClassName: "use"
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
});
|
|
20
|
+
});
|
|
21
|
+
});
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import {Store, Type} from "@tsed/core";
|
|
2
|
+
import {Middleware} from "@tsed/platform-middlewares";
|
|
3
|
+
|
|
4
|
+
import {SocketProviderTypes} from "../interfaces/SocketProviderTypes.js";
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Declare a new SocketMiddleware.
|
|
8
|
+
*
|
|
9
|
+
* ### Example
|
|
10
|
+
*
|
|
11
|
+
* A middleware can be also used on a `SocketService` either on a class or on a method.
|
|
12
|
+
*
|
|
13
|
+
* Here an example of a middleware:
|
|
14
|
+
*
|
|
15
|
+
* ```typescript
|
|
16
|
+
* @SocketMiddleware()
|
|
17
|
+
* export class UserConverterSocketMiddleware {
|
|
18
|
+
* constructor(private converterService: ConverterService) {
|
|
19
|
+
* }
|
|
20
|
+
* async use(@Args() args: any[]) {
|
|
21
|
+
*
|
|
22
|
+
* let [user] = args;
|
|
23
|
+
* // update Arguments
|
|
24
|
+
* user = this.converterService.deserialize(user, User);
|
|
25
|
+
*
|
|
26
|
+
* return [user];
|
|
27
|
+
* }
|
|
28
|
+
* }
|
|
29
|
+
* ```
|
|
30
|
+
* > The user instance will be forwarded to the next middleware and to your decorated method.
|
|
31
|
+
*
|
|
32
|
+
* Then:
|
|
33
|
+
*
|
|
34
|
+
* ```typescript
|
|
35
|
+
* import {SocketService, SocketUseAfter, SocketUseBefore, Emit, Input, Args} from "@tsed/socketio";
|
|
36
|
+
* import {UserConverterSocketMiddleware} from "../middlewares.js";
|
|
37
|
+
* import {User} from "../models/User.js";
|
|
38
|
+
*
|
|
39
|
+
* @SocketService("/my-namespace")
|
|
40
|
+
* @SocketUseBefore(UserConverterSocketMiddleware) // global version
|
|
41
|
+
* export class MySocketService {
|
|
42
|
+
*
|
|
43
|
+
* @Input("eventName")
|
|
44
|
+
* @Emit("responseEventName") // or Broadcast or BroadcastOthers
|
|
45
|
+
* @SocketUseBefore(UserConverterSocketMiddleware)
|
|
46
|
+
* async myMethod(@Args(0) user: User) {
|
|
47
|
+
*
|
|
48
|
+
* console.log(user);
|
|
49
|
+
*
|
|
50
|
+
* return user;
|
|
51
|
+
* }
|
|
52
|
+
* }
|
|
53
|
+
* ```
|
|
54
|
+
*
|
|
55
|
+
* @returns {Function}
|
|
56
|
+
* @decorator
|
|
57
|
+
* @experimental
|
|
58
|
+
*/
|
|
59
|
+
export function SocketMiddleware(): Function {
|
|
60
|
+
return (target: Type<any>) => {
|
|
61
|
+
Store.from(target).merge("socketIO", {
|
|
62
|
+
type: SocketProviderTypes.MIDDLEWARE,
|
|
63
|
+
handlers: {
|
|
64
|
+
use: {
|
|
65
|
+
methodClassName: "use"
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
return Middleware()(target);
|
|
71
|
+
};
|
|
72
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import {Store} from "@tsed/core";
|
|
2
|
+
|
|
3
|
+
import {SocketMiddlewareError, SocketProviderTypes} from "../index.js";
|
|
4
|
+
|
|
5
|
+
describe("@SocketMiddlewareError", () => {
|
|
6
|
+
it("should register the metadata and middleware", () => {
|
|
7
|
+
@SocketMiddlewareError()
|
|
8
|
+
class Test {
|
|
9
|
+
use() {}
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
expect(Store.from(Test).get("socketIO")).toEqual({
|
|
13
|
+
type: SocketProviderTypes.MIDDLEWARE,
|
|
14
|
+
error: true,
|
|
15
|
+
handlers: {
|
|
16
|
+
use: {
|
|
17
|
+
methodClassName: "use"
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
});
|
|
21
|
+
});
|
|
22
|
+
});
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import {Store, Type} from "@tsed/core";
|
|
2
|
+
import {Middleware} from "@tsed/platform-middlewares";
|
|
3
|
+
|
|
4
|
+
import {SocketProviderTypes} from "../interfaces/SocketProviderTypes.js";
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Declare a new SocketMiddlewareError.
|
|
8
|
+
*
|
|
9
|
+
* ### Example
|
|
10
|
+
*
|
|
11
|
+
* A middleware can be also used on a `SocketService` either on a class or on a method.
|
|
12
|
+
*
|
|
13
|
+
* Here an example of a middleware:
|
|
14
|
+
*
|
|
15
|
+
* ```typescript
|
|
16
|
+
* import {SocketMiddlewareError, SocketErr, Socket, Args} from "@tsed/socketio";
|
|
17
|
+
*
|
|
18
|
+
* @SocketMiddlewareError()
|
|
19
|
+
* export class ErrorHandlerSocketMiddleware {
|
|
20
|
+
* async use(@SocketEventName, @SocketErr err: any, @Socket socket: SocketIO.Socket) {
|
|
21
|
+
* console.error(err);
|
|
22
|
+
* socket.emit("error", {message: "An error has occured"})
|
|
23
|
+
* }
|
|
24
|
+
* }
|
|
25
|
+
* ```
|
|
26
|
+
*
|
|
27
|
+
* Then:
|
|
28
|
+
*
|
|
29
|
+
* ```typescript
|
|
30
|
+
* import {SocketService, SocketUseAfter, SocketUseBefore, Emit, Input, Args} from "@tsed/socketio";
|
|
31
|
+
* import {ErrorHandlerSocketMiddleware} from "../middlewares.js";
|
|
32
|
+
* import {User} from "../models/User.js";
|
|
33
|
+
*
|
|
34
|
+
* @SocketService("/my-namespace")
|
|
35
|
+
* @SocketUseAfter(ErrorHandlerSocketMiddleware) // global version
|
|
36
|
+
* export class MySocketService {
|
|
37
|
+
*
|
|
38
|
+
* @Input("eventName")
|
|
39
|
+
* @Emit("responseEventName") // or Broadcast or BroadcastOthers
|
|
40
|
+
* @SocketUseAfter(ErrorHandlerSocketMiddleware)
|
|
41
|
+
* async myMethod(@Args(0) userName: User) {
|
|
42
|
+
*
|
|
43
|
+
* console.log(user);
|
|
44
|
+
* throw new Error("Error");
|
|
45
|
+
*
|
|
46
|
+
* return user;
|
|
47
|
+
* }
|
|
48
|
+
* }
|
|
49
|
+
* ```
|
|
50
|
+
*
|
|
51
|
+
* @returns {Function}
|
|
52
|
+
* @decorator
|
|
53
|
+
* @experimental
|
|
54
|
+
*/
|
|
55
|
+
export function SocketMiddlewareError(): Function {
|
|
56
|
+
return (target: Type<any>) => {
|
|
57
|
+
Store.from(target).merge("socketIO", {
|
|
58
|
+
type: SocketProviderTypes.MIDDLEWARE,
|
|
59
|
+
error: true,
|
|
60
|
+
|
|
61
|
+
handlers: {
|
|
62
|
+
use: {
|
|
63
|
+
methodClassName: "use"
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
return Middleware()(target);
|
|
69
|
+
};
|
|
70
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import {Store} from "@tsed/core";
|
|
2
|
+
|
|
3
|
+
import {SocketNsp} from "../index.js";
|
|
4
|
+
|
|
5
|
+
describe("SocketNsp", () => {
|
|
6
|
+
it("should set metadata", () => {
|
|
7
|
+
class Test {}
|
|
8
|
+
|
|
9
|
+
SocketNsp(Test, "test", 0);
|
|
10
|
+
|
|
11
|
+
const store = Store.from(Test);
|
|
12
|
+
|
|
13
|
+
expect(store.get("socketIO")).toEqual({
|
|
14
|
+
handlers: {
|
|
15
|
+
test: {
|
|
16
|
+
parameters: {
|
|
17
|
+
"0": {
|
|
18
|
+
filter: "socket_nsp",
|
|
19
|
+
mapIndex: undefined
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
});
|
|
25
|
+
});
|
|
26
|
+
});
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import {SocketFilters} from "../interfaces/SocketFilters.js";
|
|
2
|
+
import {Namespace} from "./nsp.js";
|
|
3
|
+
import {SocketFilter} from "./socketFilter.js";
|
|
4
|
+
|
|
5
|
+
export type SocketNsp = Namespace;
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Inject the [SocketIO.Namespace](https://socket.io/docs/rooms-and-namespaces/#namespaces) instance in the decorated parameter.
|
|
9
|
+
* This namespace may differ from the default namespace when using dynamic namespaces.
|
|
10
|
+
*
|
|
11
|
+
* ### Example
|
|
12
|
+
*
|
|
13
|
+
* ```typescript
|
|
14
|
+
* @SocketService(/nsp-.+/)
|
|
15
|
+
* export class MyWS {
|
|
16
|
+
*
|
|
17
|
+
* @Input("event")
|
|
18
|
+
* myMethod(@SocketNsp nsp: SocketNsp) {
|
|
19
|
+
*
|
|
20
|
+
* }
|
|
21
|
+
* }
|
|
22
|
+
* ```
|
|
23
|
+
*
|
|
24
|
+
* @experimental
|
|
25
|
+
* @param target
|
|
26
|
+
* @param {string} propertyKey
|
|
27
|
+
* @param {number} index
|
|
28
|
+
* @decorator
|
|
29
|
+
*/
|
|
30
|
+
export function SocketNsp(target: any, propertyKey: string, index: number): any {
|
|
31
|
+
return SocketFilter(SocketFilters.SOCKET_NSP)(target, propertyKey, index);
|
|
32
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import {Store} from "@tsed/core";
|
|
2
|
+
|
|
3
|
+
import {SocketReturnsTypes} from "../interfaces/SocketReturnsTypes.js";
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
*
|
|
7
|
+
* @param {string} eventName
|
|
8
|
+
* @param {SocketReturnsTypes} type
|
|
9
|
+
* @returns {(target: any, propertyKey: string, descriptor: PropertyDescriptor) => void}
|
|
10
|
+
* @decorator
|
|
11
|
+
*/
|
|
12
|
+
export function SocketReturns(eventName: string, type: SocketReturnsTypes) {
|
|
13
|
+
return (target: any, propertyKey: string, descriptor: PropertyDescriptor) => {
|
|
14
|
+
Store.from(target).merge("socketIO", {
|
|
15
|
+
handlers: {
|
|
16
|
+
[propertyKey]: {
|
|
17
|
+
returns: {
|
|
18
|
+
eventName,
|
|
19
|
+
type
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
});
|
|
24
|
+
};
|
|
25
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import {Store} from "@tsed/core";
|
|
2
|
+
|
|
3
|
+
import {SocketService} from "./socketService.js";
|
|
4
|
+
|
|
5
|
+
describe("SocketService", () => {
|
|
6
|
+
describe("case 1", () => {
|
|
7
|
+
class Test {}
|
|
8
|
+
it("should set metadata", () => {
|
|
9
|
+
SocketService("/namespace")(Test);
|
|
10
|
+
const store = Store.from(Test);
|
|
11
|
+
|
|
12
|
+
expect(store.get("socketIO")).toEqual({
|
|
13
|
+
namespace: "/namespace",
|
|
14
|
+
type: "service"
|
|
15
|
+
});
|
|
16
|
+
});
|
|
17
|
+
});
|
|
18
|
+
describe("case 2", () => {
|
|
19
|
+
class Test {}
|
|
20
|
+
it("should set metadata", () => {
|
|
21
|
+
SocketService()(Test);
|
|
22
|
+
const store = Store.from(Test);
|
|
23
|
+
|
|
24
|
+
expect(store.get("socketIO")).toEqual({
|
|
25
|
+
namespace: "/",
|
|
26
|
+
type: "service"
|
|
27
|
+
});
|
|
28
|
+
});
|
|
29
|
+
});
|
|
30
|
+
describe("case 3", () => {
|
|
31
|
+
class Test {}
|
|
32
|
+
it("should set metadata", () => {
|
|
33
|
+
const regexp = new RegExp(/test/);
|
|
34
|
+
|
|
35
|
+
SocketService(regexp)(Test);
|
|
36
|
+
const store = Store.from(Test);
|
|
37
|
+
|
|
38
|
+
expect(store.get("socketIO")).toEqual({
|
|
39
|
+
namespace: regexp,
|
|
40
|
+
type: "service"
|
|
41
|
+
});
|
|
42
|
+
});
|
|
43
|
+
});
|
|
44
|
+
});
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import {StoreMerge, useDecorators} from "@tsed/core";
|
|
2
|
+
import {Injectable} from "@tsed/di";
|
|
3
|
+
|
|
4
|
+
import {PROVIDER_TYPE_SOCKET_SERVICE} from "../constants/constants.js";
|
|
5
|
+
import {SocketProviderTypes} from "../interfaces/SocketProviderTypes.js";
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* The decorators `@SocketService()` declare a new socket service (and service) can be injected in other service or controller on there `constructor`.
|
|
9
|
+
* All services annotated with `@SocketService()` are constructed one time.
|
|
10
|
+
*
|
|
11
|
+
* > `@SocketService()` use the `reflect-metadata` to collect and inject service on controllers or other services.
|
|
12
|
+
*
|
|
13
|
+
* @param namespace
|
|
14
|
+
* @returns {Function}
|
|
15
|
+
* @decorator
|
|
16
|
+
*/
|
|
17
|
+
export function SocketService(namespace: string | RegExp = "/") {
|
|
18
|
+
return useDecorators(
|
|
19
|
+
StoreMerge("socketIO", {namespace, type: SocketProviderTypes.SERVICE}),
|
|
20
|
+
Injectable({
|
|
21
|
+
type: PROVIDER_TYPE_SOCKET_SERVICE
|
|
22
|
+
})
|
|
23
|
+
);
|
|
24
|
+
}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import {Store} from "@tsed/core";
|
|
2
|
+
|
|
3
|
+
import {RawSocketSession, SocketFilters, SocketSession} from "../index.js";
|
|
4
|
+
|
|
5
|
+
describe("SocketSession", () => {
|
|
6
|
+
it("should set metadata", () => {
|
|
7
|
+
class Test {}
|
|
8
|
+
|
|
9
|
+
SocketSession(Test, "test", 0);
|
|
10
|
+
const store = Store.from(Test);
|
|
11
|
+
|
|
12
|
+
expect(store.get("socketIO")).toEqual({
|
|
13
|
+
handlers: {
|
|
14
|
+
test: {
|
|
15
|
+
parameters: {
|
|
16
|
+
"0": {
|
|
17
|
+
filter: SocketFilters.SESSION,
|
|
18
|
+
mapIndex: undefined
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
});
|
|
24
|
+
});
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
describe("RawSocketSession", () => {
|
|
28
|
+
it("should set metadata", () => {
|
|
29
|
+
class Test {}
|
|
30
|
+
|
|
31
|
+
RawSocketSession(Test, "test", 0);
|
|
32
|
+
const store = Store.from(Test);
|
|
33
|
+
|
|
34
|
+
expect(store.get("socketIO")).toEqual({
|
|
35
|
+
handlers: {
|
|
36
|
+
test: {
|
|
37
|
+
parameters: {
|
|
38
|
+
"0": {
|
|
39
|
+
filter: SocketFilters.RAW_SESSION,
|
|
40
|
+
mapIndex: undefined
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
});
|
|
46
|
+
});
|
|
47
|
+
});
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import {SocketFilters} from "../interfaces/SocketFilters.js";
|
|
2
|
+
import {SocketFilter} from "./socketFilter.js";
|
|
3
|
+
|
|
4
|
+
export type SocketSession = Map<string, any>;
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Inject the socket session data in the decorated parameter.
|
|
8
|
+
*
|
|
9
|
+
* ### Example
|
|
10
|
+
*
|
|
11
|
+
* ```typescript
|
|
12
|
+
* @SocketService("/nsp")
|
|
13
|
+
* export class MyWS {
|
|
14
|
+
*
|
|
15
|
+
* @Input("event")
|
|
16
|
+
* myMethod(@SocketSession session: SocketSession) {
|
|
17
|
+
* console.log(session);
|
|
18
|
+
* }
|
|
19
|
+
* }
|
|
20
|
+
* ```
|
|
21
|
+
*
|
|
22
|
+
* @param target
|
|
23
|
+
* @param {string} propertyKey
|
|
24
|
+
* @param {number} index
|
|
25
|
+
* @decorator
|
|
26
|
+
*/
|
|
27
|
+
export function SocketSession(target: any, propertyKey: string, index: number) {
|
|
28
|
+
return SocketFilter(SocketFilters.SESSION)(target, propertyKey, index);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Inject the raw `socket.data` in the decorated parameter.
|
|
33
|
+
*
|
|
34
|
+
* @example
|
|
35
|
+
* ```typescript
|
|
36
|
+
* @SocketService("/nsp")
|
|
37
|
+
* export class MyWS {
|
|
38
|
+
*
|
|
39
|
+
* @Input("event")
|
|
40
|
+
* myMethod(@RawSocketSession session: Record<string, unknown>) {
|
|
41
|
+
* console.log(session);
|
|
42
|
+
* }
|
|
43
|
+
* }
|
|
44
|
+
* ```
|
|
45
|
+
*
|
|
46
|
+
* @param target
|
|
47
|
+
* @param {string} propertyKey
|
|
48
|
+
* @param {number} index
|
|
49
|
+
* @constructor
|
|
50
|
+
*/
|
|
51
|
+
export function RawSocketSession(target: any, propertyKey: string, index: number) {
|
|
52
|
+
return SocketFilter(SocketFilters.RAW_SESSION)(target, propertyKey, index);
|
|
53
|
+
}
|