@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
package/ai/rules.md ADDED
@@ -0,0 +1,41 @@
1
+ # Usage Rules
2
+
3
+ ## Structural Rules
4
+
5
+ - The Pipeline Engine is the only request-lifecycle coordinator.
6
+ - Request processing always uses the fixed stage sequence `INIT -> PROCESS -> FINALIZE`.
7
+ - Handlers are registered during setup and must not be added, removed, or reordered after startup.
8
+ - Handler ordering is declarative and derived from `name`, `before`, and `after`.
9
+
10
+ ## Completion Rules
11
+
12
+ - Request completion is a monotonic flag for one request.
13
+ - Only `PROCESS` handlers may call `context.complete()` or set completion to `true`.
14
+ - `INIT` and `FINALIZE` handlers must never mark the request completed.
15
+ - Completion cannot be reset once set.
16
+
17
+ ## Response Rules
18
+
19
+ - Exactly one terminal HTTP response must result from each request.
20
+ - If no `PROCESS` handler completes the request and the response is still writable, the Pipeline Engine returns `404 Not Found`.
21
+ - If a `PROCESS` handler throws and the response is still writable, the Pipeline Engine returns `500 Internal Server Error` and stops further PROCESS handlers.
22
+ - Exceptions in `INIT` and `FINALIZE` handlers are isolated and do not abort the pipeline.
23
+
24
+ ## Transport Boundary
25
+
26
+ - Handlers work on request context and response specification only.
27
+ - Handlers must not perform transport-level transmission or socket management.
28
+ - Actual network response transmission belongs to the built-in `Server` or to the external transport framework that called the Pipeline Engine.
29
+
30
+ ## Environment Assumptions
31
+
32
+ - Runtime is Node.js 20 or newer.
33
+ - The package is intended for long-running server processes.
34
+ - Process supervision, restart, scaling, reverse proxying, and load balancing are external concerns.
35
+ - Multiple instances may run concurrently, but they are independent and must not rely on shared in-memory state.
36
+
37
+ ## DI Usage Rules
38
+
39
+ - The package is designed for `@teqfw/di`.
40
+ - Consumer code should resolve package modules through the `Fl32_Web_` namespace mapped to the package `src/` path.
41
+ - Treat helper internals under deep implementation paths as non-essential unless the task specifically requires them. Preferred consumer entry points are the Pipeline Engine, Server, handler API, DTO factories, enums, and built-in handlers.
package/package.json CHANGED
@@ -1,57 +1,63 @@
1
1
  {
2
2
  "name": "@flancer32/teq-web",
3
- "version": "0.4.0",
4
- "description": "Node.js web plugin supporting Express and Fastify integration, with built-in server for standalone operation",
3
+ "version": "0.5.0",
4
+ "description": "Server-side web request coordination infrastructure for TeqFW modular monolith applications.",
5
5
  "type": "module",
6
- "types": "types.d.ts",
7
- "keywords": [
8
- "es6+",
9
- "teqfw",
10
- "tequila framework",
11
- "web applications"
12
- ],
13
- "homepage": "https://github.com/flancer32/teq-web#readme",
14
- "bugs": {
15
- "url": "https://github.com/flancer32/teq-web/issues"
16
- },
17
6
  "license": "Apache-2.0",
18
7
  "author": {
19
8
  "name": "Alex Gusev",
20
9
  "email": "alex@flancer64.com",
21
10
  "url": "https://github.com/flancer64"
22
11
  },
23
- "files": [
24
- "src/",
25
- "CHANGELOG.md",
26
- "LICENSE",
27
- "README.md",
28
- "teqfw.json",
29
- "types.d.ts"
30
- ],
31
12
  "repository": {
32
13
  "type": "git",
33
14
  "url": "git+https://github.com/flancer32/teq-web.git"
34
15
  },
35
- "scripts": {
36
- "eslint": "./node_modules/.bin/eslint ./src/",
37
- "test:accept": "node --test $(find ./test/accept -name '*.test.mjs')",
38
- "test:unit": "node --test $(find ./test/unit -name '*.test.mjs')"
16
+ "homepage": "https://github.com/flancer32/teq-web",
17
+ "bugs": {
18
+ "url": "https://github.com/flancer32/teq-web/issues"
19
+ },
20
+ "keywords": [
21
+ "teqfw",
22
+ "tequila-framework",
23
+ "web",
24
+ "dispatcher",
25
+ "request-pipeline",
26
+ "dependency-injection",
27
+ "modular-monolith",
28
+ "nodejs"
29
+ ],
30
+ "types": "types.d.ts",
31
+ "engines": {
32
+ "node": ">=20"
33
+ },
34
+ "teqfw": {
35
+ "namespaces": [
36
+ {
37
+ "prefix": "Fl32_Web_",
38
+ "path": "./src",
39
+ "ext": ".mjs"
40
+ }
41
+ ]
39
42
  },
40
43
  "dependencies": {
41
- "@teqfw/di": "^1.1.3"
44
+ "@teqfw/di": "^2.0.4"
42
45
  },
43
46
  "devDependencies": {
44
- "@eslint/js": "^9.25.0",
45
- "eslint": "^9.25.0",
46
- "eslint-plugin-jsdoc": "^50.6.8",
47
- "express": "^4.18.2",
48
- "fastify": "^4.27.2"
47
+ "@types/node": "^25.4.0",
48
+ "eslint": "^10.0.3"
49
49
  },
50
- "engines": {
51
- "node": ">=20"
50
+ "scripts": {
51
+ "test:unit": "find test/unit -name '*.test.mjs' -print0 | xargs -0 node --test",
52
+ "test:integration": "find test/integration -name '*.test.mjs' -print0 | xargs -0 node --test",
53
+ "test": "npm run test:unit && npm run test:integration"
52
54
  },
53
- "funding": {
54
- "type": "individual",
55
- "url": "https://github.com/sponsors/teqfw"
56
- }
55
+ "files": [
56
+ "ai/",
57
+ "src/",
58
+ "CHANGELOG.md",
59
+ "LICENSE",
60
+ "README.md",
61
+ "types.d.ts"
62
+ ]
57
63
  }
@@ -0,0 +1,26 @@
1
+ // @ts-check
2
+
3
+ /**
4
+ * Interface for web request handlers used by the Pipeline Engine.
5
+ *
6
+ * @interface
7
+ */
8
+ export default class Fl32_Web_Back_Api_Handler {
9
+ /* eslint-disable no-unused-vars */
10
+ /**
11
+ * Handles one request context in a pipeline stage.
12
+ * @param {Fl32_Web_Back_PipelineEngine_RequestContext} context
13
+ * @returns {Promise<void>}
14
+ */
15
+ async handle(context) {
16
+ throw new Error('Method not implemented');
17
+ }
18
+
19
+ /**
20
+ * Provides metadata for pipeline registration.
21
+ * @returns {Fl32_Web_Back_Dto_Info}
22
+ */
23
+ getRegistrationInfo() {
24
+ throw new Error('Method not implemented');
25
+ }
26
+ }
@@ -1,6 +1,11 @@
1
+ // @ts-check
2
+
1
3
  /**
2
4
  * Plugin constants (hardcoded configuration) for backend code.
3
5
  */
4
6
  export default class Fl32_Web_Back_Defaults {
5
- PORT = 3000;
7
+ constructor() {
8
+ this.PORT = 3000;
9
+ Object.freeze(this);
10
+ }
6
11
  }
@@ -0,0 +1,66 @@
1
+ // @ts-check
2
+
3
+ export const __deps__ = Object.freeze({
4
+ cast: 'Fl32_Web_Back_Helper_Cast$',
5
+ STAGE: 'Fl32_Web_Back_Enum_Stage$',
6
+ });
7
+
8
+ /**
9
+ * @typedef {object} Fl32_Web_Back_Dto_InfoFactoryParams
10
+ * @property {Fl32_Web_Back_Helper_Cast} cast
11
+ * @property {Fl32_Web_Back_Enum_Stage} STAGE
12
+ */
13
+
14
+ export default class Fl32_Web_Back_Dto_Info {
15
+ /**
16
+ * Handlers to run before this one.
17
+ * @type {string[]}
18
+ */
19
+ after = [];
20
+
21
+ /**
22
+ * Handlers to run after this one.
23
+ * @type {string[]}
24
+ */
25
+ before = [];
26
+
27
+ /**
28
+ * Unique handler name for ordering.
29
+ * @type {string|undefined}
30
+ */
31
+ name;
32
+
33
+ /**
34
+ * Execution stage: `INIT`, `PROCESS`, or `FINALIZE`.
35
+ * @type {string|undefined}
36
+ * @see Fl32_Web_Back_Enum_Stage
37
+ */
38
+ stage;
39
+ }
40
+
41
+ export class Factory {
42
+ /* eslint-disable jsdoc/require-param-description,jsdoc/check-param-names */
43
+ /**
44
+ * @param {Fl32_Web_Back_Dto_InfoFactoryParams} params
45
+ */
46
+ constructor(
47
+ {
48
+ cast,
49
+ STAGE,
50
+ }
51
+ ) {
52
+ /* eslint-enable jsdoc/check-param-names */
53
+ /**
54
+ * @param {*} [data]
55
+ * @returns {Fl32_Web_Back_Dto_Info}
56
+ */
57
+ this.create = function (data) {
58
+ const res = new Fl32_Web_Back_Dto_Info();
59
+ res.after = cast.array(data?.after, cast.string);
60
+ res.before = cast.array(data?.before, cast.string);
61
+ res.name = cast.string(data?.name);
62
+ res.stage = cast.enum(data?.stage, STAGE, {upper: true});
63
+ return Object.freeze(res);
64
+ };
65
+ }
66
+ }
@@ -1,46 +1,49 @@
1
+ // @ts-check
2
+
3
+ export const __deps__ = Object.freeze({
4
+ cast: 'Fl32_Web_Back_Helper_Cast$',
5
+ });
6
+
1
7
  /**
2
- * Factory for file source configuration DTO used by Static handler.
8
+ * @typedef {object} Fl32_Web_Back_Dto_SourceFactoryParams
9
+ * @property {Fl32_Web_Back_Helper_Cast} cast
3
10
  */
4
- export default class Fl32_Web_Back_Dto_Handler_Source {
11
+
12
+ export default class Fl32_Web_Back_Dto_Source {
13
+ /** @type {string} */
14
+ root;
15
+ /** @type {string} */
16
+ prefix;
17
+ /** @type {{[key: string]: string[]}} */
18
+ allow = {};
19
+ /** @type {string[]} */
20
+ defaults = [];
21
+ }
22
+
23
+ export class Factory {
5
24
  /* eslint-disable jsdoc/require-param-description */
6
25
  /**
7
- * @param {Fl32_Web_Back_Helper_Cast} cast
26
+ * @param {Fl32_Web_Back_Dto_SourceFactoryParams} params
8
27
  */
9
28
  constructor(
10
29
  {
11
- Fl32_Web_Back_Helper_Cast$: cast,
30
+ cast,
12
31
  }
13
32
  ) {
14
33
  /* eslint-enable jsdoc/require-param-description */
15
34
  /**
16
- * Create validated DTO for source configuration.
17
- *
18
35
  * @param {*} [data]
19
- * @returns {Dto}
36
+ * @returns {Fl32_Web_Back_Dto_Source}
20
37
  */
21
38
  this.create = function (data) {
22
- const res = new Dto();
39
+ const res = new Fl32_Web_Back_Dto_Source();
23
40
  if (data) {
24
41
  res.root = cast.string(data.root);
25
42
  res.prefix = cast.string(data.prefix);
26
43
  res.allow = cast.stringArrayMap(data.allow);
27
44
  res.defaults = cast.array(data.defaults, cast.string);
28
45
  }
29
- return res;
46
+ return Object.freeze(res);
30
47
  };
31
48
  }
32
49
  }
33
-
34
- /**
35
- * @memberOf Fl32_Web_Back_Dto_Handler_Source
36
- */
37
- class Dto {
38
- /** @type {string} */
39
- root;
40
- /** @type {string} */
41
- prefix;
42
- /** @type {{[key: string]: string[]}} */
43
- allow = {};
44
- /** @type {string[]} */
45
- defaults = [];
46
- }
@@ -0,0 +1,13 @@
1
+ // @ts-check
2
+
3
+ /**
4
+ * Enum-like DTO for built-in server transport modes.
5
+ */
6
+ export default class Fl32_Web_Back_Enum_Server_Type {
7
+ constructor() {
8
+ this.HTTP2 = 'http2';
9
+ this.HTTP = 'http';
10
+ this.HTTPS = 'https';
11
+ Object.freeze(this);
12
+ }
13
+ }
@@ -0,0 +1,13 @@
1
+ // @ts-check
2
+
3
+ /**
4
+ * Enum-like DTO for web request processing stages.
5
+ */
6
+ export default class Fl32_Web_Back_Enum_Stage {
7
+ constructor() {
8
+ this.INIT = 'INIT';
9
+ this.PROCESS = 'PROCESS';
10
+ this.FINALIZE = 'FINALIZE';
11
+ Object.freeze(this);
12
+ }
13
+ }
@@ -0,0 +1,59 @@
1
+ // @ts-check
2
+
3
+ /**
4
+ * Logs basic request information at the beginning of the request lifecycle.
5
+ *
6
+ * @implements Fl32_Web_Back_Api_Handler
7
+ */
8
+ export const __deps__ = Object.freeze({
9
+ logger: 'Fl32_Web_Back_Logger$',
10
+ dtoInfoFactory: 'Fl32_Web_Back_Dto_Info__Factory$',
11
+ STAGE: 'Fl32_Web_Back_Enum_Stage$',
12
+ });
13
+
14
+ /**
15
+ * @typedef {object} Fl32_Web_Back_Handler_Pre_LogConstructorParams
16
+ * @property {Fl32_Web_Back_Logger} logger
17
+ * @property {Fl32_Web_Back_Dto_Info$Factory} dtoInfoFactory
18
+ * @property {Fl32_Web_Back_Enum_Stage} STAGE
19
+ */
20
+
21
+ export default class Fl32_Web_Back_Handler_Pre_Log {
22
+ /* eslint-disable jsdoc/require-param-description,jsdoc/check-param-names */
23
+ /**
24
+ * @param {Fl32_Web_Back_Handler_Pre_LogConstructorParams} params
25
+ */
26
+ constructor(
27
+ {
28
+ logger,
29
+ dtoInfoFactory,
30
+ STAGE,
31
+ }
32
+ ) {
33
+ /* eslint-enable jsdoc/check-param-names */
34
+ // VARS
35
+ const _info = dtoInfoFactory.create({
36
+ name: this.constructor.name,
37
+ stage: STAGE.INIT,
38
+ });
39
+
40
+ // MAIN
41
+
42
+ /**
43
+ * Log request method and URL.
44
+ *
45
+ * @param {Fl32_Web_Back_PipelineEngine_RequestContext} context
46
+ * @returns {Promise<void>}
47
+ */
48
+ this.handle = async function (context) {
49
+ logger.debug(`${context.request.method} ${context.request.url}`);
50
+ };
51
+
52
+ /**
53
+ * Return handler registration info.
54
+ *
55
+ * @returns {Fl32_Web_Back_Dto_Info}
56
+ */
57
+ this.getRegistrationInfo = () => _info;
58
+ }
59
+ }
@@ -1,12 +1,23 @@
1
+ // @ts-check
2
+
3
+ export const __deps__ = Object.freeze({
4
+ path: 'node_path',
5
+ });
6
+
7
+ /**
8
+ * @typedef {object} Fl32_Web_Back_Handler_Static_A_ConfigConstructorParams
9
+ * @property {typeof import('node:path')} path
10
+ */
11
+
1
12
  export default class Fl32_Web_Back_Handler_Static_A_Config {
2
13
  static DEFAULT_FILES = ['index.html', 'index.htm', 'index.txt'];
3
14
  /* eslint-disable jsdoc/require-param-description,jsdoc/check-param-names */
4
15
  /**
5
- * @param {typeof import('node:path')} path
16
+ * @param {Fl32_Web_Back_Handler_Static_A_ConfigConstructorParams} params
6
17
  */
7
18
  constructor(
8
19
  {
9
- 'node:path': path,
20
+ path,
10
21
  }
11
22
  ) {
12
23
  /* eslint-enable jsdoc/check-param-names */
@@ -14,7 +25,7 @@ export default class Fl32_Web_Back_Handler_Static_A_Config {
14
25
  /**
15
26
  * Normalize DTO fields into configuration object.
16
27
  *
17
- * @param {Fl32_Web_Back_Dto_Handler_Source.Dto} dto
28
+ * @param {Fl32_Web_Back_Dto_Source} dto
18
29
  * @returns {{root:string,prefix:string,allow?:Record<string,string[]>,defaults:string[]}}
19
30
  * @throws {Error} When required fields are missing or invalid.
20
31
  */
@@ -1,13 +1,25 @@
1
+ // @ts-check
2
+
3
+ export const __deps__ = Object.freeze({
4
+ fs: 'node_fs',
5
+ path: 'node_path',
6
+ });
7
+
8
+ /**
9
+ * @typedef {object} Fl32_Web_Back_Handler_Static_A_FallbackConstructorParams
10
+ * @property {typeof import('node:fs')} fs
11
+ * @property {typeof import('node:path')} path
12
+ */
13
+
1
14
  export default class Fl32_Web_Back_Handler_Static_A_Fallback {
2
15
  /* eslint-disable jsdoc/require-param-description,jsdoc/check-param-names */
3
16
  /**
4
- * @param {typeof import('node:fs')} fs
5
- * @param {typeof import('node:path')} path
17
+ * @param {Fl32_Web_Back_Handler_Static_A_FallbackConstructorParams} params
6
18
  */
7
19
  constructor(
8
20
  {
9
- 'node:fs': fs,
10
- 'node:path': path,
21
+ fs,
22
+ path,
11
23
  }
12
24
  ) {
13
25
  /* eslint-enable jsdoc/check-param-names */
@@ -1,23 +1,40 @@
1
+ // @ts-check
2
+
3
+ export const __deps__ = Object.freeze({
4
+ fs: 'node_fs',
5
+ http2: 'node_http2',
6
+ path: 'node_path',
7
+ logger: 'Fl32_Web_Back_Logger$',
8
+ helpMime: 'Fl32_Web_Back_Helper_Mime$',
9
+ resolver: 'Fl32_Web_Back_Handler_Static_A_Resolver$',
10
+ fallback: 'Fl32_Web_Back_Handler_Static_A_Fallback$',
11
+ });
12
+
13
+ /**
14
+ * @typedef {object} Fl32_Web_Back_Handler_Static_A_FileServiceConstructorParams
15
+ * @property {typeof import('node:fs')} fs
16
+ * @property {typeof import('node:http2')} http2
17
+ * @property {typeof import('node:path')} path
18
+ * @property {Fl32_Web_Back_Logger} logger
19
+ * @property {Fl32_Web_Back_Helper_Mime} helpMime
20
+ * @property {Fl32_Web_Back_Handler_Static_A_Resolver} resolver
21
+ * @property {Fl32_Web_Back_Handler_Static_A_Fallback} fallback
22
+ */
23
+
1
24
  export default class Fl32_Web_Back_Handler_Static_A_FileService {
2
25
  /* eslint-disable jsdoc/require-param-description,jsdoc/check-param-names */
3
26
  /**
4
- * @param {typeof import('node:fs')} fs
5
- * @param {typeof import('node:http2')} http2
6
- * @param {typeof import('node:path')} path
7
- * @param {Fl32_Web_Back_Logger} logger
8
- * @param {Fl32_Web_Back_Helper_Mime} helpMime
9
- * @param {Fl32_Web_Back_Handler_Static_A_Resolver} resolver
10
- * @param {Fl32_Web_Back_Handler_Static_A_Fallback} fallback
27
+ * @param {Fl32_Web_Back_Handler_Static_A_FileServiceConstructorParams} params
11
28
  */
12
29
  constructor(
13
30
  {
14
- 'node:fs': fs,
15
- 'node:http2': http2,
16
- 'node:path': path,
17
- Fl32_Web_Back_Logger$: logger,
18
- Fl32_Web_Back_Helper_Mime$: helpMime,
19
- Fl32_Web_Back_Handler_Static_A_Resolver$: resolver,
20
- Fl32_Web_Back_Handler_Static_A_Fallback$: fallback,
31
+ fs,
32
+ http2,
33
+ path,
34
+ logger,
35
+ helpMime,
36
+ resolver,
37
+ fallback,
21
38
  }
22
39
  ) {
23
40
  /* eslint-enable jsdoc/check-param-names */
@@ -1,24 +1,36 @@
1
+ // @ts-check
2
+
3
+ export const __deps__ = Object.freeze({
4
+ configFactory: 'Fl32_Web_Back_Handler_Static_A_Config$',
5
+ logger: 'Fl32_Web_Back_Logger$',
6
+ });
7
+
8
+ /**
9
+ * @typedef {object} Fl32_Web_Back_Handler_Static_A_RegistryConstructorParams
10
+ * @property {Fl32_Web_Back_Handler_Static_A_Config} configFactory
11
+ * @property {Fl32_Web_Back_Logger} logger
12
+ */
13
+
1
14
  export default class Fl32_Web_Back_Handler_Static_A_Registry {
2
15
  /* eslint-disable jsdoc/require-param-description,jsdoc/check-param-names */
3
16
  /**
4
- * @param {Fl32_Web_Back_Handler_Static_A_Config} configFactory
5
- * @param {Fl32_Web_Back_Logger} logger
17
+ * @param {Fl32_Web_Back_Handler_Static_A_RegistryConstructorParams} params
6
18
  */
7
19
  constructor(
8
20
  {
9
- Fl32_Web_Back_Handler_Static_A_Config$: configFactory,
10
- Fl32_Web_Back_Logger$: logger,
21
+ configFactory,
22
+ logger,
11
23
  }
12
24
  ) {
13
25
  /* eslint-enable jsdoc/check-param-names */
14
- /** @type {Fl32_Web_Back_Dto_Handler_Source.Dto[]} */
26
+ /** @type {Fl32_Web_Back_Dto_Source[]} */
15
27
  let _configs = [];
16
28
 
17
29
  /**
18
30
  * Add configurations ensuring unique prefixes.
19
31
  * Existing entries are not modified.
20
32
  *
21
- * @param {Fl32_Web_Back_Dto_Handler_Source.Dto[]} dtoList
33
+ * @param {Fl32_Web_Back_Dto_Source[]} dtoList
22
34
  */
23
35
  this.addConfigs = function (dtoList = []) {
24
36
  const list = dtoList.map(dto => configFactory.create(dto));
@@ -1,12 +1,23 @@
1
+ // @ts-check
2
+
1
3
  /**
2
4
  * Enforces allow‐list rules and security checks when resolving
3
5
  * a relative URL to an absolute filesystem path under a given root.
4
6
  */
7
+ export const __deps__ = Object.freeze({
8
+ path: 'node_path',
9
+ });
10
+
11
+ /**
12
+ * @typedef {object} Fl32_Web_Back_Handler_Static_A_ResolverConstructorParams
13
+ * @property {typeof import('node:path')} path
14
+ */
15
+
5
16
  export default class Fl32_Web_Back_Handler_Static_A_Resolver {
6
17
  /**
7
- * @param {typeof import('node:path')} path
18
+ * @param {Fl32_Web_Back_Handler_Static_A_ResolverConstructorParams} params
8
19
  */
9
- constructor({'node:path': path}) {
20
+ constructor({path}) {
10
21
  /**
11
22
  * Resolve a filesystem path for given config and relative URL part.
12
23
  * Applies allow rules and prevents path traversal.