Skip to content

Fix type errors for Node 24 compatibility#54

Merged
domleboss97 merged 2 commits intomainfrom
dom/node-24-support
Feb 24, 2026
Merged

Fix type errors for Node 24 compatibility#54
domleboss97 merged 2 commits intomainfrom
dom/node-24-support

Conversation

@domleboss97
Copy link
Collaborator

@domleboss97 domleboss97 commented Feb 24, 2026

  • Add FetchLike utility type to decouple from typeof globalThis.fetch, which gained a preconnect
    static property in Node 24
  • Use vi.stubGlobal for fetch mocking in tests (Vitest recommended pattern)
  • Add explicit return type to signedPayloadValidator to fix TS2742 portable type error
  • Update CI to Node 24

Summary by CodeRabbit

  • Chores

    • Updated Node.js runtime from 22 to 24 in CI.
  • Refactor

    • Enhanced type safety for DID resolution and middleware validator configuration, including a new fetch-compatible type.
  • Tests

    • Modernized test globals handling with stub/un-stub lifecycle to improve test reliability.

@coderabbitai
Copy link

coderabbitai bot commented Feb 24, 2026

Walkthrough

Introduces a FetchLike type and updates DID resolver types and JWKS initialization, replaces direct global.fetch assignment with Vitest stubbing and cleanup in tests, adds explicit MiddlewareHandler generics and SignedPayloadEnv typing to middleware, and bumps Node.js from 22 to 24 in GitHub Actions.

Changes

Cohort / File(s) Summary
DID types & resolvers
packages/did/src/types.ts, packages/did/src/did-resolvers/web-did-resolver.ts, packages/did/src/did-resolvers/get-did-resolver.ts
Add exported FetchLike type; change DidWebResolverOptions.fetch to FetchLike; update JWKS resolver initialization to pass a structured options object spreading webOptions and casting fetch to the global fetch type.
Resolver tests
packages/did/src/did-resolvers/web-did-resolver.test.ts
Replace direct global.fetch = ... with vi.stubGlobal("fetch", mockFetch), import afterEach from vitest, and add vi.unstubAllGlobals() cleanup after each test.
API middleware
tools/api-utils/src/middleware/signed-payload-validator.ts
Import MiddlewareHandler, introduce SignedPayloadEnv (with Variables.resolver: Resolvable), and update signedPayloadValidator return type to MiddlewareHandler<SignedPayloadEnv, string, { out: { json: ValidatedSignedPayload<T> } }>; use c.get("resolver") non-optional retrieval.
CI workflow
.github/actions/setup/action.yaml
Bump Node.js version used by setup-node action from 22 to 24.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the main objective of the changeset: fixing type errors and enabling Node 24 compatibility across multiple files.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch dom/node-24-support

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (2)
.github/actions/setup/action.yaml (1)

11-11: LGTM — Node 24 is Active LTS.

Node 24 (Krypton) entered Active LTS on 2025-10-28, and the latest patch as of February 2026 is 24.13.1, so "24" is a well-supported version string for actions/setup-node. The version bump is consistent with the PR's stated goal of Node 24 compatibility.

One optional consideration: Node 22 is still in Maintenance LTS until April 2027. If the library is intended to remain compatible with Node 22, adding a matrix build (e.g., [22, 24]) would ensure regressions on older supported runtimes are caught in CI. If Node 22 is being intentionally dropped, a note in the changelog/README would help consumers.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.github/actions/setup/action.yaml at line 11, The workflow currently pins
actions/setup-node to node-version: "24" which is fine; if you intend to keep
Node 22 compatibility add a matrix in the workflow (e.g., matrix.node-version:
[22, 24]) so CI runs against both runtimes and update the actions/setup-node
usage to use matrix.node-version, otherwise add a short changelog/README note
stating that Node 22 support is dropped; modify the workflow's node-version key
or add matrix.node-version and adjust any step references (actions/setup-node)
accordingly.
tools/api-utils/src/middleware/signed-payload-validator.ts (1)

38-45: "json" output key is hardcoded regardless of the target parameter.

The return type { out: { json: ValidatedSignedPayload<T> } } will misrepresent the validated output when target is anything other than "json" (e.g. "form", "query"). If this validator is only ever used with "json", consider narrowing the target parameter type accordingly. Otherwise, make target a generic type parameter so the output key matches:

♻️ Proposed refactor for target-aware output typing
-export const signedPayloadValidator = <T>(
-  target: keyof ValidationTargets,
+export const signedPayloadValidator = <T, TTarget extends keyof ValidationTargets>(
+  target: TTarget,
   schema: v.GenericSchema<unknown, T>,
 ): MiddlewareHandler<
   Env,
   string,
-  { out: { json: ValidatedSignedPayload<T> } }
+  { out: { [K in TTarget]: ValidatedSignedPayload<T> } }
 > =>
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@tools/api-utils/src/middleware/signed-payload-validator.ts` around lines 38 -
45, The return type of signedPayloadValidator incorrectly hardcodes the output
key "json"; update the function signature to make the target parameter
type-aware: change the parameter to a generic like TTarget extends keyof
ValidationTargets and accept target: TTarget (or if this validator truly only
handles JSON, narrow target to "json"), then update the MiddlewareHandler return
type from { out: { json: ValidatedSignedPayload<T> } } to use the generic key
(e.g. { out: { [K in TTarget]: ValidatedSignedPayload<T> } }), ensuring
ValidationTargets and any callers are updated to satisfy the new generic where
needed.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In @.github/actions/setup/action.yaml:
- Line 11: The workflow currently pins actions/setup-node to node-version: "24"
which is fine; if you intend to keep Node 22 compatibility add a matrix in the
workflow (e.g., matrix.node-version: [22, 24]) so CI runs against both runtimes
and update the actions/setup-node usage to use matrix.node-version, otherwise
add a short changelog/README note stating that Node 22 support is dropped;
modify the workflow's node-version key or add matrix.node-version and adjust any
step references (actions/setup-node) accordingly.

In `@tools/api-utils/src/middleware/signed-payload-validator.ts`:
- Around line 38-45: The return type of signedPayloadValidator incorrectly
hardcodes the output key "json"; update the function signature to make the
target parameter type-aware: change the parameter to a generic like TTarget
extends keyof ValidationTargets and accept target: TTarget (or if this validator
truly only handles JSON, narrow target to "json"), then update the
MiddlewareHandler return type from { out: { json: ValidatedSignedPayload<T> } }
to use the generic key (e.g. { out: { [K in TTarget]: ValidatedSignedPayload<T>
} }), ensuring ValidationTargets and any callers are updated to satisfy the new
generic where needed.

ℹ️ Review info

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 7c1739a and ccfb982.

📒 Files selected for processing (6)
  • .github/actions/setup/action.yaml
  • packages/did/src/did-resolvers/get-did-resolver.ts
  • packages/did/src/did-resolvers/web-did-resolver.test.ts
  • packages/did/src/did-resolvers/web-did-resolver.ts
  • packages/did/src/types.ts
  • tools/api-utils/src/middleware/signed-payload-validator.ts

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@tools/api-utils/src/middleware/signed-payload-validator.ts`:
- Around line 47-53: Add a runtime guard inside the async validator callback to
detect if c.get("resolver") returns undefined and throw a clear, descriptive
Error (e.g. "missing DID resolver in context") before continuing; specifically,
in the validator(target, async (value, c) => { ... }) block where you call const
didResolver = c.get("resolver"), check didResolver and throw if falsy so you
avoid opaque failures while preserving the existing dev-mode bypass path and
subsequent try/catch flow.

ℹ️ Review info

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between ccfb982 and 7019a27.

📒 Files selected for processing (1)
  • tools/api-utils/src/middleware/signed-payload-validator.ts

Comment on lines +47 to +53
): MiddlewareHandler<
SignedPayloadEnv,
string,
{ out: { json: ValidatedSignedPayload<T> } }
> =>
validator(target, async (value, c): Promise<ValidatedSignedPayload<T>> => {
const didResolver = c.get("resolver") as Resolvable | undefined
const didResolver = c.get("resolver")
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Add a runtime guard for missing resolver to avoid opaque failures.
Even with env typing, a misconfigured context can still yield undefined at runtime; throwing a clear error inside the try preserves the dev-mode bypass path.

🧯 Suggested guard
-  validator(target, async (value, c): Promise<ValidatedSignedPayload<T>> => {
-    const didResolver = c.get("resolver")
-
-    try {
+  validator(target, async (value, c): Promise<ValidatedSignedPayload<T>> => {
+    const didResolver = c.get("resolver")
+
+    try {
+      if (!didResolver) {
+        throw new Error("Missing DID resolver in context")
+      }
       const data = v.parse(signedPayloadSchema, value)
       const { parsed, body } = await validatePayload(
         data.payload,
         schema,
         didResolver,
       )
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@tools/api-utils/src/middleware/signed-payload-validator.ts` around lines 47 -
53, Add a runtime guard inside the async validator callback to detect if
c.get("resolver") returns undefined and throw a clear, descriptive Error (e.g.
"missing DID resolver in context") before continuing; specifically, in the
validator(target, async (value, c) => { ... }) block where you call const
didResolver = c.get("resolver"), check didResolver and throw if falsy so you
avoid opaque failures while preserving the existing dev-mode bypass path and
subsequent try/catch flow.

@domleboss97 domleboss97 merged commit fb5cc49 into main Feb 24, 2026
3 checks passed
@domleboss97 domleboss97 deleted the dom/node-24-support branch February 24, 2026 16:30
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