@e22m4u/js-trie-router 0.7.4 → 0.7.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/README.md CHANGED
@@ -16,6 +16,7 @@ HTTP маршрутизатор для Node.js на основе
16
16
  ## Содержание
17
17
 
18
18
  - [Установка](#установка)
19
+ - [Расширения](#расширения)
19
20
  - [Использование](#использование)
20
21
  - [Параметры маршрутизатора](#параметры-маршрутизатора)
21
22
  - [Контекст запроса](#контекст-запроса)
@@ -54,6 +55,15 @@ import {TrieRouter} from '@e22m4u/js-trie-router';
54
55
  const {TrieRouter} = require('@e22m4u/js-trie-router');
55
56
  ```
56
57
 
58
+ ## Расширения
59
+
60
+ Расширение функционала выполняется с помощью NPM модулей.
61
+
62
+ | модуль | описание |
63
+ |------------------------------------------------------------------------------------------------|------------------------------------------------|
64
+ | [@e22m4u/js-trie-router-cors](https://www.npmjs.com/package/@e22m4u/js-trie-router-cors) | Модуль поддержки CORS (кросс-доменные запросы) |
65
+ | [@e22m4u/js-trie-router-openapi](https://www.npmjs.com/package/@e22m4u/js-trie-router-openapi) | Генерация OpenAPI документа и валидация данных |
66
+
57
67
  ## Использование
58
68
 
59
69
  Базовый пример создания экземпляра роутера, объявления маршрута
@@ -43,6 +43,7 @@ __export(index_exports, {
43
43
  RequestQueryParser: () => RequestQueryParser,
44
44
  Route: () => Route,
45
45
  RouteRegistry: () => RouteRegistry,
46
+ RouterBranch: () => RouterBranch,
46
47
  RouterDataSender: () => RouterDataSender,
47
48
  RouterErrorSender: () => RouterErrorSender,
48
49
  RouterHookInvoker: () => RouterHookInvoker,
@@ -65,12 +66,14 @@ __export(index_exports, {
65
66
  isResponseSent: () => isResponseSent,
66
67
  isWritableStream: () => isWritableStream,
67
68
  mergeDeep: () => mergeDeep,
69
+ mergeRouterBranchDefinitions: () => mergeRouterBranchDefinitions,
68
70
  parseContentType: () => parseContentType,
69
71
  parseCookieString: () => parseCookieString,
70
72
  parseJsonBody: () => parseJsonBody,
71
73
  toCamelCase: () => toCamelCase,
72
74
  toPascalCase: () => toPascalCase,
73
- validateRouteDefinition: () => validateRouteDefinition
75
+ validateRouteDefinition: () => validateRouteDefinition,
76
+ validateRouterBranchDefinition: () => validateRouterBranchDefinition
74
77
  });
75
78
  module.exports = __toCommonJS(index_exports);
76
79
 
@@ -2428,8 +2431,8 @@ var _RouterDataSender = class _RouterDataSender extends DebuggableService {
2428
2431
  return;
2429
2432
  }
2430
2433
  if (isReadableStream(data)) {
2431
- if (!response.getHeader("content-type")) {
2432
- response.setHeader("content-type", "application/octet-stream");
2434
+ if (!response.getHeader("Content-Type")) {
2435
+ response.setHeader("Content-Type", "application/octet-stream");
2433
2436
  }
2434
2437
  data.pipe(response);
2435
2438
  debug("Sending response with a Stream.");
@@ -2441,13 +2444,13 @@ var _RouterDataSender = class _RouterDataSender extends DebuggableService {
2441
2444
  case "boolean":
2442
2445
  case "object":
2443
2446
  if (Buffer.isBuffer(data)) {
2444
- if (!response.getHeader("content-type")) {
2445
- response.setHeader("content-type", "application/octet-stream");
2447
+ if (!response.getHeader("Content-Type")) {
2448
+ response.setHeader("Content-Type", "application/octet-stream");
2446
2449
  }
2447
2450
  debugMsg = "Buffer has been sent as binary data.";
2448
2451
  } else {
2449
- if (!response.getHeader("content-type")) {
2450
- response.setHeader("content-type", "application/json");
2452
+ if (!response.getHeader("Content-Type")) {
2453
+ response.setHeader("Content-Type", "application/json");
2451
2454
  }
2452
2455
  debugMsg = (0, import_js_format21.format)(
2453
2456
  "%v has been sent as JSON.",
@@ -2457,8 +2460,8 @@ var _RouterDataSender = class _RouterDataSender extends DebuggableService {
2457
2460
  }
2458
2461
  break;
2459
2462
  default:
2460
- if (!response.getHeader("content-type")) {
2461
- response.setHeader("content-type", "text/plain");
2463
+ if (!response.getHeader("Content-Type")) {
2464
+ response.setHeader("Content-Type", "text/plain");
2462
2465
  }
2463
2466
  debugMsg = "Response data has been sent as plain text.";
2464
2467
  data = String(data);
@@ -2525,7 +2528,7 @@ var _RouterErrorSender = class _RouterErrorSender extends DebuggableService {
2525
2528
  console.error(error);
2526
2529
  }
2527
2530
  response.statusCode = statusCode;
2528
- response.setHeader("content-type", "application/json; charset=utf-8");
2531
+ response.setHeader("Content-Type", "application/json; charset=utf-8");
2529
2532
  response.end(JSON.stringify(body, null, 2), "utf-8");
2530
2533
  debug(
2531
2534
  "%s error has been sent for the request %s %v.",
@@ -2544,7 +2547,7 @@ var _RouterErrorSender = class _RouterErrorSender extends DebuggableService {
2544
2547
  send404(request, response) {
2545
2548
  const debug = this.getDebuggerFor(this.send404);
2546
2549
  response.statusCode = 404;
2547
- response.setHeader("content-type", "text/plain; charset=utf-8");
2550
+ response.setHeader("Content-Type", "text/plain; charset=utf-8");
2548
2551
  response.end("404 Not Found", "utf-8");
2549
2552
  debug(
2550
2553
  "404 error has been sent for the request %s %v.",
@@ -2797,6 +2800,7 @@ var TrieRouter = _TrieRouter;
2797
2800
  RequestQueryParser,
2798
2801
  Route,
2799
2802
  RouteRegistry,
2803
+ RouterBranch,
2800
2804
  RouterDataSender,
2801
2805
  RouterErrorSender,
2802
2806
  RouterHookInvoker,
@@ -2819,10 +2823,12 @@ var TrieRouter = _TrieRouter;
2819
2823
  isResponseSent,
2820
2824
  isWritableStream,
2821
2825
  mergeDeep,
2826
+ mergeRouterBranchDefinitions,
2822
2827
  parseContentType,
2823
2828
  parseCookieString,
2824
2829
  parseJsonBody,
2825
2830
  toCamelCase,
2826
2831
  toPascalCase,
2827
- validateRouteDefinition
2832
+ validateRouteDefinition,
2833
+ validateRouterBranchDefinition
2828
2834
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@e22m4u/js-trie-router",
3
- "version": "0.7.4",
3
+ "version": "0.7.6",
4
4
  "description": "HTTP маршрутизатор для Node.js на основе префиксного дерева",
5
5
  "author": "Mikhail Evstropov <e22m4u@yandex.ru>",
6
6
  "license": "MIT",
@@ -11,10 +11,10 @@
11
11
  "server",
12
12
  "nodejs"
13
13
  ],
14
- "homepage": "https://gitrepos.ru/e22m4u/js-trie-router",
14
+ "homepage": "https://gitverse.ru/e22m4u/js-trie-router",
15
15
  "repository": {
16
16
  "type": "git",
17
- "url": "git+https://gitrepos.ru/e22m4u/js-trie-router.git"
17
+ "url": "git+https://gitverse.ru/e22m4u/js-trie-router.git"
18
18
  },
19
19
  "type": "module",
20
20
  "types": "./src/index.d.ts",
package/src/index.d.ts CHANGED
@@ -3,6 +3,7 @@ export * from './route/index.js';
3
3
  export * from './utils/index.js';
4
4
  export * from './hooks/index.js';
5
5
  export * from './trie-router.js';
6
+ export * from './branch/index.js';
6
7
  export * from './parsers/index.js';
7
8
  export * from './senders/index.js';
8
9
  export * from './request-context.js';
package/src/index.js CHANGED
@@ -3,6 +3,7 @@ export * from './route/index.js';
3
3
  export * from './utils/index.js';
4
4
  export * from './hooks/index.js';
5
5
  export * from './trie-router.js';
6
+ export * from './branch/index.js';
6
7
  export * from './parsers/index.js';
7
8
  export * from './senders/index.js';
8
9
  export * from './request-context.js';
@@ -33,10 +33,10 @@ export class RouterDataSender extends DebuggableService {
33
33
  // если ответ контроллера является стримом,
34
34
  // то поток отправляет бинарные данные
35
35
  if (isReadableStream(data)) {
36
- // если заголовок "content-type" не определен ранее,
36
+ // если заголовок "Content-Type" не определен ранее,
37
37
  // то устанавливается заголовок потоковых данных
38
- if (!response.getHeader('content-type')) {
39
- response.setHeader('content-type', 'application/octet-stream');
38
+ if (!response.getHeader('Content-Type')) {
39
+ response.setHeader('Content-Type', 'application/octet-stream');
40
40
  }
41
41
  data.pipe(response);
42
42
  debug('Sending response with a Stream.');
@@ -49,21 +49,21 @@ export class RouterDataSender extends DebuggableService {
49
49
  case 'number':
50
50
  case 'boolean':
51
51
  case 'object':
52
- // для бинарных данных предусмотрен специальный "content-type",
52
+ // для бинарных данных предусмотрен специальный "Content-Type",
53
53
  // который устанавливается автоматически, если не был определен
54
54
  // ранее (к примеру, в обработчике маршрута)
55
55
  if (Buffer.isBuffer(data)) {
56
- if (!response.getHeader('content-type')) {
57
- response.setHeader('content-type', 'application/octet-stream');
56
+ if (!response.getHeader('Content-Type')) {
57
+ response.setHeader('Content-Type', 'application/octet-stream');
58
58
  }
59
59
  debugMsg = 'Buffer has been sent as binary data.';
60
60
  }
61
61
  // объекты, массивы, числа и логические значения
62
62
  // отправляются в виде JSON строки, с соответствующим
63
- // заголовком "content-type" (если не был определен)
63
+ // заголовком "Content-Type" (если не был определен)
64
64
  else {
65
- if (!response.getHeader('content-type')) {
66
- response.setHeader('content-type', 'application/json');
65
+ if (!response.getHeader('Content-Type')) {
66
+ response.setHeader('Content-Type', 'application/json');
67
67
  }
68
68
  debugMsg = format(
69
69
  '%v has been sent as JSON.',
@@ -73,8 +73,8 @@ export class RouterDataSender extends DebuggableService {
73
73
  }
74
74
  break;
75
75
  default:
76
- if (!response.getHeader('content-type')) {
77
- response.setHeader('content-type', 'text/plain');
76
+ if (!response.getHeader('Content-Type')) {
77
+ response.setHeader('Content-Type', 'text/plain');
78
78
  }
79
79
  debugMsg = 'Response data has been sent as plain text.';
80
80
  data = String(data);
@@ -80,7 +80,7 @@ describe('RouterDataSender', function () {
80
80
  writable._final = function (callback) {
81
81
  const sentData = Buffer.concat(chunks).toString('utf-8');
82
82
  expect(sentData).to.be.eq(data);
83
- const ct = res.getHeader('content-type');
83
+ const ct = res.getHeader('Content-Type');
84
84
  expect(ct).to.be.eq('application/octet-stream');
85
85
  callback();
86
86
  done();
@@ -90,7 +90,7 @@ describe('RouterDataSender', function () {
90
90
  S.send(res, stream);
91
91
  });
92
92
 
93
- it('should allow override the "content-type" header for a readable stream', function (done) {
93
+ it('should allow override the "Content-Type" header for a readable stream', function (done) {
94
94
  const data = 'text';
95
95
  const stream = new Readable();
96
96
  stream._read = () => {};
@@ -98,7 +98,7 @@ describe('RouterDataSender', function () {
98
98
  stream.push(null);
99
99
  const res = createResponseMock();
100
100
  const contentType = 'custom/type';
101
- res.setHeader('content-type', contentType);
101
+ res.setHeader('Content-Type', contentType);
102
102
  const writable = new Writable();
103
103
  const chunks = [];
104
104
  writable._write = function (chunk, encoding, done) {
@@ -108,7 +108,7 @@ describe('RouterDataSender', function () {
108
108
  writable._final = function (callback) {
109
109
  const sentData = Buffer.concat(chunks).toString('utf-8');
110
110
  expect(sentData).to.be.eq(data);
111
- const ct = res.getHeader('content-type');
111
+ const ct = res.getHeader('Content-Type');
112
112
  expect(ct).to.be.eq(contentType);
113
113
  callback();
114
114
  done();
@@ -131,7 +131,7 @@ describe('RouterDataSender', function () {
131
131
  const sentJson = Buffer.concat(chunks).toString('utf-8');
132
132
  const sentData = JSON.parse(sentJson);
133
133
  expect(sentData).to.be.eql(data);
134
- const ct = res.getHeader('content-type');
134
+ const ct = res.getHeader('Content-Type');
135
135
  expect(ct).to.be.eq('application/json');
136
136
  callback();
137
137
  done();
@@ -141,11 +141,11 @@ describe('RouterDataSender', function () {
141
141
  S.send(res, data);
142
142
  });
143
143
 
144
- it('should allow override the "content-type" header for a number value', function (done) {
144
+ it('should allow override the "Content-Type" header for a number value', function (done) {
145
145
  const data = 10;
146
146
  const res = createResponseMock();
147
147
  const contentType = 'custom/type';
148
- res.setHeader('content-type', contentType);
148
+ res.setHeader('Content-Type', contentType);
149
149
  const writable = new Writable();
150
150
  const chunks = [];
151
151
  writable._write = function (chunk, encoding, done) {
@@ -156,7 +156,7 @@ describe('RouterDataSender', function () {
156
156
  const sentJson = Buffer.concat(chunks).toString('utf-8');
157
157
  const sentData = JSON.parse(sentJson);
158
158
  expect(sentData).to.be.eql(data);
159
- const ct = res.getHeader('content-type');
159
+ const ct = res.getHeader('Content-Type');
160
160
  expect(ct).to.be.eq(contentType);
161
161
  callback();
162
162
  done();
@@ -179,7 +179,7 @@ describe('RouterDataSender', function () {
179
179
  const sentJson = Buffer.concat(chunks).toString('utf-8');
180
180
  const sentData = JSON.parse(sentJson);
181
181
  expect(sentData).to.be.eql(data);
182
- const ct = res.getHeader('content-type');
182
+ const ct = res.getHeader('Content-Type');
183
183
  expect(ct).to.be.eq('application/json');
184
184
  callback();
185
185
  done();
@@ -189,11 +189,11 @@ describe('RouterDataSender', function () {
189
189
  S.send(res, data);
190
190
  });
191
191
 
192
- it('should allow override the "content-type" header for a boolean value', function (done) {
192
+ it('should allow override the "Content-Type" header for a boolean value', function (done) {
193
193
  const data = true;
194
194
  const res = createResponseMock();
195
195
  const contentType = 'custom/type';
196
- res.setHeader('content-type', contentType);
196
+ res.setHeader('Content-Type', contentType);
197
197
  const writable = new Writable();
198
198
  const chunks = [];
199
199
  writable._write = function (chunk, encoding, done) {
@@ -204,7 +204,7 @@ describe('RouterDataSender', function () {
204
204
  const sentJson = Buffer.concat(chunks).toString('utf-8');
205
205
  const sentData = JSON.parse(sentJson);
206
206
  expect(sentData).to.be.eql(data);
207
- const ct = res.getHeader('content-type');
207
+ const ct = res.getHeader('Content-Type');
208
208
  expect(ct).to.be.eq(contentType);
209
209
  callback();
210
210
  done();
@@ -226,7 +226,7 @@ describe('RouterDataSender', function () {
226
226
  writable._final = function (callback) {
227
227
  const sentData = Buffer.concat(chunks);
228
228
  expect(sentData).to.be.eql(sentData);
229
- const ct = res.getHeader('content-type');
229
+ const ct = res.getHeader('Content-Type');
230
230
  expect(ct).to.be.eq('application/octet-stream');
231
231
  callback();
232
232
  done();
@@ -236,11 +236,11 @@ describe('RouterDataSender', function () {
236
236
  S.send(res, data);
237
237
  });
238
238
 
239
- it('should allow override the "content-type" header for a Buffer', function (done) {
239
+ it('should allow override the "Content-Type" header for a Buffer', function (done) {
240
240
  const data = Buffer.from('text');
241
241
  const res = createResponseMock();
242
242
  const contentType = 'custom/type';
243
- res.setHeader('content-type', contentType);
243
+ res.setHeader('Content-Type', contentType);
244
244
  const writable = new Writable();
245
245
  const chunks = [];
246
246
  writable._write = function (chunk, encoding, done) {
@@ -250,7 +250,7 @@ describe('RouterDataSender', function () {
250
250
  writable._final = function (callback) {
251
251
  const sentData = Buffer.concat(chunks);
252
252
  expect(sentData).to.be.eql(sentData);
253
- const ct = res.getHeader('content-type');
253
+ const ct = res.getHeader('Content-Type');
254
254
  expect(ct).to.be.eq(contentType);
255
255
  callback();
256
256
  done();
@@ -273,7 +273,7 @@ describe('RouterDataSender', function () {
273
273
  const sentJson = Buffer.concat(chunks).toString('utf-8');
274
274
  const sentData = JSON.parse(sentJson);
275
275
  expect(sentData).to.be.eql(data);
276
- const ct = res.getHeader('content-type');
276
+ const ct = res.getHeader('Content-Type');
277
277
  expect(ct).to.be.eq('application/json');
278
278
  callback();
279
279
  done();
@@ -283,11 +283,11 @@ describe('RouterDataSender', function () {
283
283
  S.send(res, data);
284
284
  });
285
285
 
286
- it('should allow override the "content-type" header for an object value', function (done) {
286
+ it('should allow override the "Content-Type" header for an object value', function (done) {
287
287
  const data = {foo: 'bar'};
288
288
  const res = createResponseMock();
289
289
  const contentType = 'custom/type';
290
- res.setHeader('content-type', contentType);
290
+ res.setHeader('Content-Type', contentType);
291
291
  const writable = new Writable();
292
292
  const chunks = [];
293
293
  writable._write = function (chunk, encoding, done) {
@@ -298,7 +298,7 @@ describe('RouterDataSender', function () {
298
298
  const sentJson = Buffer.concat(chunks).toString('utf-8');
299
299
  const sentData = JSON.parse(sentJson);
300
300
  expect(sentData).to.be.eql(data);
301
- const ct = res.getHeader('content-type');
301
+ const ct = res.getHeader('Content-Type');
302
302
  expect(ct).to.be.eq(contentType);
303
303
  callback();
304
304
  done();
@@ -320,7 +320,7 @@ describe('RouterDataSender', function () {
320
320
  writable._final = function (callback) {
321
321
  const sentData = Buffer.concat(chunks).toString('utf-8');
322
322
  expect(sentData).to.be.eq(data);
323
- const ct = res.getHeader('content-type');
323
+ const ct = res.getHeader('Content-Type');
324
324
  expect(ct).to.be.eq('text/plain');
325
325
  callback();
326
326
  done();
@@ -330,11 +330,11 @@ describe('RouterDataSender', function () {
330
330
  S.send(res, data);
331
331
  });
332
332
 
333
- it('should allow override the "content-type" header for a string value', function (done) {
333
+ it('should allow override the "Content-Type" header for a string value', function (done) {
334
334
  const data = 'text';
335
335
  const res = createResponseMock();
336
336
  const contentType = 'custom/type';
337
- res.setHeader('content-type', contentType);
337
+ res.setHeader('Content-Type', contentType);
338
338
  const writable = new Writable();
339
339
  const chunks = [];
340
340
  writable._write = function (chunk, encoding, done) {
@@ -344,7 +344,7 @@ describe('RouterDataSender', function () {
344
344
  writable._final = function (callback) {
345
345
  const sentData = Buffer.concat(chunks).toString('utf-8');
346
346
  expect(sentData).to.be.eq(data);
347
- const ct = res.getHeader('content-type');
347
+ const ct = res.getHeader('Content-Type');
348
348
  expect(ct).to.be.eq(contentType);
349
349
  callback();
350
350
  done();
@@ -63,7 +63,7 @@ export class RouterErrorSender extends DebuggableService {
63
63
  console.error(error);
64
64
  }
65
65
  response.statusCode = statusCode;
66
- response.setHeader('content-type', 'application/json; charset=utf-8');
66
+ response.setHeader('Content-Type', 'application/json; charset=utf-8');
67
67
  response.end(JSON.stringify(body, null, 2), 'utf-8');
68
68
  debug(
69
69
  '%s error has been sent for the request %s %v.',
@@ -83,7 +83,7 @@ export class RouterErrorSender extends DebuggableService {
83
83
  send404(request, response) {
84
84
  const debug = this.getDebuggerFor(this.send404);
85
85
  response.statusCode = 404;
86
- response.setHeader('content-type', 'text/plain; charset=utf-8');
86
+ response.setHeader('Content-Type', 'text/plain; charset=utf-8');
87
87
  response.end('404 Not Found', 'utf-8');
88
88
  debug(
89
89
  '404 error has been sent for the request %s %v.',
@@ -25,7 +25,7 @@ describe('RouterErrorSender', function () {
25
25
  const data = JSON.parse(json);
26
26
  expect(data).to.be.eql({error: {message: 'Unauthorized'}});
27
27
  expect(res.statusCode).to.be.eq(401);
28
- const ct = res.getHeader('content-type');
28
+ const ct = res.getHeader('Content-Type');
29
29
  expect(ct).to.be.eq('application/json; charset=utf-8');
30
30
  callback();
31
31
  done();
@@ -57,7 +57,7 @@ describe('RouterErrorSender', function () {
57
57
  expect(data.error).not.to.have.property('shouldNotBeExposedProp');
58
58
  expect(data).to.be.eql(expectedData);
59
59
  expect(res.statusCode).to.be.eq(401);
60
- const ct = res.getHeader('content-type');
60
+ const ct = res.getHeader('Content-Type');
61
61
  expect(ct).to.be.eq('application/json; charset=utf-8');
62
62
  callback();
63
63
  done();
@@ -82,7 +82,7 @@ describe('RouterErrorSender', function () {
82
82
  const body = Buffer.concat(chunks).toString('utf-8');
83
83
  expect(body).to.be.eql('404 Not Found');
84
84
  expect(res.statusCode).to.be.eq(404);
85
- const ct = res.getHeader('content-type');
85
+ const ct = res.getHeader('Content-Type');
86
86
  expect(ct).to.be.eq('text/plain; charset=utf-8');
87
87
  callback();
88
88
  done();