@eleven-am/pondsocket 0.1.11 → 0.1.13
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/client/channel.js +200 -0
- package/dist/client/index.d.ts +122 -0
- package/{pondClient/socket.js → dist/client/index.js} +30 -44
- package/dist/express/index.d.ts +36 -0
- package/dist/express/index.js +16 -0
- package/dist/index.d.ts +340 -0
- package/dist/index.js +4 -0
- package/dist/server/abstracts/abstractRequest.js +40 -0
- package/dist/server/abstracts/abstractRequest.test.js +41 -0
- package/dist/server/abstracts/abstractResponse.js +6 -0
- package/dist/server/abstracts/middleware.js +38 -0
- package/dist/server/abstracts/middleware.test.js +70 -0
- package/dist/server/channel/channelEngine.js +279 -0
- package/dist/server/channel/channelEngine.test.js +377 -0
- package/dist/server/channel/channelRequest.test.js +29 -0
- package/dist/server/channel/channelResponse.test.js +134 -0
- package/dist/server/channel/eventRequest.js +18 -0
- package/dist/server/channel/eventResponse.js +141 -0
- package/dist/server/endpoint/connectionResponse.js +50 -0
- package/dist/server/endpoint/endpoint.js +269 -0
- package/dist/server/endpoint/endpoint.test.js +406 -0
- package/dist/server/endpoint/endpointResponse.test.js +43 -0
- package/dist/server/pondChannel/joinRequest.js +29 -0
- package/dist/server/pondChannel/joinResponse.js +96 -0
- package/dist/server/pondChannel/pondChannel.js +161 -0
- package/dist/server/pondChannel/pondChannelResponse.test.js +108 -0
- package/dist/server/presence/presenceEngine.js +112 -0
- package/dist/server/presence/presenceEngine.test.js +104 -0
- package/dist/server/server/pondSocket.js +122 -0
- package/{pondSocket → dist/server/server}/server.test.js +7 -21
- package/{pondBase/baseClass.js → dist/server/utils/matchPattern.js} +33 -43
- package/{pondBase/baseClass.test.js → dist/server/utils/matchPattern.test.js} +16 -25
- package/dist/server/utils/subjectUtils.js +68 -0
- package/package.json +31 -12
- package/.eslintrc.js +0 -28
- package/base.d.ts +0 -1
- package/base.js +0 -17
- package/client.d.ts +0 -1
- package/client.js +0 -17
- package/index.d.ts +0 -1
- package/index.js +0 -17
- package/jest.config.js +0 -11
- package/pondBase/baseClass.d.ts +0 -55
- package/pondBase/enums.d.ts +0 -9
- package/pondBase/enums.js +0 -14
- package/pondBase/index.d.ts +0 -6
- package/pondBase/index.js +0 -22
- package/pondBase/pondBase.d.ts +0 -41
- package/pondBase/pondBase.js +0 -60
- package/pondBase/pondBase.test.js +0 -101
- package/pondBase/pubSub.d.ts +0 -82
- package/pondBase/pubSub.js +0 -158
- package/pondBase/pubSub.test.js +0 -332
- package/pondBase/simpleBase.d.ts +0 -126
- package/pondBase/simpleBase.js +0 -211
- package/pondBase/simpleBase.test.js +0 -153
- package/pondBase/types.d.ts +0 -2
- package/pondBase/types.js +0 -2
- package/pondClient/channel.d.ts +0 -77
- package/pondClient/channel.js +0 -167
- package/pondClient/index.d.ts +0 -2
- package/pondClient/index.js +0 -18
- package/pondClient/socket.d.ts +0 -41
- package/pondSocket/channel.d.ts +0 -129
- package/pondSocket/channel.js +0 -287
- package/pondSocket/channel.test.js +0 -377
- package/pondSocket/channelMiddleWare.d.ts +0 -28
- package/pondSocket/channelMiddleWare.js +0 -36
- package/pondSocket/endpoint.d.ts +0 -90
- package/pondSocket/endpoint.js +0 -320
- package/pondSocket/endpoint.test.js +0 -490
- package/pondSocket/enums.d.ts +0 -19
- package/pondSocket/enums.js +0 -25
- package/pondSocket/index.d.ts +0 -7
- package/pondSocket/index.js +0 -23
- package/pondSocket/pondChannel.d.ts +0 -79
- package/pondSocket/pondChannel.js +0 -211
- package/pondSocket/pondChannel.test.js +0 -430
- package/pondSocket/pondResponse.d.ts +0 -25
- package/pondSocket/pondResponse.js +0 -120
- package/pondSocket/pondSocket.d.ts +0 -47
- package/pondSocket/pondSocket.js +0 -94
- package/pondSocket/socketMiddleWare.d.ts +0 -6
- package/pondSocket/socketMiddleWare.js +0 -32
- package/pondSocket/types.d.ts +0 -74
- package/pondSocket/types.js +0 -2
- package/socket.d.ts +0 -1
- package/socket.js +0 -17
- package/tsconfig.eslint.json +0 -5
- package/tsconfig.json +0 -90
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,340 @@
|
|
|
1
|
+
import { Server as HTTPServer, IncomingMessage, IncomingHttpHeaders } from 'http';
|
|
2
|
+
import internal from 'stream';
|
|
3
|
+
|
|
4
|
+
// eslint-disable-next-line import/no-unresolved
|
|
5
|
+
import { Express } from 'express';
|
|
6
|
+
import { WebSocketServer, WebSocket } from 'ws';
|
|
7
|
+
|
|
8
|
+
export type PondPath = string | RegExp;
|
|
9
|
+
type NextFunction = () => void;
|
|
10
|
+
export type JoinParams = Record<string, any>;
|
|
11
|
+
type PondAssigns = Record<string, any>;
|
|
12
|
+
export type PondMessage = Record<string, any>;
|
|
13
|
+
export type PondPresence = Record<string, any>;
|
|
14
|
+
export type EndpointHandler = (req: IncomingConnection, res: ConnectionResponse) => void;
|
|
15
|
+
type SocketCache = Pick<RequestCache, 'socket' | 'clientId' | 'assigns'>;
|
|
16
|
+
type AuthorizeMiddleware = (request: JoinRequest, response: JoinResponse) => void | Promise<void>;
|
|
17
|
+
type SocketMiddlewareFunction = (req: IncomingMessage, socket: internal.Duplex, head: Buffer, next: NextFunction) => void;
|
|
18
|
+
|
|
19
|
+
interface RequestCache {
|
|
20
|
+
clientId: string;
|
|
21
|
+
socket: WebSocket;
|
|
22
|
+
channelName: string;
|
|
23
|
+
assigns: PondAssigns;
|
|
24
|
+
joinParams: Record<string, any>;
|
|
25
|
+
params: Record<string, string>;
|
|
26
|
+
query: Record<string, string>;
|
|
27
|
+
}
|
|
28
|
+
interface UserAssigns {
|
|
29
|
+
[userId: string]: PondAssigns;
|
|
30
|
+
}
|
|
31
|
+
interface UserData {
|
|
32
|
+
assigns: PondAssigns;
|
|
33
|
+
presence: PondPresence;
|
|
34
|
+
id: string;
|
|
35
|
+
}
|
|
36
|
+
interface EventObject {
|
|
37
|
+
event: string;
|
|
38
|
+
params: Record<string, string>;
|
|
39
|
+
query: Record<string, string>;
|
|
40
|
+
payload: PondMessage;
|
|
41
|
+
}
|
|
42
|
+
interface IncomingConnection {
|
|
43
|
+
id: string;
|
|
44
|
+
params: Record<string, string>;
|
|
45
|
+
query: Record<string, string>;
|
|
46
|
+
headers: IncomingHttpHeaders;
|
|
47
|
+
address: string;
|
|
48
|
+
}
|
|
49
|
+
interface UserPresences {
|
|
50
|
+
[userId: string]: PondPresence;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
declare class AbstractRequest {
|
|
54
|
+
get event (): EventObject;
|
|
55
|
+
|
|
56
|
+
get channelNme (): string;
|
|
57
|
+
|
|
58
|
+
get assigns (): UserAssigns;
|
|
59
|
+
|
|
60
|
+
get presence (): UserPresences;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
declare class EventRequest extends AbstractRequest {
|
|
64
|
+
get user (): UserData;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
declare class EventResponse {
|
|
68
|
+
/**
|
|
69
|
+
* @desc Checks if the response has been sent
|
|
70
|
+
*/
|
|
71
|
+
get responseSent (): boolean;
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* @desc Accepts the request and optionally assigns data to the client
|
|
75
|
+
* @param assigns - the data to assign to the client
|
|
76
|
+
*/
|
|
77
|
+
accept (assigns?: PondAssigns): EventResponse;
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* @desc Rejects the request and optionally assigns data to the client
|
|
81
|
+
* @param message - the error message
|
|
82
|
+
* @param errorCode - the error code
|
|
83
|
+
* @param assigns - the data to assign to the client
|
|
84
|
+
*/
|
|
85
|
+
reject (message?: string, errorCode?: number, assigns?: PondAssigns): EventResponse;
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* @desc Emits a direct message to the client
|
|
89
|
+
* @param event - the event name
|
|
90
|
+
* @param payload - the payload to send
|
|
91
|
+
* @param assigns - the data to assign to the client
|
|
92
|
+
*/
|
|
93
|
+
send (event: string, payload: PondMessage, assigns?: PondAssigns): EventResponse;
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* @desc Sends a message to all clients in the channel
|
|
97
|
+
* @param event - the event to send
|
|
98
|
+
* @param payload - the payload to send
|
|
99
|
+
*/
|
|
100
|
+
broadcast (event: string, payload: PondMessage): EventResponse;
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* @desc Sends a message to all clients in the channel except the client making the request
|
|
104
|
+
* @param event - the event to send
|
|
105
|
+
* @param payload - the payload to send
|
|
106
|
+
*/
|
|
107
|
+
broadcastFromUser (event: string, payload: PondMessage): EventResponse;
|
|
108
|
+
|
|
109
|
+
/**
|
|
110
|
+
* @desc Sends a message to a set of clients in the channel
|
|
111
|
+
* @param event - the event to send
|
|
112
|
+
* @param payload - the payload to send
|
|
113
|
+
* @param userIds - the ids of the clients to send the message to
|
|
114
|
+
*/
|
|
115
|
+
sendToUsers (event: string, payload: PondMessage, userIds: string[]): EventResponse;
|
|
116
|
+
|
|
117
|
+
/**
|
|
118
|
+
* @desc Tracks a user's presence in the channel
|
|
119
|
+
* @param presence - the initial presence data
|
|
120
|
+
* @param userId - the id of the user to track
|
|
121
|
+
*/
|
|
122
|
+
trackPresence (presence: PondPresence, userId?: string): EventResponse;
|
|
123
|
+
|
|
124
|
+
/**
|
|
125
|
+
* @desc Updates a user's presence in the channel
|
|
126
|
+
* @param presence - the updated presence data
|
|
127
|
+
* @param userId - the id of the user to update
|
|
128
|
+
*/
|
|
129
|
+
updatePresence (presence: PondPresence, userId?: string): EventResponse;
|
|
130
|
+
|
|
131
|
+
/**
|
|
132
|
+
* @desc Removes a user's presence from the channel
|
|
133
|
+
* @param userId - the id of the user to remove
|
|
134
|
+
*/
|
|
135
|
+
unTrackPresence (userId?: string): EventResponse;
|
|
136
|
+
|
|
137
|
+
/**
|
|
138
|
+
* @desc Evicts a user from the channel
|
|
139
|
+
* @param reason - the reason for the eviction
|
|
140
|
+
* @param userId - the id of the user to evict,
|
|
141
|
+
*/
|
|
142
|
+
evictUser (reason: string, userId?: string): void;
|
|
143
|
+
|
|
144
|
+
/**
|
|
145
|
+
* @desc Closes the channel from the server side for all clients
|
|
146
|
+
* @param reason - the reason for closing the channel
|
|
147
|
+
*/
|
|
148
|
+
closeChannel (reason: string): void;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
declare class JoinRequest extends AbstractRequest {
|
|
152
|
+
get joinParams (): JoinParams;
|
|
153
|
+
|
|
154
|
+
get user (): UserData;
|
|
155
|
+
|
|
156
|
+
get event (): EventObject;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
declare class JoinResponse {
|
|
160
|
+
get responseSent (): boolean;
|
|
161
|
+
|
|
162
|
+
/**
|
|
163
|
+
* @desc Accepts the request and optionally assigns data to the client
|
|
164
|
+
* @param assigns - the data to assign to the client
|
|
165
|
+
*/
|
|
166
|
+
accept (assigns?: PondAssigns): JoinResponse;
|
|
167
|
+
|
|
168
|
+
/**
|
|
169
|
+
* @desc Rejects the request and optionally assigns data to the client
|
|
170
|
+
* @param message - the error message
|
|
171
|
+
* @param errorCode - the error code
|
|
172
|
+
*/
|
|
173
|
+
reject (message?: string, errorCode?: number): JoinResponse;
|
|
174
|
+
|
|
175
|
+
/**
|
|
176
|
+
* @desc Emits a direct message to the client
|
|
177
|
+
* @param event - the event name
|
|
178
|
+
* @param payload - the payload to send
|
|
179
|
+
* @param assigns - the data to assign to the client
|
|
180
|
+
*/
|
|
181
|
+
send (event: string, payload: PondMessage, assigns?: PondAssigns): this;
|
|
182
|
+
|
|
183
|
+
/**
|
|
184
|
+
* @desc Emits a message to all clients in the channel
|
|
185
|
+
* @param event - the event name
|
|
186
|
+
* @param payload - the payload to send
|
|
187
|
+
*/
|
|
188
|
+
broadcast (event: string, payload: PondMessage): JoinResponse;
|
|
189
|
+
|
|
190
|
+
/**
|
|
191
|
+
* @desc Emits a message to all clients in the channel except the sender
|
|
192
|
+
* @param event - the event name
|
|
193
|
+
* @param payload - the payload to send
|
|
194
|
+
*/
|
|
195
|
+
broadcastFromUser (event: string, payload: PondMessage): JoinResponse;
|
|
196
|
+
|
|
197
|
+
/**
|
|
198
|
+
* @desc Emits a message to a specific set of clients
|
|
199
|
+
* @param event - the event name
|
|
200
|
+
* @param payload - the payload to send
|
|
201
|
+
* @param userIds - the ids of the clients to send the message to
|
|
202
|
+
*/
|
|
203
|
+
sendToUsers (event: string, payload: PondMessage, userIds: string[]): JoinResponse;
|
|
204
|
+
|
|
205
|
+
/**
|
|
206
|
+
* @desc tracks the presence of a client
|
|
207
|
+
* @param presence - the presence data to track
|
|
208
|
+
*/
|
|
209
|
+
trackPresence (presence: PondPresence): JoinResponse;
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
declare class PondChannel {
|
|
213
|
+
/**
|
|
214
|
+
* @desc Authorize a user to join a channel
|
|
215
|
+
* @param handler - The handler to authorize the user
|
|
216
|
+
* @example
|
|
217
|
+
* const pond = new PondChannelEngine();
|
|
218
|
+
* pond.onJoinRequest((request, response) => {
|
|
219
|
+
* if (request.event.assigns.admin)
|
|
220
|
+
* response.accept();
|
|
221
|
+
* else
|
|
222
|
+
* response.reject('You are not an admin', 403);
|
|
223
|
+
* });
|
|
224
|
+
*/
|
|
225
|
+
onJoinRequest (handler: AuthorizeMiddleware): void;
|
|
226
|
+
|
|
227
|
+
/**
|
|
228
|
+
* @desc Handles an event request made by a user
|
|
229
|
+
* @param event - The event to listen for
|
|
230
|
+
* @param handler - The handler to execute when the event is received
|
|
231
|
+
* @example
|
|
232
|
+
* pond.onEvent('echo', (request, response) => {
|
|
233
|
+
* response.send('echo', {
|
|
234
|
+
* message: request.payload,
|
|
235
|
+
* });
|
|
236
|
+
* });
|
|
237
|
+
*/
|
|
238
|
+
onEvent (event: PondPath, handler: (request: EventRequest, response: EventResponse) => void | Promise<void>): void;
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
declare class ConnectionResponse {
|
|
242
|
+
/**
|
|
243
|
+
* @desc Accepts the request and optionally assigns data to the client
|
|
244
|
+
* @param assigns - the data to assign to the client
|
|
245
|
+
*/
|
|
246
|
+
accept (assigns?: PondAssigns): void;
|
|
247
|
+
|
|
248
|
+
/**
|
|
249
|
+
* @desc Rejects the request with the given error message
|
|
250
|
+
* @param message - the error message
|
|
251
|
+
* @param errorCode - the error code
|
|
252
|
+
*/
|
|
253
|
+
reject (message?: string, errorCode?: number): void;
|
|
254
|
+
|
|
255
|
+
/**
|
|
256
|
+
* @desc Emits a direct message to the client
|
|
257
|
+
* @param event - the event name
|
|
258
|
+
* @param payload - the payload to send
|
|
259
|
+
* @param assigns - the data to assign to the client
|
|
260
|
+
*/
|
|
261
|
+
send (event: string, payload: PondMessage, assigns?: PondAssigns): void;
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
export declare class Endpoint {
|
|
265
|
+
/**
|
|
266
|
+
* @desc Adds a new PondChannel to this path on this endpoint
|
|
267
|
+
* @param path - The path to add the channel to
|
|
268
|
+
* @param channel - The channel to add
|
|
269
|
+
*
|
|
270
|
+
* @example
|
|
271
|
+
* endpoint.useChannel('/chat', pondChannelInstance);
|
|
272
|
+
*/
|
|
273
|
+
useChannel (path: PondPath, channel: PondChannel): void;
|
|
274
|
+
|
|
275
|
+
/**
|
|
276
|
+
* @desc List all clients connected to this endpoint
|
|
277
|
+
*/
|
|
278
|
+
listConnections (): string[];
|
|
279
|
+
|
|
280
|
+
/**
|
|
281
|
+
* @desc Gets all clients connected to this endpoint
|
|
282
|
+
*/
|
|
283
|
+
getClients (): SocketCache[];
|
|
284
|
+
|
|
285
|
+
/**
|
|
286
|
+
* @desc Broadcasts a message to all clients connected to this endpoint
|
|
287
|
+
* @param event - The event to broadcast
|
|
288
|
+
* @param payload - The payload to broadcast
|
|
289
|
+
*/
|
|
290
|
+
broadcast (event: string, payload: PondMessage): void;
|
|
291
|
+
|
|
292
|
+
/**
|
|
293
|
+
* @desc Closes specific clients connected to this endpoint
|
|
294
|
+
* @param clientIds - The id for the client / clients to close
|
|
295
|
+
*/
|
|
296
|
+
closeConnection (clientIds: string | string[]): void;
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
declare class PondSocket {
|
|
300
|
+
constructor (server?: HTTPServer, socketServer?: WebSocketServer);
|
|
301
|
+
|
|
302
|
+
/**
|
|
303
|
+
* @desc Specifies the port to listen on
|
|
304
|
+
* @param port - the port to listen on
|
|
305
|
+
* @param callback - the callback to call when the server is listening
|
|
306
|
+
*/
|
|
307
|
+
listen (port: number, callback: (port?: number) => void): HTTPServer<typeof IncomingMessage, typeof import('http').ServerResponse>;
|
|
308
|
+
|
|
309
|
+
/**
|
|
310
|
+
* @desc Closes the server
|
|
311
|
+
* @param callback - the callback to call when the server is closed
|
|
312
|
+
*/
|
|
313
|
+
close (callback?: () => void): HTTPServer<typeof IncomingMessage, typeof import('http').ServerResponse>;
|
|
314
|
+
|
|
315
|
+
/**
|
|
316
|
+
* @desc Accepts a new socket upgrade request on the provided endpoint using the handler function to authenticate the socket
|
|
317
|
+
* @param path - the pattern to accept || can also be a regex
|
|
318
|
+
* @param handler - the handler function to authenticate the socket
|
|
319
|
+
* @example
|
|
320
|
+
* const endpoint = pond.createEndpoint('/api/socket', (req, res) => {
|
|
321
|
+
* const token = req.query.token;
|
|
322
|
+
* if (!token)
|
|
323
|
+
* return res.reject('No token provided');
|
|
324
|
+
* res.accept({
|
|
325
|
+
* assign: {
|
|
326
|
+
* token
|
|
327
|
+
* }
|
|
328
|
+
* });
|
|
329
|
+
* })
|
|
330
|
+
*/
|
|
331
|
+
createEndpoint (path: PondPath, handler: EndpointHandler): Endpoint;
|
|
332
|
+
|
|
333
|
+
/**
|
|
334
|
+
* @desc Adds a middleware function to the socket server
|
|
335
|
+
* @param middleware - the middleware function to add
|
|
336
|
+
*/
|
|
337
|
+
use (middleware: SocketMiddlewareFunction): void;
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
export default PondSocket;
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.AbstractRequest = void 0;
|
|
4
|
+
const matchPattern_1 = require("../utils/matchPattern");
|
|
5
|
+
class AbstractRequest {
|
|
6
|
+
constructor(event, engine, payload) {
|
|
7
|
+
this._engine = engine;
|
|
8
|
+
this._event = event;
|
|
9
|
+
this._eventObject = null;
|
|
10
|
+
this._payload = payload;
|
|
11
|
+
}
|
|
12
|
+
get event() {
|
|
13
|
+
var _a, _b;
|
|
14
|
+
return {
|
|
15
|
+
event: this._event,
|
|
16
|
+
params: ((_a = this._eventObject) === null || _a === void 0 ? void 0 : _a.params) || {},
|
|
17
|
+
query: ((_b = this._eventObject) === null || _b === void 0 ? void 0 : _b.query) || {},
|
|
18
|
+
payload: this._payload,
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
get channelNme() {
|
|
22
|
+
return this._engine.name;
|
|
23
|
+
}
|
|
24
|
+
get assigns() {
|
|
25
|
+
return this._engine.getAssigns();
|
|
26
|
+
}
|
|
27
|
+
get presence() {
|
|
28
|
+
return this._engine.getPresence();
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* @desc Parses the event and returns true if the event matches the path
|
|
32
|
+
* @param path - the path to match
|
|
33
|
+
*/
|
|
34
|
+
_parseQueries(path) {
|
|
35
|
+
const match = new matchPattern_1.MatchPattern();
|
|
36
|
+
this._eventObject = match.parseEvent(path, this._event);
|
|
37
|
+
return this._eventObject !== null;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
exports.AbstractRequest = AbstractRequest;
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const abstractRequest_1 = require("./abstractRequest");
|
|
4
|
+
const createMockChannelEngine = () => ({
|
|
5
|
+
name: 'test',
|
|
6
|
+
getAssigns: () => ({}),
|
|
7
|
+
getPresence: () => ({}),
|
|
8
|
+
});
|
|
9
|
+
describe('AbstractRequest', () => {
|
|
10
|
+
it('should be able to be instantiated', () => {
|
|
11
|
+
const request = new abstractRequest_1.AbstractRequest('/test', createMockChannelEngine(), {});
|
|
12
|
+
expect(request).toBeTruthy();
|
|
13
|
+
expect(request.channelNme).toBe('test');
|
|
14
|
+
expect(request.assigns).toEqual({});
|
|
15
|
+
expect(request.presence).toEqual({});
|
|
16
|
+
});
|
|
17
|
+
it('should be able to parse queries', () => {
|
|
18
|
+
const request = new abstractRequest_1.AbstractRequest('/1234?choke=balls', createMockChannelEngine(), {});
|
|
19
|
+
expect(request.event).toEqual({
|
|
20
|
+
event: '/1234?choke=balls',
|
|
21
|
+
payload: {},
|
|
22
|
+
params: {},
|
|
23
|
+
query: {},
|
|
24
|
+
});
|
|
25
|
+
expect(request._parseQueries('/:id')).toBe(true);
|
|
26
|
+
expect(request.event).toEqual({
|
|
27
|
+
event: '/1234?choke=balls',
|
|
28
|
+
params: { id: '1234' },
|
|
29
|
+
query: { choke: 'balls' },
|
|
30
|
+
payload: {},
|
|
31
|
+
});
|
|
32
|
+
});
|
|
33
|
+
it('should be return the value of the payload', () => {
|
|
34
|
+
const request = new abstractRequest_1.AbstractRequest('/test', createMockChannelEngine(), { test: 'test' });
|
|
35
|
+
expect(request.event.payload).toEqual({ test: 'test' });
|
|
36
|
+
const request2 = new abstractRequest_1.AbstractRequest('/test', createMockChannelEngine(), { test: 'test',
|
|
37
|
+
test2: 'test2' });
|
|
38
|
+
expect(request2.event.payload).toEqual({ test: 'test',
|
|
39
|
+
test2: 'test2' });
|
|
40
|
+
});
|
|
41
|
+
});
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Middleware = void 0;
|
|
4
|
+
class Middleware {
|
|
5
|
+
constructor(second) {
|
|
6
|
+
this._stack = [];
|
|
7
|
+
if (second) {
|
|
8
|
+
this._stack.push(...second._stack);
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* @desc Adds a middleware function to the middleware stack
|
|
13
|
+
* @param middleware - the middleware function to add
|
|
14
|
+
*/
|
|
15
|
+
use(middleware) {
|
|
16
|
+
this._stack.push(middleware);
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* @desc Runs the middleware stack
|
|
20
|
+
* @param req - the request object
|
|
21
|
+
* @param res - the response object
|
|
22
|
+
* @param final - the final function to call
|
|
23
|
+
*/
|
|
24
|
+
run(req, res, final) {
|
|
25
|
+
const temp = this._stack.concat();
|
|
26
|
+
const nextFunction = () => {
|
|
27
|
+
const middleware = temp.shift();
|
|
28
|
+
if (middleware && !res.responseSent) {
|
|
29
|
+
void middleware(req, res, nextFunction);
|
|
30
|
+
}
|
|
31
|
+
else if (!res.responseSent) {
|
|
32
|
+
final();
|
|
33
|
+
}
|
|
34
|
+
};
|
|
35
|
+
nextFunction();
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
exports.Middleware = Middleware;
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
const middleware_1 = require("./middleware");
|
|
13
|
+
describe('Middleware', () => {
|
|
14
|
+
it('should be able to add middleware to the stack', () => {
|
|
15
|
+
const middleware = new middleware_1.Middleware();
|
|
16
|
+
middleware.use(() => { });
|
|
17
|
+
expect(middleware['_stack'].length).toBe(1);
|
|
18
|
+
});
|
|
19
|
+
it('should be able to run middleware', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
20
|
+
const middleware = new middleware_1.Middleware();
|
|
21
|
+
const mock = jest.fn();
|
|
22
|
+
middleware.use(mock);
|
|
23
|
+
yield middleware.run({}, {}, () => { });
|
|
24
|
+
expect(mock).toHaveBeenCalled();
|
|
25
|
+
}));
|
|
26
|
+
it('should be able to run multiple middleware', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
27
|
+
const middleware = new middleware_1.Middleware();
|
|
28
|
+
const mock = jest.fn();
|
|
29
|
+
middleware.use((_, __, next) => {
|
|
30
|
+
mock('first');
|
|
31
|
+
next();
|
|
32
|
+
});
|
|
33
|
+
middleware.use((_, __, next) => {
|
|
34
|
+
mock('second');
|
|
35
|
+
next();
|
|
36
|
+
});
|
|
37
|
+
yield middleware.run({}, {}, () => { });
|
|
38
|
+
expect(mock).toHaveBeenCalledTimes(2);
|
|
39
|
+
expect(mock.mock.calls[0][2]).toBe(mock.mock.calls[1][2]);
|
|
40
|
+
}));
|
|
41
|
+
it('should be merge middleware in the correct order', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
42
|
+
const middleware = new middleware_1.Middleware();
|
|
43
|
+
const mock = jest.fn();
|
|
44
|
+
middleware.use(mock);
|
|
45
|
+
middleware.use(mock);
|
|
46
|
+
const middleware2 = new middleware_1.Middleware(middleware);
|
|
47
|
+
expect(middleware2['_stack'].length).toBe(2);
|
|
48
|
+
}));
|
|
49
|
+
it('should call the final function when the middleware stack is empty', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
50
|
+
const middleware = new middleware_1.Middleware();
|
|
51
|
+
const mock = jest.fn();
|
|
52
|
+
yield middleware.run({}, {}, mock);
|
|
53
|
+
expect(mock).toHaveBeenCalled();
|
|
54
|
+
}));
|
|
55
|
+
it('should be able to run middleware in the correct order when using a second middleware', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
56
|
+
const middleware = new middleware_1.Middleware();
|
|
57
|
+
const mock = jest.fn();
|
|
58
|
+
middleware.use((_, __, next) => {
|
|
59
|
+
mock('first');
|
|
60
|
+
next();
|
|
61
|
+
});
|
|
62
|
+
middleware.use((_, __, next) => {
|
|
63
|
+
mock('second');
|
|
64
|
+
next();
|
|
65
|
+
});
|
|
66
|
+
const middleware2 = new middleware_1.Middleware(middleware);
|
|
67
|
+
yield middleware2.run({}, {}, () => { });
|
|
68
|
+
expect(mock.mock.calls[0][2]).toBe(mock.mock.calls[1][2]);
|
|
69
|
+
}));
|
|
70
|
+
});
|