]> Piment Noir Git Repositories - e-mobility-charging-stations-simulator.git/commit
refactor: complete barrel-gap scope — extract host-parsing utilities and expose Abstr...
authorJérôme Benoit <jerome.benoit@piment-noir.org>
Sun, 5 Jul 2026 20:21:38 +0000 (22:21 +0200)
committerGitHub <noreply@github.com>
Sun, 5 Jul 2026 20:21:38 +0000 (22:21 +0200)
commitdaad8a9d812aa4484ebdb5e50d0ec09daa6fbf3c
tree3c0f6485d9030faf3f48af3c5be20738e288590e
parentb4b5a5eb6e670106eaf6f82c851e991a68dfef8f
refactor: complete barrel-gap scope — extract host-parsing utilities and expose AbstractUIServer (#1954)

refactor: complete barrel-gap scope — extract host-parsing utilities and expose AbstractUIServer

Complete the scope that #1952 and #1953 left incomplete. Three coupled
concerns addressed atomically to avoid further PR fragmentation:

R1. Extract host-parsing utilities from ui-server internals to
    src/utils/HostUtils.ts:

    The `ui-server/UIServerNet.ts` file previously mixed pure host/IP
    parsing helpers (`LOOPBACK_HOSTNAME`, `isLoopback`,
    `normalizeIPAddress`, `normalizeHost`, `isHostLiteralWithoutPort`)
    with HTTP-header parsing helpers (`splitHeaderList`, `splitQuoted`).
    The host-parsing family is a pure utility, not UI-server-specific,
    and was consumed cross-layer by `src/utils/ConfigurationSchema.ts`
    (a Zod validator) — an inverted dependency (`utils/` importing from
    `charging-station/ui-server/`) that required a workaround comment
    documenting the TDZ (Temporal Dead Zone) cycle risk at
    UIServerNet.ts:3.

    Move the 5 host-parsing exports plus their private helpers
    (`HOSTNAME_PATTERN`, `isValidPort`, `parseIPv4MappedAddress`,
    `expandIPv6`, `isIPv6Group`) to `src/utils/HostUtils.ts`. The
    `ui-server/UIServerNet.ts` file now contains only the HTTP-header
    parsing helpers (`splitHeaderList`, `splitQuoted`) that legitimately
    belong to the ui-server access-policy layer.

    Callers updated:
    - ChargingStation ui-server internals (`AbstractUIServer.ts`,
      `UIServerAccessPolicy.ts`, `UIServerFactory.ts`) now import from
      `../../utils/index.js` (the utils barrel), each in a single
      alphabetically-sorted specifier block merged with the pre-existing
      utils imports from that file (no duplicate import statements).
    - `src/utils/ConfigurationSchema.ts` imports from `./HostUtils.js`
      directly (same directory, avoids barrel TDZ risk).
    - The utils barrel (`src/utils/index.ts`) re-exports the 5 host
      helpers alphabetically.

    Priority-3 anchor comments preserved verbatim in the moved private
    helpers (radix-16 rationale for `Number.parseInt` in
    `parseIPv4MappedAddress` and `expandIPv6`).

R2. Expose AbstractUIServer as a type-only re-export from the
    ui-server barrel:

    Bootstrap.ts holds a `readonly uiServer: AbstractUIServer` field
    without subclassing the abstract base — a legitimate external
    type-reference consumer. Previously deep-imported via
    `./ui-server/AbstractUIServer.js`. Now available through the
    barrel via `export type { AbstractUIServer } from './AbstractUIServer.js'`.
    Bootstrap merges its two ui-server imports into a single barrel
    import.

    The ui-server barrel `@file` header updates:
    - Move `AbstractUIServer` from the "Deliberately not re-exported"
      list to a positive mention: "re-exported as a type-only symbol
      for external consumers (Bootstrap) that hold a reference to the
      selected concrete server without subclassing it".
    - Retitle the `UIServerNet` bullet: the host-parsing helpers no
      longer live here; the barrel now cross-references
      `src/utils/HostUtils.ts` so a reader chasing them does not
      wonder where they went.
    - Complete the "Deliberately not re-exported" enumeration to also
      name the omitted internal symbols from `UIServerSecurity`
      (`DEFAULT_MAX_PAYLOAD_SIZE_BYTES`, `PayloadTooLargeError`,
      `readLimitedBody`) and `UIServerUtils`
      (`isProtocolAndVersionSupported`) so the list is exhaustive.

R3. Adjacent-sub-component cycle already resolved in #1953: the
    `broadcast-channel ↔ ui-server/ui-services` value-import back-edge
    remains a direct import (not via the barrel) per the codebase's
    established convention (`meter-values/index.ts`: "Internal helpers
    are intentionally not re-exported; tests and internal callers
    should import them directly from the owning sub-module"). No
    code change required for R3 in this PR.

Test surface reorganized to match the code surface:
- `tests/utils/HostUtils.test.ts` (new) — 9 `isLoopback` cases and
  12 `normalizeHost` cases moved from the previous
  `tests/charging-station/ui-server/UIServerNet.test.ts`. Uses a
  direct module import (`../../src/utils/HostUtils.js`) rather than
  the utils barrel: the barrel load pulls Configuration singleton +
  Logger side effects into a pure-function test surface, which under
  the Node test runner produces "Promise resolution is still pending
  but the event loop has already resolved" hangs. Peer utility tests
  that need those side effects use the barrel; a pure host-parsing
  unit test does not.
- `tests/charging-station/ui-server/UIServerNet.test.ts` retains only
  the 4 `splitHeaderList` cases.

Quality gates: typecheck clean, lint clean, targeted tests pass
(utils + ui-server + broadcast-channel suites: 705/705 pass, 0 fail).
src/charging-station/Bootstrap.ts
src/charging-station/ui-server/AbstractUIServer.ts
src/charging-station/ui-server/UIServerAccessPolicy.ts
src/charging-station/ui-server/UIServerFactory.ts
src/charging-station/ui-server/UIServerNet.ts
src/charging-station/ui-server/index.ts
src/utils/ConfigurationSchema.ts
src/utils/HostUtils.ts [new file with mode: 0644]
src/utils/index.ts
tests/charging-station/ui-server/UIServerNet.test.ts
tests/utils/HostUtils.test.ts [new file with mode: 0644]