barehttp 0.6.0 → 2.0.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/lib/context/execution.js +3 -10
- package/lib/context/index.d.ts +2 -3
- package/lib/context/index.js +6 -14
- package/lib/env.js +1 -4
- package/lib/index.d.ts +5 -5
- package/lib/index.js +3 -9
- package/lib/logger/index.d.ts +3 -5
- package/lib/logger/index.js +16 -43
- package/lib/logger/serializers.d.ts +2 -3
- package/lib/logger/serializers.js +12 -22
- package/lib/middlewares/cookies/cookie-manager.d.ts +7 -6
- package/lib/middlewares/cookies/cookie-manager.js +14 -18
- package/lib/middlewares/cookies/signer.js +4 -11
- package/lib/middlewares/cors/cors.d.ts +3 -3
- package/lib/middlewares/cors/cors.js +1 -4
- package/lib/request.d.ts +7 -8
- package/lib/request.js +22 -29
- package/lib/schemas/custom-schema.d.ts +7 -7
- package/lib/schemas/custom-schema.js +13 -20
- package/lib/schemas/dirty-tsm.js +18 -20
- package/lib/schemas/generator.d.ts +3 -3
- package/lib/schemas/generator.js +25 -32
- package/lib/schemas/helpers.d.ts +1 -1
- package/lib/schemas/helpers.js +26 -36
- package/lib/schemas/json-schema.d.ts +1 -1
- package/lib/schemas/json-schema.js +4 -8
- package/lib/schemas/openami-schema.d.ts +2 -2
- package/lib/schemas/openami-schema.js +4 -8
- package/lib/schemas/project.d.ts +1 -0
- package/lib/schemas/project.js +1 -1
- package/lib/server.d.ts +17 -18
- package/lib/server.js +35 -42
- package/lib/utils/content-type.js +2 -5
- package/lib/utils/http-methods.d.ts +2 -2
- package/lib/utils/http-methods.js +1 -4
- package/lib/utils/index.d.ts +4 -4
- package/lib/utils/index.js +4 -12
- package/lib/utils/safe-json.js +2 -7
- package/lib/utils/status-codes.d.ts +1 -1
- package/lib/utils/status-codes.js +1 -4
- package/lib/utils/status-phrases.js +1 -4
- package/lib/websocket.d.ts +6 -7
- package/lib/websocket.js +24 -27
- package/package.json +48 -37
package/lib/server.js
CHANGED
|
@@ -1,21 +1,15 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
};
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
const cors_1 = require("./middlewares/cors/cors");
|
|
14
|
-
const websocket_1 = require("./websocket");
|
|
15
|
-
const generator_1 = require("./schemas/generator");
|
|
16
|
-
const dns_1 = __importDefault(require("dns"));
|
|
17
|
-
const http_1 = require("http");
|
|
18
|
-
class BareServer {
|
|
1
|
+
import Router from 'find-my-way';
|
|
2
|
+
import { Ajv } from 'ajv';
|
|
3
|
+
import { BareRequest } from './request.js';
|
|
4
|
+
import { logMe } from './logger/index.js';
|
|
5
|
+
import { context, enableContext, newContext } from './context/index.js';
|
|
6
|
+
import { HttpMethods, } from './utils/index.js';
|
|
7
|
+
import { Cors } from './middlewares/cors/cors.js';
|
|
8
|
+
import { WebSocketServer } from './websocket.js';
|
|
9
|
+
import { generateRouteSchema } from './schemas/generator.js';
|
|
10
|
+
import dns from 'dns';
|
|
11
|
+
import { createServer } from 'http';
|
|
12
|
+
export class BareServer {
|
|
19
13
|
bareOptions;
|
|
20
14
|
server;
|
|
21
15
|
ws;
|
|
@@ -24,7 +18,7 @@ class BareServer {
|
|
|
24
18
|
#middlewares = [];
|
|
25
19
|
#routes = new Map();
|
|
26
20
|
#routesLib = new Map();
|
|
27
|
-
#router = (
|
|
21
|
+
#router = Router({ ignoreTrailingSlash: true });
|
|
28
22
|
#errorHandler = this.basicErrorHandler;
|
|
29
23
|
#corsInstance;
|
|
30
24
|
#port = 3000;
|
|
@@ -35,7 +29,7 @@ class BareServer {
|
|
|
35
29
|
constructor(bareOptions = {}) {
|
|
36
30
|
this.bareOptions = bareOptions;
|
|
37
31
|
// init
|
|
38
|
-
this.server =
|
|
32
|
+
this.server = createServer(this.#listener.bind(this));
|
|
39
33
|
this.attachGracefulHandlers();
|
|
40
34
|
this.attachRoutesDeclarator();
|
|
41
35
|
this.applyLaunchOptions();
|
|
@@ -43,11 +37,11 @@ class BareServer {
|
|
|
43
37
|
return this;
|
|
44
38
|
}
|
|
45
39
|
#listener = (request, response) => {
|
|
46
|
-
const flow = new
|
|
40
|
+
const flow = new BareRequest(request, response, this.bareOptions);
|
|
47
41
|
// init and attach request uuid to the context
|
|
48
42
|
if (this.bareOptions.context) {
|
|
49
|
-
|
|
50
|
-
|
|
43
|
+
newContext('request');
|
|
44
|
+
context.current?.store.set('id', flow.ID.code);
|
|
51
45
|
}
|
|
52
46
|
// execute global middlewares on the request
|
|
53
47
|
this.applyMiddlewares(flow)
|
|
@@ -90,10 +84,10 @@ class BareServer {
|
|
|
90
84
|
this.#host = typeof bo.serverAddress === 'string' ? bo.serverAddress : '0.0.0.0';
|
|
91
85
|
// context setting
|
|
92
86
|
if (bo.context)
|
|
93
|
-
|
|
87
|
+
enableContext();
|
|
94
88
|
// ws attachment
|
|
95
89
|
if (bo.ws) {
|
|
96
|
-
this.ws = new
|
|
90
|
+
this.ws = new WebSocketServer(this.server, bo.wsOptions);
|
|
97
91
|
}
|
|
98
92
|
// middlewares settings
|
|
99
93
|
if (bo.errorHandlerMiddleware) {
|
|
@@ -101,7 +95,7 @@ class BareServer {
|
|
|
101
95
|
}
|
|
102
96
|
if (this.bareOptions.cors) {
|
|
103
97
|
const corsOpts = typeof this.bareOptions.cors === 'object' ? this.bareOptions.cors : {};
|
|
104
|
-
this.#corsInstance = new
|
|
98
|
+
this.#corsInstance = new Cors(corsOpts);
|
|
105
99
|
}
|
|
106
100
|
this.#middlewares.push(...(bo.middlewares || []));
|
|
107
101
|
};
|
|
@@ -121,7 +115,7 @@ class BareServer {
|
|
|
121
115
|
// to test in cloud provider
|
|
122
116
|
// this should resolve the name of the first hop from the dns chain
|
|
123
117
|
if (this.bareOptions.reverseDns) {
|
|
124
|
-
const remoteClient = await
|
|
118
|
+
const remoteClient = await dns.promises.reverse(flow.remoteIp);
|
|
125
119
|
flow['setRemoteClient'](remoteClient[0]);
|
|
126
120
|
}
|
|
127
121
|
if (this.#middlewares.length)
|
|
@@ -204,7 +198,7 @@ class BareServer {
|
|
|
204
198
|
if ((schema && check) || !schema)
|
|
205
199
|
flow.send(response);
|
|
206
200
|
else {
|
|
207
|
-
|
|
201
|
+
logMe.error('Response schema error!', {
|
|
208
202
|
method,
|
|
209
203
|
url,
|
|
210
204
|
errors: schema?.compiled.errors,
|
|
@@ -247,19 +241,19 @@ class BareServer {
|
|
|
247
241
|
process.on('unhandledRejection', (err) => {
|
|
248
242
|
console.error(err);
|
|
249
243
|
});
|
|
250
|
-
process.on('SIGTERM', graceful);
|
|
251
|
-
process.on('SIGINT', graceful);
|
|
244
|
+
process.on('SIGTERM', () => graceful(0));
|
|
245
|
+
process.on('SIGINT', () => graceful(0));
|
|
252
246
|
}
|
|
253
247
|
attachRoutesDeclarator() {
|
|
254
|
-
for (const method of [...Object.keys(
|
|
248
|
+
for (const method of [...Object.keys(HttpMethods), 'declare']) {
|
|
255
249
|
this.route[method] = (routeSetUp) => {
|
|
256
250
|
checkRouteSetUp(routeSetUp, method);
|
|
257
251
|
if (method === 'declare') {
|
|
258
252
|
for (const m of new Set(routeSetUp.methods))
|
|
259
|
-
this.setRoute(
|
|
253
|
+
this.setRoute(HttpMethods[m], routeSetUp.route, false, routeSetUp.handler, routeSetUp.options);
|
|
260
254
|
}
|
|
261
255
|
else {
|
|
262
|
-
this.setRoute(
|
|
256
|
+
this.setRoute(HttpMethods[method], routeSetUp.route, false, routeSetUp.handler, routeSetUp.options);
|
|
263
257
|
}
|
|
264
258
|
return this;
|
|
265
259
|
};
|
|
@@ -281,15 +275,15 @@ class BareServer {
|
|
|
281
275
|
console.warn('Runtime route declaration can be done only while the server is running. Follow documentation for more details');
|
|
282
276
|
return this;
|
|
283
277
|
}
|
|
284
|
-
if ([...Object.keys(
|
|
278
|
+
if ([...Object.keys(HttpMethods), 'declare'].includes(key)) {
|
|
285
279
|
return (routeSetUp) => {
|
|
286
280
|
checkRouteSetUp(routeSetUp, key);
|
|
287
281
|
if (key === 'declare') {
|
|
288
282
|
for (const m of new Set(routeSetUp.methods))
|
|
289
|
-
self.setRoute(
|
|
283
|
+
self.setRoute(HttpMethods[m], routeSetUp.route, true, routeSetUp.handler, routeSetUp.options);
|
|
290
284
|
}
|
|
291
285
|
else {
|
|
292
|
-
self.setRoute(
|
|
286
|
+
self.setRoute(HttpMethods[key], routeSetUp.route, true, routeSetUp.handler, routeSetUp.options);
|
|
293
287
|
}
|
|
294
288
|
return this;
|
|
295
289
|
};
|
|
@@ -304,7 +298,7 @@ class BareServer {
|
|
|
304
298
|
return new Promise((res) =>
|
|
305
299
|
// https://nodejs.org/api/net.html#net_server_listen_port_host_backlog_callback
|
|
306
300
|
this.server.listen(this.#port, this.#host, undefined, () => {
|
|
307
|
-
cb
|
|
301
|
+
cb?.(`http://0.0.0.0:${this.#port}`);
|
|
308
302
|
res();
|
|
309
303
|
}));
|
|
310
304
|
}
|
|
@@ -338,9 +332,9 @@ class BareServer {
|
|
|
338
332
|
return;
|
|
339
333
|
}
|
|
340
334
|
if (this.bareOptions.declaredRoutesPaths?.length) {
|
|
341
|
-
this.ajv = new
|
|
335
|
+
this.ajv = new Ajv({ strict: true });
|
|
342
336
|
for (const path of this.bareOptions.declaredRoutesPaths) {
|
|
343
|
-
const schemas =
|
|
337
|
+
const schemas = generateRouteSchema(path);
|
|
344
338
|
for (const schema of schemas) {
|
|
345
339
|
this.#routeRuntimeSchemas.set(`${schema.methodName}-${schema.route}`, {
|
|
346
340
|
raw: schema.jsonSchema,
|
|
@@ -367,8 +361,6 @@ class BareServer {
|
|
|
367
361
|
return [...this.#routes.keys()];
|
|
368
362
|
}
|
|
369
363
|
}
|
|
370
|
-
exports.BareServer = BareServer;
|
|
371
|
-
exports.BareHttp = BareServer;
|
|
372
364
|
function checkRouteSetUp(routeSetUp, key) {
|
|
373
365
|
if (typeof routeSetUp.route !== 'string') {
|
|
374
366
|
throw new TypeError(`A route path for the method ${key} is not a a string`);
|
|
@@ -395,9 +387,10 @@ function checkParams(params) {
|
|
|
395
387
|
if (value === undefined)
|
|
396
388
|
continue;
|
|
397
389
|
if (/(\.\/)(\.\.)(\\.)/.test(decodeURI(value))) {
|
|
398
|
-
|
|
390
|
+
logMe.warn(`Param ${param} value ${value} was redacted because contained dangerous characters`);
|
|
399
391
|
param[param] = 'REDACTED';
|
|
400
392
|
}
|
|
401
393
|
}
|
|
402
394
|
return params;
|
|
403
395
|
}
|
|
396
|
+
export { BareServer as BareHttp };
|
|
@@ -1,7 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.ContentType = void 0;
|
|
4
|
-
exports.ContentType = {
|
|
1
|
+
export const ContentType = {
|
|
5
2
|
'application/EDI-X12': 'application/EDI-X12',
|
|
6
3
|
'application/EDIFACT': 'application/EDIFACT',
|
|
7
4
|
'application/javascript': 'application/javascript',
|
|
@@ -29,7 +26,7 @@ exports.ContentType = {
|
|
|
29
26
|
'image/svg+xml': 'image/svg+xml',
|
|
30
27
|
'multipart/mixed': 'multipart/mixed',
|
|
31
28
|
'multipart/alternative': 'multipart/alternative',
|
|
32
|
-
'multipart/related': 'multipart/related',
|
|
29
|
+
'multipart/related': 'multipart/related', // (using by MHTML (HTML mail).)
|
|
33
30
|
'multipart/form-data': 'multipart/form-data',
|
|
34
31
|
'text/css': 'text/css',
|
|
35
32
|
'text/csv': 'text/csv',
|
|
@@ -7,5 +7,5 @@ export declare const HttpMethods: {
|
|
|
7
7
|
readonly options: "OPTIONS";
|
|
8
8
|
readonly head: "HEAD";
|
|
9
9
|
};
|
|
10
|
-
export
|
|
11
|
-
export
|
|
10
|
+
export type HttpMethodsUnion = keyof typeof HttpMethods;
|
|
11
|
+
export type HttpMethodsUnionUppercase = typeof HttpMethods[keyof typeof HttpMethods];
|
package/lib/utils/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { StatusPhrases } from './status-phrases';
|
|
2
|
-
export { StatusCodes, StatusCodesUnion } from './status-codes';
|
|
3
|
-
export { HttpMethods, HttpMethodsUnion, HttpMethodsUnionUppercase } from './http-methods';
|
|
4
|
-
export { JSONStringify, JSONParse } from './safe-json';
|
|
1
|
+
export { StatusPhrases } from './status-phrases.js';
|
|
2
|
+
export { StatusCodes, StatusCodesUnion } from './status-codes.js';
|
|
3
|
+
export { HttpMethods, HttpMethodsUnion, HttpMethodsUnionUppercase } from './http-methods.js';
|
|
4
|
+
export { JSONStringify, JSONParse } from './safe-json.js';
|
package/lib/utils/index.js
CHANGED
|
@@ -1,12 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
Object.defineProperty(exports, "StatusPhrases", { enumerable: true, get: function () { return status_phrases_1.StatusPhrases; } });
|
|
6
|
-
var status_codes_1 = require("./status-codes");
|
|
7
|
-
Object.defineProperty(exports, "StatusCodes", { enumerable: true, get: function () { return status_codes_1.StatusCodes; } });
|
|
8
|
-
var http_methods_1 = require("./http-methods");
|
|
9
|
-
Object.defineProperty(exports, "HttpMethods", { enumerable: true, get: function () { return http_methods_1.HttpMethods; } });
|
|
10
|
-
var safe_json_1 = require("./safe-json");
|
|
11
|
-
Object.defineProperty(exports, "JSONStringify", { enumerable: true, get: function () { return safe_json_1.JSONStringify; } });
|
|
12
|
-
Object.defineProperty(exports, "JSONParse", { enumerable: true, get: function () { return safe_json_1.JSONParse; } });
|
|
1
|
+
export { StatusPhrases } from './status-phrases.js';
|
|
2
|
+
export { StatusCodes } from './status-codes.js';
|
|
3
|
+
export { HttpMethods } from './http-methods.js';
|
|
4
|
+
export { JSONStringify, JSONParse } from './safe-json.js';
|
package/lib/utils/safe-json.js
CHANGED
|
@@ -1,7 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.JSONParse = exports.JSONStringify = void 0;
|
|
4
|
-
const JSONStringify = (data) => {
|
|
1
|
+
export const JSONStringify = (data) => {
|
|
5
2
|
try {
|
|
6
3
|
return JSON.stringify(data);
|
|
7
4
|
}
|
|
@@ -10,8 +7,7 @@ const JSONStringify = (data) => {
|
|
|
10
7
|
return null;
|
|
11
8
|
}
|
|
12
9
|
};
|
|
13
|
-
|
|
14
|
-
const JSONParse = (data) => {
|
|
10
|
+
export const JSONParse = (data) => {
|
|
15
11
|
try {
|
|
16
12
|
return JSON.parse(data);
|
|
17
13
|
}
|
|
@@ -20,4 +16,3 @@ const JSONParse = (data) => {
|
|
|
20
16
|
return e;
|
|
21
17
|
}
|
|
22
18
|
};
|
|
23
|
-
exports.JSONParse = JSONParse;
|
|
@@ -1,8 +1,5 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.StatusCodes = void 0;
|
|
4
1
|
// taken from https://github.com/prettymuchbryce/http-status-codes/
|
|
5
|
-
|
|
2
|
+
export const StatusCodes = {
|
|
6
3
|
/**
|
|
7
4
|
* Official Documentation @ https://tools.ietf.org/html/rfc7231#section-6.3.3
|
|
8
5
|
*
|
|
@@ -1,8 +1,5 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.StatusPhrases = void 0;
|
|
4
1
|
// taken from https://github.com/prettymuchbryce/http-status-codes/
|
|
5
|
-
|
|
2
|
+
export const StatusPhrases = {
|
|
6
3
|
/**
|
|
7
4
|
* Official Documentation @ https://tools.ietf.org/html/rfc7231#section-6.3.3
|
|
8
5
|
*
|
package/lib/websocket.d.ts
CHANGED
|
@@ -1,17 +1,16 @@
|
|
|
1
|
-
|
|
2
|
-
import Client, { MessageEvent, Server as WServer, ServerOptions } from 'ws';
|
|
1
|
+
import WebSocket, { WebSocketServer as WServer, type MessageEvent, type ServerOptions } from 'ws';
|
|
3
2
|
import { IncomingMessage, Server } from 'http';
|
|
4
|
-
|
|
3
|
+
type UserClient = {
|
|
5
4
|
secId: string;
|
|
6
5
|
[k: string]: any;
|
|
7
6
|
};
|
|
8
|
-
|
|
7
|
+
type AuthAccess<T> = {
|
|
9
8
|
access: boolean;
|
|
10
9
|
message?: string;
|
|
11
10
|
client?: T;
|
|
12
11
|
};
|
|
13
|
-
export
|
|
14
|
-
|
|
12
|
+
export type WsMessageHandler<D = any, UC extends UserClient = UserClient, M = any> = (data: D, client: UC, _ws: ClientWS<UC>, _event: MessageEvent) => Promise<M> | M;
|
|
13
|
+
type ClientWS<UC extends UserClient = UserClient> = WebSocket & {
|
|
15
14
|
userClient: UC;
|
|
16
15
|
};
|
|
17
16
|
export declare class WebSocketServer {
|
|
@@ -31,7 +30,7 @@ export declare class WebSocketServer {
|
|
|
31
30
|
handler: WsMessageHandler<D, C>;
|
|
32
31
|
}): void;
|
|
33
32
|
getClientById<T extends UserClient>(id: string): ClientWS<T> | undefined;
|
|
34
|
-
getClientByCriteria<T extends UserClient>(criteria: string, value: any, criteriaFunction?: (client: ClientWS<T>) => boolean):
|
|
33
|
+
getClientByCriteria<T extends UserClient>(criteria: string, value: any, criteriaFunction?: (client: ClientWS<T>) => boolean): WebSocket | undefined;
|
|
35
34
|
handleManualConnect<T extends UserClient>(fn: (socket: ClientWS<T>, client: T) => Promise<void> | void): void;
|
|
36
35
|
}
|
|
37
36
|
export {};
|
package/lib/websocket.js
CHANGED
|
@@ -1,16 +1,10 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
};
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
const callsites_1 = __importDefault(require("callsites"));
|
|
9
|
-
const hyperid_1 = __importDefault(require("hyperid"));
|
|
10
|
-
const logger_1 = require("./logger");
|
|
11
|
-
const utils_1 = require("./utils");
|
|
12
|
-
const generateId = (0, hyperid_1.default)();
|
|
13
|
-
class WebSocketServer {
|
|
1
|
+
import WebSocket, { WebSocketServer as WServer } from 'ws';
|
|
2
|
+
import callsites from 'callsites';
|
|
3
|
+
import hyperid from 'hyperid';
|
|
4
|
+
import { logMe } from './logger/index.js';
|
|
5
|
+
import { JSONParse, JSONStringify } from './utils/index.js';
|
|
6
|
+
const generateId = hyperid();
|
|
7
|
+
export class WebSocketServer {
|
|
14
8
|
opts;
|
|
15
9
|
_internal;
|
|
16
10
|
#httpServer;
|
|
@@ -27,7 +21,7 @@ class WebSocketServer {
|
|
|
27
21
|
}
|
|
28
22
|
#createWServer(newOptions = {}) {
|
|
29
23
|
const opts = Object.assign({}, this.opts, newOptions);
|
|
30
|
-
this._internal = new
|
|
24
|
+
this._internal = new WServer(opts);
|
|
31
25
|
this.attachTypesHandling();
|
|
32
26
|
}
|
|
33
27
|
defineUpgrade(fn) {
|
|
@@ -71,22 +65,22 @@ class WebSocketServer {
|
|
|
71
65
|
}
|
|
72
66
|
}
|
|
73
67
|
rejectUpgrade(request, socket, message = 'Not Authorized', data) {
|
|
74
|
-
|
|
68
|
+
logMe.warn(message || `Upgrade rejected for the client from ${request.socket.remoteAddress}`, data);
|
|
75
69
|
socket.write('HTTP/1.1 401 Unauthorized\r\n\r\n'); // TODO: enhance to be able to personalize this
|
|
76
70
|
socket.destroy();
|
|
77
71
|
}
|
|
78
72
|
attachTypesHandling() {
|
|
79
73
|
this._internal.on('connection', (ws, _, client) => {
|
|
80
74
|
ws.onmessage = (event) => {
|
|
81
|
-
const decode =
|
|
75
|
+
const decode = JSONParse(event.data);
|
|
82
76
|
if (decode === null) {
|
|
83
|
-
|
|
77
|
+
logMe.error('Incorrect data received from the client', {
|
|
84
78
|
data: event.data,
|
|
85
79
|
client: client ?? 'UNDEFINED_CLIENT',
|
|
86
80
|
});
|
|
87
81
|
}
|
|
88
82
|
else if (!decode.type) {
|
|
89
|
-
|
|
83
|
+
logMe.error(`Data from the client does not contain 'type' field`, {
|
|
90
84
|
data: event.data,
|
|
91
85
|
client: client ?? 'UNDEFINED_CLIENT',
|
|
92
86
|
});
|
|
@@ -94,7 +88,7 @@ class WebSocketServer {
|
|
|
94
88
|
else {
|
|
95
89
|
const procedure = this.#types.get(decode.type);
|
|
96
90
|
if (!procedure || typeof procedure.handler !== 'function') {
|
|
97
|
-
|
|
91
|
+
logMe.error(`There's no correct procedure for type "${decode.type}"`, {
|
|
98
92
|
data: event.data,
|
|
99
93
|
client: client ?? 'UNDEFINED_CLIENT',
|
|
100
94
|
});
|
|
@@ -107,9 +101,9 @@ class WebSocketServer {
|
|
|
107
101
|
.then((resolvedResponse) => {
|
|
108
102
|
if (!resolvedResponse)
|
|
109
103
|
return;
|
|
110
|
-
this.send({ ws, client },
|
|
104
|
+
this.send({ ws, client }, JSONStringify({ type: `${decode.type}_RESPONSE`, ...resolvedResponse }));
|
|
111
105
|
})
|
|
112
|
-
.catch((e) =>
|
|
106
|
+
.catch((e) => logMe.error(`Error working out a handler for type ${decode.type}`, {
|
|
113
107
|
error: e,
|
|
114
108
|
client,
|
|
115
109
|
data: decode,
|
|
@@ -118,11 +112,11 @@ class WebSocketServer {
|
|
|
118
112
|
else {
|
|
119
113
|
if (!response)
|
|
120
114
|
return;
|
|
121
|
-
this.send({ ws, client },
|
|
115
|
+
this.send({ ws, client }, JSONStringify({ type: `${decode.type}_RESPONSE`, ...response }));
|
|
122
116
|
}
|
|
123
117
|
}
|
|
124
118
|
catch (e) {
|
|
125
|
-
|
|
119
|
+
logMe.error(`Error working out a handler for type ${decode.type}`, {
|
|
126
120
|
error: e,
|
|
127
121
|
client,
|
|
128
122
|
data: decode,
|
|
@@ -134,11 +128,15 @@ class WebSocketServer {
|
|
|
134
128
|
});
|
|
135
129
|
}
|
|
136
130
|
send(ctx, data) {
|
|
137
|
-
if (
|
|
131
|
+
if (data === null) {
|
|
132
|
+
logMe.error('Could not serialize data for the client', { client: ctx.client });
|
|
133
|
+
return;
|
|
134
|
+
}
|
|
135
|
+
if (ctx.ws.readyState === WebSocket.OPEN) {
|
|
138
136
|
ctx.ws.send(data);
|
|
139
137
|
}
|
|
140
138
|
else {
|
|
141
|
-
|
|
139
|
+
logMe.error('Could not send data for the client', { client: ctx.client });
|
|
142
140
|
}
|
|
143
141
|
}
|
|
144
142
|
declareReceiver(receiver) {
|
|
@@ -149,7 +147,7 @@ class WebSocketServer {
|
|
|
149
147
|
if (typeof receiver.handler !== 'function') {
|
|
150
148
|
throw new Error(`Can't declare a handler with type ${typeof receiver.handler}, should be a function with following signature: WsMessageHandler<T,?>`);
|
|
151
149
|
}
|
|
152
|
-
const place = (
|
|
150
|
+
const place = callsites()[2];
|
|
153
151
|
const loc = `${place.getFileName()}:${place.getLineNumber()}:${place.getColumnNumber()}`;
|
|
154
152
|
this.#types.set(receiver.type, { loc, handler: receiver.handler });
|
|
155
153
|
}
|
|
@@ -176,4 +174,3 @@ class WebSocketServer {
|
|
|
176
174
|
this._internal.on('connection', (ws, _, client) => fn(ws, client));
|
|
177
175
|
}
|
|
178
176
|
}
|
|
179
|
-
exports.WebSocketServer = WebSocketServer;
|
package/package.json
CHANGED
|
@@ -1,8 +1,15 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "barehttp",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "2.0.0",
|
|
4
4
|
"description": "Lightweight and fast Node.js web server",
|
|
5
5
|
"main": "lib/index.js",
|
|
6
|
+
"types": "lib/index.d.ts",
|
|
7
|
+
"exports": {
|
|
8
|
+
".": {
|
|
9
|
+
"types": "./lib/index.d.ts",
|
|
10
|
+
"import": "./lib/index.js"
|
|
11
|
+
}
|
|
12
|
+
},
|
|
6
13
|
"directories": {
|
|
7
14
|
"lib": "lib",
|
|
8
15
|
"test": "__tests__"
|
|
@@ -10,6 +17,10 @@
|
|
|
10
17
|
"files": [
|
|
11
18
|
"lib"
|
|
12
19
|
],
|
|
20
|
+
"type": "module",
|
|
21
|
+
"engines": {
|
|
22
|
+
"node": ">=22"
|
|
23
|
+
},
|
|
13
24
|
"scripts": {
|
|
14
25
|
"build": "rm -rf ./lib && tsc -p tsconfig.build.json",
|
|
15
26
|
"build:dev": "rm -rf ./dev-lib && tsc -p tsconfig.dev.json",
|
|
@@ -29,50 +40,50 @@
|
|
|
29
40
|
"author": "Konstantin Knyazev <konstantinknyazev@outlook.com>",
|
|
30
41
|
"repository": {
|
|
31
42
|
"type": "git",
|
|
32
|
-
"url": "https://github.com/sckv/barehttp.git"
|
|
43
|
+
"url": "git+https://github.com/sckv/barehttp.git"
|
|
33
44
|
},
|
|
34
45
|
"license": "MIT",
|
|
35
46
|
"dependencies": {
|
|
36
|
-
"ajv": "^8.
|
|
37
|
-
"callsites": "^
|
|
38
|
-
"cookie": "^
|
|
39
|
-
"cookie-signature": "^1.2.
|
|
40
|
-
"find-my-way": "^
|
|
41
|
-
"hyperid": "^
|
|
47
|
+
"ajv": "^8.17.1",
|
|
48
|
+
"callsites": "^4.2.0",
|
|
49
|
+
"cookie": "^1.1.1",
|
|
50
|
+
"cookie-signature": "^1.2.2",
|
|
51
|
+
"find-my-way": "^9.3.0",
|
|
52
|
+
"hyperid": "^3.3.0",
|
|
42
53
|
"lodash": "^4.17.21",
|
|
43
|
-
"pino": "^
|
|
44
|
-
"pino-pretty": "^
|
|
45
|
-
"ts-morph": "^
|
|
46
|
-
"ws": "^8.
|
|
54
|
+
"pino": "^10.1.0",
|
|
55
|
+
"pino-pretty": "^13.1.3",
|
|
56
|
+
"ts-morph": "^27.0.2",
|
|
57
|
+
"ws": "^8.18.3"
|
|
47
58
|
},
|
|
48
59
|
"devDependencies": {
|
|
49
60
|
"@semantic-release/git": "^10.0.1",
|
|
50
|
-
"@semantic-release/github": "^
|
|
51
|
-
"@ts-morph/bootstrap": "^0.
|
|
52
|
-
"@types/cookie": "^0.
|
|
53
|
-
"@types/cookie-signature": "^1.
|
|
54
|
-
"@types/jest": "^
|
|
55
|
-
"@types/node": "^
|
|
56
|
-
"@types/pino": "^7.0.
|
|
57
|
-
"@types/ws": "^8.
|
|
58
|
-
"@typescript-eslint/eslint-plugin": "^
|
|
59
|
-
"@typescript-eslint/parser": "^
|
|
60
|
-
"axios": "^
|
|
61
|
-
"eslint": "^
|
|
62
|
-
"eslint-plugin-import": "^2.
|
|
63
|
-
"eslint-plugin-jest": "^
|
|
64
|
-
"express": "^
|
|
65
|
-
"fastify": "^
|
|
66
|
-
"jest": "^
|
|
67
|
-
"prettier": "^
|
|
68
|
-
"semantic-release": "^
|
|
69
|
-
"supertest": "^
|
|
70
|
-
"ts-jest": "^
|
|
71
|
-
"ts-node-dev": "^
|
|
72
|
-
"typescript": "^
|
|
61
|
+
"@semantic-release/github": "^12.0.2",
|
|
62
|
+
"@ts-morph/bootstrap": "^0.28.1",
|
|
63
|
+
"@types/cookie": "^0.6.0",
|
|
64
|
+
"@types/cookie-signature": "^1.1.2",
|
|
65
|
+
"@types/jest": "^30.0.0",
|
|
66
|
+
"@types/node": "^25.0.3",
|
|
67
|
+
"@types/pino": "^7.0.4",
|
|
68
|
+
"@types/ws": "^8.18.1",
|
|
69
|
+
"@typescript-eslint/eslint-plugin": "^8.50.1",
|
|
70
|
+
"@typescript-eslint/parser": "^8.50.1",
|
|
71
|
+
"axios": "^1.13.2",
|
|
72
|
+
"eslint": "^9.39.2",
|
|
73
|
+
"eslint-plugin-import": "^2.32.0",
|
|
74
|
+
"eslint-plugin-jest": "^29.11.0",
|
|
75
|
+
"express": "^5.2.1",
|
|
76
|
+
"fastify": "^5.6.2",
|
|
77
|
+
"jest": "^30.2.0",
|
|
78
|
+
"prettier": "^3.7.4",
|
|
79
|
+
"semantic-release": "^25.0.2",
|
|
80
|
+
"supertest": "^7.1.4",
|
|
81
|
+
"ts-jest": "^29.4.6",
|
|
82
|
+
"ts-node-dev": "^2.0.0",
|
|
83
|
+
"typescript": "^5.9.3"
|
|
73
84
|
},
|
|
74
85
|
"optionalDependencies": {
|
|
75
|
-
"bufferutil": "^4.0
|
|
76
|
-
"utf-8-validate": "^
|
|
86
|
+
"bufferutil": "^4.1.0",
|
|
87
|
+
"utf-8-validate": "^6.0.6"
|
|
77
88
|
}
|
|
78
89
|
}
|