Skip to content

fix(eol): classify unknown-metadata components as UNKNOWN#30

Merged
v3nant merged 1 commit into
mainfrom
fix/unknown-component-metadata-status
Jul 16, 2026
Merged

fix(eol): classify unknown-metadata components as UNKNOWN#30
v3nant merged 1 commit into
mainfrom
fix/unknown-component-metadata-status

Conversation

@v3nant

@v3nant v3nant commented Jul 16, 2026

Copy link
Copy Markdown
Collaborator

Summary

  • Fix deriveComponentStatus silently classifying unknown/unresolvable packages as OK ("Not EOL") after eol-api changed the component metadata shape.
  • Model the new "unknown" metadata shape in the type system so consumers can detect and narrow it.

Changes

  • src/types/eol-scan.ts — add UNKNOWN_REASONS, UnknownReason, UnknownComponentMetadata, the ComponentMetadata union, and an isUnknownReason guard. Widen EolScanComponent.metadata to ComponentMetadata | null (keep | null so legacy null records still resolve to UNKNOWN).
  • src/eol/utils.ts — widen deriveComponentStatus to ComponentMetadata | null; detect a present unknownReason before the isEol/eolAt logic and return UNKNOWN. Add a private type guard that narrows the known branch back to EolScanComponentMetadata so the existing EOL/EOL_UPCOMING/OK logic typechecks unchanged.
  • src/index.ts — export the runtime values UNKNOWN_REASONS and isUnknownReason.
  • src/eol/utils.test.ts — add tests for each of the four reasons → UNKNOWN, an unrecognized-but-present reason → UNKNOWN, nullUNKNOWN, the existing EOL/EOL_UPCOMING/OK cases, and a full isUnknownReason suite.

Testing

  • npm run build — pass
  • npm run type-check (tsc --noEmit) — pass
  • npm test — 200/200 pass (eol-scan.ts at 100% coverage)
  • npm run format:check — clean; npm run lint (oxlint) — only pre-existing warnings in spdx-to-cdx.ts, none from this change

Screenshots

n/a

Risks & Rollback

  • Behavior change (intended): unknown packages now derive UNKNOWN instead of OK — this is the fix.
  • Type-level break: EolScanComponent.metadata is now a union. TS consumers that dereference known fields directly off metadata (e.g. metadata.isEol after only a null check) must narrow first — via deriveComponentStatus, isUnknownReason, or an 'unknownReason' in metadata check. Consumers routing UNKNOWN detection through deriveComponentStatus are unaffected. Warrants a minor/major version bump.
  • Runtime surface is otherwise backward-compatible (no removed/renamed exports, no changed signatures). Rollback is a straight revert of the commit.

Checklist

  • Tests added or updated
  • Linting passes
  • Typecheck passes (if applicable)
  • No breaking changes without clear migration notes — type-level break documented above; needs version bump
  • Environment variables documented (if added/changed) — n/a

eol-api now always returns a metadata object per component. Unknown/
unresolvable packages return a partial object with only a reason
({ unknownReason }) instead of the historical null. deriveComponentStatus
only treated falsy metadata as UNKNOWN, so the new truthy { unknownReason }
object fell through to the isEol/eolAt logic and was silently classified
as OK ("Not EOL").

Detect the unknown reason before the isEol/eolAt logic and widen the type
surface to model the new shape:

- add UNKNOWN_REASONS / UnknownReason / UnknownComponentMetadata and the
  ComponentMetadata union to src/types/eol-scan.ts, plus an isUnknownReason
  guard; EolScanComponent.metadata becomes ComponentMetadata | null
  (| null kept so legacy null records still resolve to UNKNOWN)
- deriveComponentStatus takes ComponentMetadata | null and returns UNKNOWN
  for null or any present unknownReason, narrowing to the known metadata
  shape for the existing EOL/EOL_UPCOMING/OK logic
- export UNKNOWN_REASONS and isUnknownReason from the package root
- cover the four reasons, an unrecognized reason, null, and isUnknownReason
@v3nant
v3nant merged commit 53cd3d0 into main Jul 16, 2026
7 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants