@flancer32/teq-web 0.4.0 → 0.5.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.
Files changed (44) hide show
  1. package/CHANGELOG.md +20 -0
  2. package/README.md +236 -127
  3. package/ai/AGENTS.md +36 -0
  4. package/ai/abstractions.md +75 -0
  5. package/ai/examples/minimal-server.md +78 -0
  6. package/ai/overview.md +27 -0
  7. package/ai/rules.md +41 -0
  8. package/package.json +43 -37
  9. package/src/Back/Api/Handler.mjs +26 -0
  10. package/src/Back/{Defaults.js → Defaults.mjs} +6 -1
  11. package/src/Back/Dto/Info.mjs +66 -0
  12. package/src/Back/Dto/{Handler/Source.js → Source.mjs} +26 -23
  13. package/src/Back/Enum/Server/Type.mjs +13 -0
  14. package/src/Back/Enum/Stage.mjs +13 -0
  15. package/src/Back/Handler/Pre/Log.mjs +59 -0
  16. package/src/Back/Handler/Static/A/{Config.js → Config.mjs} +14 -3
  17. package/src/Back/Handler/Static/A/{Fallback.js → Fallback.mjs} +16 -4
  18. package/src/Back/Handler/Static/A/{FileService.js → FileService.mjs} +31 -14
  19. package/src/Back/Handler/Static/A/{Registry.js → Registry.mjs} +18 -6
  20. package/src/Back/Handler/Static/A/{Resolver.js → Resolver.mjs} +13 -2
  21. package/src/Back/Handler/Static.mjs +83 -0
  22. package/src/Back/Helper/Cast.mjs +116 -0
  23. package/src/Back/Helper/{Mime.js → Mime.mjs} +2 -0
  24. package/src/Back/Helper/Order/Kahn.mjs +69 -0
  25. package/src/Back/Helper/{Respond.js → Respond.mjs} +14 -3
  26. package/src/Back/Logger.mjs +57 -0
  27. package/src/Back/PipelineEngine.mjs +228 -0
  28. package/src/Back/Server/Config/{Tls.js → Tls.mjs} +35 -33
  29. package/src/Back/Server/Config.mjs +69 -0
  30. package/src/Back/{Server.js → Server.mjs} +35 -24
  31. package/types.d.ts +27 -22
  32. package/src/AGENTS.md +0 -108
  33. package/src/Back/Api/Handler.js +0 -26
  34. package/src/Back/Dispatcher.js +0 -115
  35. package/src/Back/Dto/Handler/Info.js +0 -68
  36. package/src/Back/Enum/Server/Type.js +0 -12
  37. package/src/Back/Enum/Stage.js +0 -10
  38. package/src/Back/Handler/Pre/Log.js +0 -45
  39. package/src/Back/Handler/Static.js +0 -63
  40. package/src/Back/Helper/Cast.js +0 -114
  41. package/src/Back/Helper/Order/Kahn.js +0 -66
  42. package/src/Back/Logger.js +0 -53
  43. package/src/Back/Server/Config.js +0 -69
  44. package/teqfw.json +0 -8
@@ -0,0 +1,69 @@
1
+ // @ts-check
2
+
3
+ export const __deps__ = Object.freeze({
4
+ cast: 'Fl32_Web_Back_Helper_Cast$',
5
+ SERVER_TYPE: 'Fl32_Web_Back_Enum_Server_Type$',
6
+ tlsFactory: 'Fl32_Web_Back_Server_Config_Tls__Factory$',
7
+ });
8
+
9
+ /**
10
+ * @typedef {object} Fl32_Web_Back_Server_ConfigFactoryParams
11
+ * @property {Fl32_Web_Back_Helper_Cast} cast
12
+ * @property {Fl32_Web_Back_Enum_Server_Type} SERVER_TYPE
13
+ * @property {Fl32_Web_Back_Server_Config_Tls$Factory} tlsFactory
14
+ */
15
+
16
+ export default class Fl32_Web_Back_Server_Config {
17
+ /**
18
+ * Port to listening (3000).
19
+ *
20
+ * @type {number}
21
+ */
22
+ port;
23
+ /**
24
+ * @type {string}
25
+ * @see Fl32_Web_Back_Enum_Server_Type
26
+ */
27
+ type;
28
+ /**
29
+ * TLS configuration for HTTPS server.
30
+ * @type {Fl32_Web_Back_Server_Config_Tls|undefined}
31
+ */
32
+ tls;
33
+ }
34
+
35
+ export class Factory {
36
+ /* eslint-disable jsdoc/require-param-description,jsdoc/check-param-names */
37
+ /**
38
+ * @param {Fl32_Web_Back_Server_ConfigFactoryParams} params
39
+ */
40
+ constructor(
41
+ {
42
+ cast,
43
+ SERVER_TYPE,
44
+ tlsFactory,
45
+ }
46
+ ) {
47
+ /* eslint-enable jsdoc/require-param-description,jsdoc/check-param-names */
48
+ /**
49
+ * @param {Fl32_Web_Back_Server_Config|object} [data]
50
+ * @returns {Fl32_Web_Back_Server_Config}
51
+ */
52
+ this.create = function (data) {
53
+ const res = new Fl32_Web_Back_Server_Config();
54
+ if (data) {
55
+ res.port = cast.int(data.port);
56
+ res.type = cast.enum(data.type, SERVER_TYPE, {lower: true});
57
+
58
+ if (data.tls) {
59
+ res.tls = tlsFactory.create(data.tls);
60
+ }
61
+
62
+ if (res.type === SERVER_TYPE.HTTPS && !res.tls) {
63
+ throw new Error('TLS configuration is required for HTTPS server type');
64
+ }
65
+ }
66
+ return Object.freeze(res);
67
+ };
68
+ }
69
+ }
@@ -1,35 +1,47 @@
1
+ // @ts-check
2
+
1
3
  /**
2
4
  * Web server implementation supporting HTTP/1 and HTTP/2 protocols.
3
- * Handles incoming requests and delegates them to the dispatcher.
4
- *
5
- * @property {function(): module:http.Server} getInstance - Returns the server instance.
6
- * @property {function(Fl32_Web_Back_Server_Config.Dto): Promise<void>} start - Starts the server with given configuration.
7
- * @property {function(): Promise<void>} stop - Stops the server.
5
+ * Handles incoming requests and delegates them to the Pipeline Engine.
8
6
  */
7
+ export const __deps__ = Object.freeze({
8
+ http: 'node_http',
9
+ http2: 'node_http2',
10
+ DEF: 'Fl32_Web_Back_Defaults$',
11
+ logger: 'Fl32_Web_Back_Logger$',
12
+ pipelineEngine: 'Fl32_Web_Back_PipelineEngine$',
13
+ SERVER_TYPE: 'Fl32_Web_Back_Enum_Server_Type$',
14
+ });
15
+
16
+ /**
17
+ * @typedef {object} Fl32_Web_Back_ServerConstructorParams
18
+ * @property {typeof import('node:http')} http
19
+ * @property {typeof import('node:http2')} http2
20
+ * @property {import('./Defaults.mjs').default} DEF
21
+ * @property {Fl32_Web_Back_Logger} logger
22
+ * @property {Fl32_Web_Back_PipelineEngine} pipelineEngine
23
+ * @property {Fl32_Web_Back_Enum_Server_Type} SERVER_TYPE
24
+ */
25
+
9
26
  export default class Fl32_Web_Back_Server {
10
27
  /* eslint-disable jsdoc/require-param-description,jsdoc/check-param-names */
11
28
  /**
12
- * @param {typeof import('node:http')} http
13
- * @param {typeof import('node:http2')} http2
14
- * @param {Fl32_Web_Back_Defaults} DEF
15
- * @param {Fl32_Web_Back_Logger} logger
16
- * @param {Fl32_Web_Back_Dispatcher} dispatcher
17
- * @param {typeof Fl32_Web_Back_Enum_Server_Type} SERVER_TYPE
29
+ * @param {Fl32_Web_Back_ServerConstructorParams} deps
18
30
  */
19
31
  constructor(
20
32
  {
21
- 'node:http': http,
22
- 'node:http2': http2,
23
- Fl32_Web_Back_Defaults$: DEF,
24
- Fl32_Web_Back_Logger$: logger,
25
- Fl32_Web_Back_Dispatcher$: dispatcher,
26
- Fl32_Web_Back_Enum_Server_Type$: SERVER_TYPE,
33
+ http,
34
+ http2,
35
+ DEF,
36
+ logger,
37
+ pipelineEngine,
38
+ SERVER_TYPE,
27
39
  }
28
40
  ) {
29
41
  /* eslint-enable jsdoc/require-param-description,jsdoc/check-param-names */
30
42
  // VARS
31
- const {createServer} = http;
32
- const {createServer: createServerH2, createSecureServer} = http2;
43
+ const { createServer } = http;
44
+ const { createServer: createServerH2, createSecureServer } = http2;
33
45
  /** @type {module:http.Server} */
34
46
  let _instance;
35
47
 
@@ -41,12 +53,11 @@ export default class Fl32_Web_Back_Server {
41
53
 
42
54
  /**
43
55
  * Starts the server with optional configuration.
44
- * @param {Fl32_Web_Back_Server_Config.Dto} [cfg] - Server configuration
56
+ * @param {Fl32_Web_Back_Server_Config} [cfg]
45
57
  * @returns {Promise<void>}
46
58
  */
47
59
  this.start = async function (cfg) {
48
- // order handlers in the dispatcher
49
- dispatcher.orderHandlers();
60
+ pipelineEngine.lockHandlers();
50
61
  // create server
51
62
  const port = cfg?.port ?? DEF.PORT;
52
63
  const type = cfg?.type ?? SERVER_TYPE.HTTP;
@@ -69,7 +80,7 @@ export default class Fl32_Web_Back_Server {
69
80
  throw new Error(`Server type '${type}' is not supported`);
70
81
  }
71
82
 
72
- _instance.on('request', dispatcher.onEventRequest);
83
+ _instance.on('request', pipelineEngine.handleRequest);
73
84
  _instance.listen(port);
74
85
  };
75
86
 
@@ -89,4 +100,4 @@ export default class Fl32_Web_Back_Server {
89
100
  }
90
101
  };
91
102
  }
92
- }
103
+ }
package/types.d.ts CHANGED
@@ -1,25 +1,30 @@
1
1
  declare global {
2
- type Fl32_Web_Back_Api_Handler = import("./src/Back/Api/Handler.js").default;
3
- type Fl32_Web_Back_Defaults = import("./src/Back/Defaults.js").default;
4
- type Fl32_Web_Back_Dispatcher = import("./src/Back/Dispatcher.js").default;
5
- type Fl32_Web_Back_Dto_Handler_Info = import("./src/Back/Dto/Handler/Info.js").default;
6
- type Fl32_Web_Back_Dto_Handler_Source = import("./src/Back/Dto/Handler/Source.js").default;
7
- type Fl32_Web_Back_Enum_Server_Type = import("./src/Back/Enum/Server/Type.js").default;
8
- type Fl32_Web_Back_Enum_Stage = import("./src/Back/Enum/Stage.js").default;
9
- type Fl32_Web_Back_Handler_Pre_Log = import("./src/Back/Handler/Pre/Log.js").default;
10
- type Fl32_Web_Back_Handler_Static = import("./src/Back/Handler/Static.js").default;
11
- type Fl32_Web_Back_Handler_Static_A_Config = import("./src/Back/Handler/Static/A/Config.js").default;
12
- type Fl32_Web_Back_Handler_Static_A_Fallback = import("./src/Back/Handler/Static/A/Fallback.js").default;
13
- type Fl32_Web_Back_Handler_Static_A_FileService = import("./src/Back/Handler/Static/A/FileService.js").default;
14
- type Fl32_Web_Back_Handler_Static_A_Registry = import("./src/Back/Handler/Static/A/Registry.js").default;
15
- type Fl32_Web_Back_Handler_Static_A_Resolver = import("./src/Back/Handler/Static/A/Resolver.js").default;
16
- type Fl32_Web_Back_Helper_Cast = import("./src/Back/Helper/Cast.js").default;
17
- type Fl32_Web_Back_Helper_Mime = import("./src/Back/Helper/Mime.js").default;
18
- type Fl32_Web_Back_Helper_Order_Kahn = import("./src/Back/Helper/Order/Kahn.js").default;
19
- type Fl32_Web_Back_Helper_Respond = import("./src/Back/Helper/Respond.js").default;
20
- type Fl32_Web_Back_Logger = import("./src/Back/Logger.js").default;
21
- type Fl32_Web_Back_Server = import("./src/Back/Server.js").default;
22
- type Fl32_Web_Back_Server_Config = import("./src/Back/Server/Config.js").default;
23
- type Fl32_Web_Back_Server_Config_Tls = import("./src/Back/Server/Config/Tls.js").default;
2
+ type Fl32_Web_Back_Api_Handler = import("./src/Back/Api/Handler.mjs").default;
3
+ type Fl32_Web_Back_Defaults = import("./src/Back/Defaults.mjs").default;
4
+ type Fl32_Web_Back_Dto_Info = import("./src/Back/Dto/Info.mjs").default;
5
+ type Fl32_Web_Back_Dto_Info$Factory = import("./src/Back/Dto/Info.mjs").Factory;
6
+ type Fl32_Web_Back_Dto_Source = import("./src/Back/Dto/Source.mjs").default;
7
+ type Fl32_Web_Back_Dto_Source$Factory = import("./src/Back/Dto/Source.mjs").Factory;
8
+ type Fl32_Web_Back_Enum_Server_Type = import("./src/Back/Enum/Server/Type.mjs").default;
9
+ type Fl32_Web_Back_Enum_Stage = import("./src/Back/Enum/Stage.mjs").default;
10
+ type Fl32_Web_Back_Handler_Pre_Log = import("./src/Back/Handler/Pre/Log.mjs").default;
11
+ type Fl32_Web_Back_Handler_Static = import("./src/Back/Handler/Static.mjs").default;
12
+ type Fl32_Web_Back_Handler_Static_A_Config = import("./src/Back/Handler/Static/A/Config.mjs").default;
13
+ type Fl32_Web_Back_Handler_Static_A_Fallback = import("./src/Back/Handler/Static/A/Fallback.mjs").default;
14
+ type Fl32_Web_Back_Handler_Static_A_FileService = import("./src/Back/Handler/Static/A/FileService.mjs").default;
15
+ type Fl32_Web_Back_Handler_Static_A_Registry = import("./src/Back/Handler/Static/A/Registry.mjs").default;
16
+ type Fl32_Web_Back_Handler_Static_A_Resolver = import("./src/Back/Handler/Static/A/Resolver.mjs").default;
17
+ type Fl32_Web_Back_Helper_Cast = import("./src/Back/Helper/Cast.mjs").default;
18
+ type Fl32_Web_Back_Helper_Mime = import("./src/Back/Helper/Mime.mjs").default;
19
+ type Fl32_Web_Back_Helper_Order_Kahn = import("./src/Back/Helper/Order/Kahn.mjs").default;
20
+ type Fl32_Web_Back_Helper_Respond = import("./src/Back/Helper/Respond.mjs").default;
21
+ type Fl32_Web_Back_Logger = import("./src/Back/Logger.mjs").default;
22
+ type Fl32_Web_Back_PipelineEngine = import("./src/Back/PipelineEngine.mjs").default;
23
+ type Fl32_Web_Back_Server = import("./src/Back/Server.mjs").default;
24
+ type Fl32_Web_Back_Server_Config = import("./src/Back/Server/Config.mjs").default;
25
+ type Fl32_Web_Back_Server_Config$Factory = import("./src/Back/Server/Config.mjs").Factory;
26
+ type Fl32_Web_Back_Server_Config_Tls = import("./src/Back/Server/Config/Tls.mjs").default;
27
+ type Fl32_Web_Back_Server_Config_Tls$Factory = import("./src/Back/Server/Config/Tls.mjs").Factory;
24
28
  }
29
+
25
30
  export {};
package/src/AGENTS.md DELETED
@@ -1,108 +0,0 @@
1
- # AI Agents Configuration for Source Directory
2
-
3
- This document defines **long-term, project-agnostic** conventions that AI agents must follow when reading, creating, refactoring, or testing code under any `src/` directory. These guidelines are **permanent** and apply to **all** tasks in this area.
4
-
5
- ---
6
-
7
- ## 1. Directory & File Organization
8
-
9
- * **AZ-structuring**
10
-
11
- * **A-struct**: decompose a single “root” module into its private implementation parts under an `A/` subfolder.
12
-
13
- ```text
14
- src/Feature/Component.js
15
- src/Feature/Component/A/Part1.js
16
- src/Feature/Component/A/Part2.js
17
- ```
18
-
19
- Files under `A/` are private to their parent.
20
- * **Z-struct**: helper modules whose changes do not affect siblings live under a `Z/` subfolder.
21
-
22
- * **Visibility boundaries**: anything **outside** `A/` or `Z/` is public API.
23
-
24
- * **Role → Feature layering**
25
-
26
- * First level: by architectural layer (e.g. `Back/`, `Front/`, `Shared/`).
27
- * Second level: by business feature or component.
28
-
29
- * **Mirror in tests**
30
-
31
- * For every `src/.../X.js` there must be a matching `test/unit/.../X.test.mjs` with the same relative path and filename.
32
-
33
- ---
34
-
35
- ## 2. Class Naming (FQN)
36
-
37
- * Map file path to fully qualified class name (FQN). Example:
38
-
39
- ```text
40
- src/Back/Handler/Static/A/Config.js => class Back_Handler_Static_A_Config
41
- ```
42
-
43
- ---
44
-
45
- ## 3. Dependency Injection, `this` & Closures
46
-
47
- * **DI Container**
48
-
49
- * Inject all external services (file system, path, network, helpers, loggers, factories, enums) via a DI container.
50
- * **Private state via closure**
51
-
52
- * Do **not** assign injected dependencies to `this`.
53
- * Capture each in a `const` inside the constructor and expose only public methods.
54
-
55
- ```js
56
- class Example {
57
- constructor({helperService, logger}) {
58
- this.handle = (req, res) => {
59
- if (!helperService.isWritable(res)) return false;
60
- logger.info('Processing');
61
- return true;
62
- };
63
- }
64
- }
65
- ```
66
-
67
- ---
68
-
69
- ## 4. Comments & Annotations
70
-
71
- * **Language**: all comments and JSDoc must be in **English**.
72
- * **JSDoc**: use `@param {Type}` and `@returns {Type}` on every public method.
73
- * **Class annotation**: annotate all classes with a JSDoc `@class` tag and description.
74
-
75
- ---
76
-
77
- ## 5. Error Handling
78
-
79
- * **Module-level**
80
-
81
- * Do **not** catch all exceptions in each module.
82
- * Catch only **expected, domain-specific** errors when a meaningful fallback exists.
83
- * **Top-level handler**
84
-
85
- * Wrap the entire pipeline in a single `try/catch` at the entry point.
86
- * In that catch, use `logger.exception(error)` and return a safe default (`false`, `null`, or `[]`).
87
-
88
- ---
89
-
90
- ## 6. Testing Conventions
91
-
92
- Refer to the [AI Agent Unit Testing Instructions](../test/unit/AGENTS.md) for project-specific testing guidelines.
93
-
94
- ---
95
-
96
- ## 7. Ongoing Responsibilities
97
-
98
- AI agents must always:
99
-
100
- 1. **Enforce AZ-structuring** when adding or refactoring code.
101
- 2. **Preserve FQN mapping** between file paths and class names.
102
- 3. **Use DI + closures**—never attach injected services to `this`.
103
- 4. **Write English JSDoc** for every new or modified public API, including `@class` on all classes.
104
- 5. **Catch and log errors** at the top level; handle known cases locally.
105
- 6. **Generate or update unit tests** with full coverage for every behavior change (see unit testing guidelines).
106
- 7. **Maintain test-source mirror** so no source file exists without a corresponding test.
107
-
108
- These policies are **permanent** and must be validated on every code change.
@@ -1,26 +0,0 @@
1
- /**
2
- * Interface for web request handlers used by the dispatcher in this plugin.
3
- * Defines the structure and behavior of a handler.
4
- *
5
- * @interface
6
- */
7
- export default class Fl32_Web_Back_Api_Handler {
8
- /* eslint-disable no-unused-vars */
9
- /**
10
- * Handles the incoming web request.
11
- * @param {module:http.IncomingMessage|module:http2.Http2ServerRequest} req - The incoming HTTP request object.
12
- * @param {module:http.ServerResponse|module:http2.Http2ServerResponse} res - The HTTP response object.
13
- * @returns {Promise<boolean>} - Returns true if the request was handled, false otherwise.
14
- */
15
- async handle(req, res) {
16
- throw new Error('Method not implemented');
17
- }
18
-
19
- /**
20
- * Provides metadata for dispatcher registration.
21
- * @returns {Fl32_Web_Back_Dto_Handler_Info.Dto}
22
- */
23
- getRegistrationInfo() {
24
- throw new Error('Method not implemented');
25
- }
26
- }
@@ -1,115 +0,0 @@
1
- /**
2
- * Dispatcher for HTTP(S) requests with three-stage handler execution: pre, process, post.
3
- *
4
- * Handlers are registered via `addHandler()` and activated by `orderHandlers()`.
5
- * On each request, pre-handlers run first, then process-handlers (until one returns true),
6
- * and finally post-handlers are always executed.
7
- *
8
- * If no process handler responds, a 404 is sent. If one throws, a 500 is returned.
9
- */
10
- export default class Fl32_Web_Back_Dispatcher {
11
- /* eslint-disable jsdoc/require-param-description,jsdoc/check-param-names */
12
- /**
13
- * @param {Fl32_Web_Back_Logger} logger
14
- * @param {Fl32_Web_Back_Helper_Respond} respond
15
- * @param {Fl32_Web_Back_Helper_Order_Kahn} helpOrder
16
- * @param {typeof Fl32_Web_Back_Enum_Stage} STAGE
17
- */
18
- constructor(
19
- {
20
- Fl32_Web_Back_Logger$: logger,
21
- Fl32_Web_Back_Helper_Respond$: respond,
22
- Fl32_Web_Back_Helper_Order_Kahn$: helpOrder,
23
- Fl32_Web_Back_Enum_Stage$: STAGE,
24
- }
25
- ) {
26
- /* eslint-enable jsdoc/check-param-names */
27
- // VARS
28
- /** @type {Map<string, Fl32_Web_Back_Api_Handler>} */
29
- const _handlers = new Map();
30
-
31
- /** @type {Fl32_Web_Back_Api_Handler[]} */
32
- let _pre = [], _process = [], _post = [];
33
-
34
- // MAIN
35
-
36
- /**
37
- * Registers a handler. Requires a unique name and stage.
38
- *
39
- * @param {Fl32_Web_Back_Api_Handler} handler
40
- */
41
- this.addHandler = function (handler) {
42
- const info = handler.getRegistrationInfo();
43
- _handlers.set(info.name, handler);
44
- };
45
-
46
- /**
47
- * Executes registered handlers for one HTTP request.
48
- *
49
- * @param {module:http.IncomingMessage|module:http2.Http2ServerRequest} req
50
- * @param {module:http.ServerResponse|module:http2.Http2ServerResponse} res
51
- * @returns {Promise<void>}
52
- */
53
- this.onEventRequest = async function (req, res) {
54
- try {
55
- // Execute all pre-handlers (errors are isolated)
56
- for (const h of _pre) {
57
- try {
58
- await h.handle(req, res);
59
- } catch (e) {
60
- logger.exception(e);
61
- }
62
- }
63
-
64
- // Execute process-handlers (stop at first successful)
65
- let handled = false;
66
- for (const h of _process) {
67
- try {
68
- handled = await h.handle(req, res);
69
- if (handled) break;
70
- } catch (e) {
71
- logger.exception(e);
72
- respond.code500_InternalServerError({res, body: e?.message});
73
- break;
74
- }
75
- }
76
-
77
- // If not handled at all and no error occurred
78
- if (respond.isWritable(res)) {
79
- logger.error(`404 Not Found: ${req.url}`);
80
- respond.code404_NotFound({res});
81
- }
82
- } finally {
83
- // Always run all post-handlers (errors are isolated)
84
- for (const h of _post) {
85
- try {
86
- await h.handle(req, res);
87
- } catch (e) {
88
- logger.exception(e);
89
- }
90
- }
91
- }
92
- };
93
-
94
- /**
95
- * Sorts registered handlers by stage.
96
- */
97
- this.orderHandlers = function () {
98
- const pre = [], process = [], post = [];
99
-
100
- for (const handler of _handlers.values()) {
101
- const dto = handler.getRegistrationInfo();
102
- if (dto.stage === STAGE.PRE) {
103
- pre.push(handler);
104
- } else if (dto.stage === STAGE.PROCESS) {
105
- process.push(handler);
106
- } else if (dto.stage === STAGE.POST) post.push(handler);
107
- }
108
-
109
- _pre = helpOrder.sort(pre);
110
- _process = helpOrder.sort(process);
111
- _post = helpOrder.sort(post);
112
- };
113
- }
114
-
115
- }
@@ -1,68 +0,0 @@
1
- /**
2
- * Factory for dispatcher handler registration metadata.
3
- *
4
- * Produces validated DTOs for registering web request handlers.
5
- *
6
- * @see TeqFw_Core_Shared_Api_Factory
7
- */
8
- export default class Fl32_Web_Back_Dto_Handler_Info {
9
- /* eslint-disable jsdoc/require-param-description,jsdoc/check-param-names */
10
- /**
11
- * @param {Fl32_Web_Back_Helper_Cast} cast
12
- * @param {typeof Fl32_Web_Back_Enum_Stage} STAGE
13
- */
14
- constructor(
15
- {
16
- Fl32_Web_Back_Helper_Cast$: cast,
17
- Fl32_Web_Back_Enum_Stage$: STAGE,
18
- }
19
- ) {
20
- /* eslint-enable jsdoc/check-param-names */
21
- /**
22
- * Create a validated DTO for handler registration.
23
- *
24
- * @param {*} [data] - Optional raw object.
25
- * @returns {Dto}
26
- */
27
- this.create = function (data) {
28
- const res = (data && typeof data === 'object' && !Array.isArray(data))
29
- ? Object.assign(new Dto(), data)
30
- : new Dto();
31
- res.after = cast.array(data?.after, cast.string);
32
- res.before = cast.array(data?.before, cast.string);
33
- res.name = cast.string(data?.name);
34
- res.stage = cast.enum(data?.stage, STAGE, {lower: true});
35
- return res;
36
- };
37
- }
38
- }
39
-
40
- /**
41
- * @memberOf Fl32_Web_Back_Dto_Handler_Info
42
- */
43
- class Dto {
44
- /**
45
- * Handlers to run before this one.
46
- * @type {string[]}
47
- */
48
- after;
49
-
50
- /**
51
- * Handlers to run after this one.
52
- * @type {string[]}
53
- */
54
- before;
55
-
56
- /**
57
- * Unique handler name for ordering.
58
- * @type {string}
59
- */
60
- name;
61
-
62
- /**
63
- * Execution stage: 'pre', 'process', or 'post'.
64
- * @type {string}
65
- * @see Fl32_Web_Back_Enum_Stage
66
- */
67
- stage;
68
- }
@@ -1,12 +0,0 @@
1
- /**
2
- * Enum for server types used to configure built-in web server.
3
- * - 'http': HTTP/1.1
4
- * - 'http2': HTTP/2 without TLS (cleartext)
5
- * - 'https': HTTP/2 over TLS (via http2.createSecureServer)
6
- */
7
- const Fl32_Web_Back_Enum_Server_Type = {
8
- HTTP2: 'http2',
9
- HTTP: 'http',
10
- HTTPS: 'https'
11
- };
12
- export default Fl32_Web_Back_Enum_Server_Type;
@@ -1,10 +0,0 @@
1
- /**
2
- * Enum for web request processing stages in this plugin.
3
- * Used to define processing phases in the web dispatcher specific to this plugin.
4
- */
5
- const Fl32_Web_Back_Enum_Stage = {
6
- PRE: 'pre', // Pre-processing stage: initial request handling (e.g., logging, authentication)
7
- PROCESS: 'process', // Main processing stage: routing and core logic
8
- POST: 'post' // Post-processing stage: final actions (e.g., logging response, cleanup)
9
- };
10
- export default Fl32_Web_Back_Enum_Stage;
@@ -1,45 +0,0 @@
1
- /**
2
- * Logs basic request information at the beginning of the request lifecycle.
3
- * @implements Fl32_Web_Back_Api_Handler
4
- */
5
- export default class Fl32_Web_Back_Handler_Pre_Log {
6
- /* eslint-disable jsdoc/require-param-description,jsdoc/check-param-names */
7
- /**
8
- * @param {Fl32_Web_Back_Logger} logger
9
- * @param {Fl32_Web_Back_Dto_Handler_Info} dtoInfo
10
- * @param {typeof Fl32_Web_Back_Enum_Stage} STAGE
11
- */
12
- constructor(
13
- {
14
- Fl32_Web_Back_Logger$: logger,
15
- Fl32_Web_Back_Dto_Handler_Info$: dtoInfo,
16
- Fl32_Web_Back_Enum_Stage$: STAGE,
17
- }
18
- ) {
19
- /* eslint-enable jsdoc/check-param-names */
20
- // VARS
21
- const _info = dtoInfo.create();
22
- _info.name = this.constructor.name;
23
- _info.stage = STAGE.PRE;
24
- Object.freeze(_info);
25
-
26
- // MAIN
27
-
28
- /**
29
- * Log request method and URL.
30
- *
31
- * @param {module:http.IncomingMessage|module:http2.Http2ServerRequest} req
32
- * @returns {Promise<void>}
33
- */
34
- this.handle = async function (req) {
35
- logger.debug(`${req.method} ${req.url}`);
36
- };
37
-
38
- /**
39
- * Return handler registration info.
40
- *
41
- * @returns {Fl32_Web_Back_Dto_Handler_Info.Dto}
42
- */
43
- this.getRegistrationInfo = () => _info;
44
- }
45
- }
@@ -1,63 +0,0 @@
1
- /**
2
- * Universal file handler serving files from multiple sources using helper modules.
3
- *
4
- * @implements Fl32_Web_Back_Api_Handler
5
- */
6
- export default class Fl32_Web_Back_Handler_Static {
7
- /* eslint-disable jsdoc/require-param-description,jsdoc/check-param-names */
8
- /**
9
- * @param {Fl32_Web_Back_Handler_Static_A_Registry} registry
10
- * @param {Fl32_Web_Back_Handler_Static_A_FileService} fileService
11
- * @param {Fl32_Web_Back_Helper_Respond} respond
12
- * @param {Fl32_Web_Back_Logger} logger
13
- * @param {Fl32_Web_Back_Dto_Handler_Info} dtoInfo
14
- * @param {typeof Fl32_Web_Back_Enum_Stage} STAGE
15
- */
16
- constructor(
17
- {
18
- Fl32_Web_Back_Handler_Static_A_Registry$: registry,
19
- Fl32_Web_Back_Handler_Static_A_FileService$: fileService,
20
- Fl32_Web_Back_Helper_Respond$: respond,
21
- Fl32_Web_Back_Logger$: logger,
22
- Fl32_Web_Back_Dto_Handler_Info$: dtoInfo,
23
- Fl32_Web_Back_Enum_Stage$: STAGE,
24
- }
25
- ) {
26
- /* eslint-enable jsdoc/check-param-names */
27
-
28
- const _info = dtoInfo.create();
29
- _info.name = this.constructor.name;
30
- _info.stage = STAGE.PROCESS;
31
- Object.freeze(_info);
32
-
33
- /**
34
- * Initialize registry with provided sources.
35
- *
36
- * @param {{sources: Fl32_Web_Back_Dto_Handler_Source.Dto[]}} params
37
- * @returns {Promise<void>}
38
- */
39
- this.init = async ({sources = []} = {}) => {
40
- registry.addConfigs(sources);
41
- };
42
-
43
- /**
44
- * Attempt to handle incoming request.
45
- *
46
- * @param {module:http.IncomingMessage|module:http2.Http2ServerRequest} req
47
- * @param {module:http.ServerResponse|module:http2.Http2ServerResponse} res
48
- * @returns {Promise<boolean>} True if file served
49
- */
50
- this.handle = async (req, res) => {
51
- if (!respond.isWritable(res)) return false;
52
- const urlPath = decodeURIComponent(req.url.split('?')[0]);
53
- const match = registry.find(urlPath);
54
- if (!match) return false;
55
- return fileService.serve(match.config, match.rel, req, res);
56
- };
57
-
58
- /**
59
- * @returns {Fl32_Web_Back_Dto_Handler_Info.Dto}
60
- */
61
- this.getRegistrationInfo = () => _info;
62
- }
63
- }