Browse Source

feat: adds the state property to RequestContext

e22m4u 1 week ago
parent
commit
93368782bc
5 changed files with 63 additions and 0 deletions
  1. 34 0
      README.md
  2. 6 0
      dist/cjs/index.cjs
  3. 5 0
      src/request-context.d.ts
  4. 7 0
      src/request-context.js
  5. 11 0
      src/request-context.spec.js

+ 34 - 0
README.md

@@ -23,6 +23,7 @@ HTTP маршрутизатор для Node.js на основе
     - [postHandler](#posthandler)
     - [postHandler](#posthandler)
   - [Глобальные хуки](#глобальные-хуки)
   - [Глобальные хуки](#глобальные-хуки)
   - [Метаданные](#метаданные)
   - [Метаданные](#метаданные)
+  - [Состояние запроса](#состояние-запроса)
 - [Отладка](#отладка)
 - [Отладка](#отладка)
 - [Тестирование](#тестирование)
 - [Тестирование](#тестирование)
 - [Лицензия](#лицензия)
 - [Лицензия](#лицензия)
@@ -100,6 +101,7 @@ server.listen(3000, 'localhost');             // прослушивание за
 - `response: ServerResponse` нативный поток ответа сервера;
 - `response: ServerResponse` нативный поток ответа сервера;
 - `route: Route` экземпляр текущего маршрута;
 - `route: Route` экземпляр текущего маршрута;
 - `meta: object` геттер для доступа к метаданным маршрута (`route.meta`);
 - `meta: object` геттер для доступа к метаданным маршрута (`route.meta`);
+- `state: object` объект для обмена данными между хуками и обработчиком;
 
 
 Пример доступа к контексту из обработчика маршрута.
 Пример доступа к контексту из обработчика маршрута.
 
 
@@ -303,6 +305,38 @@ server.on('request', router.requestListener);
 server.listen(3000, 'localhost');
 server.listen(3000, 'localhost');
 ```
 ```
 
 
+### Состояние запроса
+
+Объект `ctx.state` инициализируется как пустой объект `{}` для каждого нового
+запроса. Он предназначен для передачи динамических данных (например, профиля
+пользователя после авторизации) из *pre-handler* хуков в основной обработчик
+маршрута или *post-handler* хуки.
+
+```js
+import http from 'http';
+import {TrieRouter, HttpMethod} from '@e22m4u/js-trie-router';
+
+const router = new TrieRouter();
+
+// глобальный хук авторизации
+router.addPreHandler((ctx) => {
+  // логика получения пользователя (например, из заголовков)
+  const user = {id: 1, name: 'John', role: 'admin'};
+  // сохранение данных в state
+  ctx.state.user = user;
+});
+
+router.defineRoute({
+  method: HttpMethod.GET,
+  path: '/profile',
+  handler(ctx) {
+    // доступ к данным, установленным в хуке
+    const user = ctx.state.user;
+    return `Hello, ${user.name}!`;
+  },
+});
+```
+
 ## Отладка
 ## Отладка
 
 
 Установка переменной `DEBUG` включает вывод логов.
 Установка переменной `DEBUG` включает вывод логов.

+ 6 - 0
dist/cjs/index.cjs

@@ -1454,6 +1454,12 @@ var _RequestContext = class _RequestContext {
    * @type {*}
    * @type {*}
    */
    */
   body;
   body;
+  /**
+   * State.
+   *
+   * @type {object}
+   */
+  state = {};
   /**
   /**
    * Route meta.
    * Route meta.
    *
    *

+ 5 - 0
src/request-context.d.ts

@@ -60,6 +60,11 @@ export declare class RequestContext {
    */
    */
   body: unknown;
   body: unknown;
 
 
+  /**
+   * State.
+   */
+  state: Record<string, any>;
+
   /**
   /**
    * Route meta.
    * Route meta.
    */
    */

+ 7 - 0
src/request-context.js

@@ -111,6 +111,13 @@ export class RequestContext {
    */
    */
   body;
   body;
 
 
+  /**
+   * State.
+   *
+   * @type {object}
+   */
+  state = {};
+
   /**
   /**
    * Route meta.
    * Route meta.
    *
    *

+ 11 - 0
src/request-context.spec.js

@@ -166,4 +166,15 @@ describe('RequestContext', function () {
       expect(ctx.pathname).to.be.eq('/overridden');
       expect(ctx.pathname).to.be.eq('/overridden');
     });
     });
   });
   });
+
+  describe('state', function () {
+    it('has an empty object by default', function () {
+      const req = createRequestMock({path: '/pathname'});
+      const res = createResponseMock();
+      const route = createRouteMock();
+      const cont = new ServiceContainer();
+      const ctx = new RequestContext(cont, req, res, route);
+      expect(ctx.state).to.be.eql({});
+    });
+  });
 });
 });