Skip to content

Enabling noUncheckedIndexedAccess#3426

Merged
RobinTail merged 11 commits into
masterfrom
enable-index-check
May 31, 2026
Merged

Enabling noUncheckedIndexedAccess#3426
RobinTail merged 11 commits into
masterfrom
enable-index-check

Conversation

@RobinTail

@RobinTail RobinTail commented May 31, 2026

Copy link
Copy Markdown
Owner

Summary by CodeRabbit

  • Bug Fixes

    • SSE/EventStream now fails fast when no events are provided, surfacing an explicit error.
  • Chores

    • Tightened TypeScript strictness for more robust builds and safer indexing.
  • Documentation

    • Added v28.1.1 changelog entry documenting the empty-event failure behavior.
  • Tests

    • Added/updated tests covering empty-event handling and improved routing/server startup robustness.

@RobinTail RobinTail added refactoring The better way to achieve the same result prevention labels May 31, 2026
@coderabbitai

coderabbitai Bot commented May 31, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: f879f78c-eeb7-4ecc-9e0e-bb6d39ace999

📥 Commits

Reviewing files that changed from the base of the PR and between f2a2784 and c7176e5.

📒 Files selected for processing (3)
  • tools/headers.ts
  • tools/make-tests.ts
  • tools/rfc-agent.ts
🚧 Files skipped from review as they are similar to previous changes (3)
  • tools/headers.ts
  • tools/make-tests.ts
  • tools/rfc-agent.ts

📝 Walkthrough

Walkthrough

Enables TypeScript noUncheckedIndexedAccess and applies non-null assertions and safer iteration across source and tests; tightens SSE handling by asserting event schemas and throwing ResultHandlerError when an empty events map is provided; updates CHANGELOG with v28.1.1.

Changes

TypeScript Strictness Enablement

Layer / File(s) Summary
TypeScript compiler strictness setting
tsconfig.json
Enables noUncheckedIndexedAccess: true in compiler options.
JSON schema and diagnostics helper compliance
express-zod-api/src/diagnostics.ts, express-zod-api/src/documentation-helpers.ts, express-zod-api/src/json-schema-helpers.ts
Schema traversal and nullable-type handling refactored: #checkSchema and flattenIO switch to for...of loops; depictNullable returns original schema when anyOf is missing/empty and non-null asserts the first anyOf variant when present.
SSE event handler strictness and error handling
express-zod-api/src/sse.ts, express-zod-api/tests/sse.spec.ts
makeResultHandler imports ResultHandlerError, asserts event schema retrieval with non-null (events[event]!), and throws when events is empty; tests assert thrown error for empty events map.
Routing, AST emission, Zod types, and migration compliance
express-zod-api/src/routing-walker.ts, express-zod-api/src/typescript-api.ts, express-zod-api/src/zts.ts, migration/index.ts
Added non-null assertions and safe indexing: detachMethod and walkRouting assert stack tuples, makeTernary passes non-null asserted branches, onLiteral/onRecord assert nodes, and migration rule logic non-null asserts array element access.
Test suite compliance updates
express-zod-api/tests/*, migration/index.spec.ts
Tests updated across suites to use non-null assertions when accessing mock call arguments, array elements, or object properties; system tests add server-listening synchronization; migration test adds assert(theRule, "Rule not found").
Tooling and scripts
tools/headers.ts, tools/make-tests.ts, tools/rfc-agent.ts
Generator and tooling use non-null assertions or optional chaining to avoid unchecked indexed access and unsafe assumptions about external input shapes.
Release documentation
CHANGELOG.md
Adds v28.1.1 entry documenting SSE EventStreamFactory now throws ResultHandlerError for empty-event arguments.

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Suggested labels: documentation

"A rabbit hops through code so tight,
Paws press '!' to keep indices right.
Events checked — no empty stream,
Validated, tidy, and supreme.
Hooray for strictness, snug and bright!"

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main change: enabling the TypeScript compiler option noUncheckedIndexedAccess across the codebase, with supporting refactors throughout all affected files.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

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

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch enable-index-check

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.

@coveralls-official

coveralls-official Bot commented May 31, 2026

Copy link
Copy Markdown

Coverage Status

coverage: 100.0%. remained the same — enable-index-check into master

Comment thread express-zod-api/tests/cookie-middleware.spec.ts Outdated
@RobinTail RobinTail marked this pull request as ready for review May 31, 2026 08:52

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🧹 Nitpick comments (2)
express-zod-api/tests/sse.spec.ts (1)

157-159: ⚡ Quick win

Assert the thrown error type, not only snapshot text.

This test currently allows any thrown error with matching snapshot. Please assert ResultHandlerError explicitly to lock the
contract.

Proposed change
+import { ResultHandlerError } from "../src/errors";
@@
-    test("should throw when events map is empty", () => {
-      expect(() => makeResultHandler({})).toThrowErrorMatchingSnapshot();
-    });
+    test("should throw when events map is empty", () => {
+      expect(() => makeResultHandler({})).toThrowError(ResultHandlerError);
+      expect(() => makeResultHandler({})).toThrowErrorMatchingSnapshot();
+    });
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@express-zod-api/tests/sse.spec.ts` around lines 157 - 159, The test "should
throw when events map is empty" must assert the specific error type: update the
test invoking makeResultHandler({}) to expect a thrown ResultHandlerError (use
toThrow or toThrowError with the ResultHandlerError constructor or instanceof
check) in addition to or instead of toThrowErrorMatchingSnapshot; import or
reference ResultHandlerError from the module where it's defined and ensure the
assertion verifies the error is an instance of ResultHandlerError while
preserving the snapshot assertion if desired.
express-zod-api/src/sse.ts (1)

13-13: ⚡ Quick win

.ts extension in local imports is allowed in this repo, so it’s not a build-breaking issue.

express-zod-api/src/sse.ts:13 imports ./errors.ts; the root tsconfig.json sets compilerOptions.allowImportingTsExtensions: true, and express-zod-api/tsconfig.json extends it—so module resolution/build settings shouldn’t be affected. Keeping (or removing) the .ts suffix is a consistency/style choice only.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@express-zod-api/src/sse.ts` at line 13, The import in
express-zod-api/src/sse.ts currently uses a .ts extension ("./errors.ts"); align
it with the repository's import style by removing the extension so the import
reads "./errors" instead, updating the existing import of ResultHandlerError in
sse.ts to match other local imports and maintain consistency across the
codebase.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@express-zod-api/src/sse.ts`:
- Line 13: The import in express-zod-api/src/sse.ts currently uses a .ts
extension ("./errors.ts"); align it with the repository's import style by
removing the extension so the import reads "./errors" instead, updating the
existing import of ResultHandlerError in sse.ts to match other local imports and
maintain consistency across the codebase.

In `@express-zod-api/tests/sse.spec.ts`:
- Around line 157-159: The test "should throw when events map is empty" must
assert the specific error type: update the test invoking makeResultHandler({})
to expect a thrown ResultHandlerError (use toThrow or toThrowError with the
ResultHandlerError constructor or instanceof check) in addition to or instead of
toThrowErrorMatchingSnapshot; import or reference ResultHandlerError from the
module where it's defined and ensure the assertion verifies the error is an
instance of ResultHandlerError while preserving the snapshot assertion if
desired.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 82da7673-bb4a-4268-9ef9-b144d6a76744

📥 Commits

Reviewing files that changed from the base of the PR and between 6ac1728 and eb1e431.

⛔ Files ignored due to path filters (1)
  • express-zod-api/tests/__snapshots__/sse.spec.ts.snap is excluded by !**/*.snap
📒 Files selected for processing (19)
  • CHANGELOG.md
  • express-zod-api/src/diagnostics.ts
  • express-zod-api/src/documentation-helpers.ts
  • express-zod-api/src/json-schema-helpers.ts
  • express-zod-api/src/routing-walker.ts
  • express-zod-api/src/sse.ts
  • express-zod-api/src/typescript-api.ts
  • express-zod-api/src/zts.ts
  • express-zod-api/tests/cookie-middleware.spec.ts
  • express-zod-api/tests/endpoints-factory.spec.ts
  • express-zod-api/tests/result-handler.spec.ts
  • express-zod-api/tests/routing.spec.ts
  • express-zod-api/tests/server-helpers.spec.ts
  • express-zod-api/tests/server.spec.ts
  • express-zod-api/tests/sse.spec.ts
  • express-zod-api/tests/system.spec.ts
  • migration/index.spec.ts
  • migration/index.ts
  • tsconfig.json

@pullfrog pullfrog Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

✅ No new issues found.

Reviewed changes — enabling noUncheckedIndexedAccess in the root tsconfig.json and adjusting source, test, and migration code to compile under the stricter checks, plus adding a runtime guard in makeResultHandler for empty EventsMap.

  • Enable noUncheckedIndexedAccess in root tsconfig.json.
  • Refactor index-based loops to for...of where the index was only used for array access (diagnostics.ts, json-schema-helpers.ts).
  • Add justified non-null assertions (!) with inline comments where runtime invariants guarantee safety (routing-walker.ts, sse.ts, typescript-api.ts, zts.ts, tests).
  • Throw ResultHandlerError in makeResultHandler when the events map is empty, preventing an invalid schema at runtime.
  • Add runtime length assertions in tests before indexed access (endpoints-factory.spec.ts).
  • Add assert guard in migration/index.spec.ts for rule lookup.

ℹ️ tools/ files not adjusted for the new flag

The root tsconfig.json has no exclude array, so tools/headers.ts, tools/make-tests.ts, and tools/rfc-agent.ts are included in root-level type-checking. These files currently emit noUncheckedIndexedAccess errors. They appear to be auxiliary scripts rather than production code, and CI likely runs tsc per-workspace, so this is a minor coverage gap rather than a blocking issue.

Pullfrog  | View workflow run | Using Kimi K2𝕏

@pullfrog pullfrog Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

✅ No new issues found.

Reviewed changes — the makeResultHandler empty-events guard was moved from eager (at factory call time) to lazy (inside the positive callback), aligning the throw timing with how ResultHandler evaluates its positive schema. Tests and snapshots were updated accordingly.

  • Refactored makeResultHandler in express-zod-api/src/sse.ts to throw ResultHandlerError lazily within the positive callback instead of at factory invocation time.
  • Updated sse.spec.ts to assert the throw via rh.getPositiveResponse() rather than at makeResultHandler() construction time.
  • Updated snapshot to match the renamed test case.
  • Simplified EventStreamFactory inheritance test to use an empty events map.

Pullfrog  | View workflow run | Using Kimi K2𝕏

@RobinTail RobinTail merged commit 3dc1316 into master May 31, 2026
14 checks passed
@RobinTail RobinTail deleted the enable-index-check branch May 31, 2026 19:04
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

prevention refactoring The better way to achieve the same result

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant