Skip to content

Fix small follow-ups after the strict TypeScript port (TSF5) - #33

Merged
Finesssee merged 1 commit into
mainfrom
ts/tsf5-followups
Oct 11, 2026
Merged

Finesssee merged 1 commit into
mainfrom
ts/tsf5-followups

Conversation

@Finesssee

Copy link
Copy Markdown
Collaborator

Small fixes left over from the strict TypeScript port. This is a behavior PR, not a port PR: each behavior change has a test that failed before the fix and passes after it, plus a doc line.

Items

# Item Status
1 Session cookie read at a name boundary Done. session() was already anchored. The real bug was /auth/logout, which matched mini_session= anywhere in the header, so xmini_session=<hex> signed out the wrong session. Both now use one sessionCookie() in server/auth.ts.
2 botDropText prototype keys Done. DROP_TEXT is a Map, so constructor reads as constructor instead of function Object() { [native code] } (constructor).
3 /auth/* errors escape the Worker's catch Done. return await handleAuth(...) inside the try, so a throwing AuthStore gets the 503 Service unavailable; check owner diagnostics answer instead of a rejected fetch.
4 Demo overlay warns on extension messages Done. parseDemoMessage returns null for a message without a demoPaused field, and the overlay ignores it silently. A demoPaused that isn't a boolean still warns once.
5 Profile save reports "Not saved" when a 2xx answer is unreadable Done. New acceptedUnreadable(r) in src/parse.ts. The fighter page says "Your profile may have saved, but this page couldn't read the answer. Reload the page to check."
6 Stale comments Done. overlay.ts (the ?v= hash comment now names vite.config.ts servedBuild), upload.ts (vite.config.ts, src/admin.ts), cosmetics.ts (tests/cosmetics.test.ts). Comment-only changes to served code change the served hash once.
7 port-check NON_SHIPPING misses vite.config.ts Done. The rule now matches vite.config.(js|ts), which matches what DEVELOPMENT.md and CONTRACTS.md already say.
8 Make shape() specs exhaustive over T Skipped. A mapped { readonly [K in keyof T]-?: Check } spec fails tsc in two places (STATE_CONFIG is annotated Spec, and LogRow.context?: unknown has no check). Fixing it needs a new always-pass check in the page bundle, which is more than a few lines and changes how every spec is written.
9 Vacuous test assertions Done. channel.test.ts (alarm ?? 0) <= x is now must(alarm) <= x at five sites, so an unset alarm fails. The registry test's Twitch stub answers /helix/moderation/moderators with {data: []} explicitly. I confirmed the call is made: naming the viewer a mod there flips "a renamed Twitch name..."

Red, then green

The pre-commit hook runs bun run check, so the failing runs aren't in history. These are from the working tree before each fix.

Unit (bun run test:unit, before the fixes: 364 run, 360 pass, 4 fail):

not ok 32 - sign-out reads only the cookie named mini_session, not one that ends in it
  error: the real session is gone
not ok 33 - an auth route that throws gets the Worker's error answer, not a rejected fetch
  error: 'auth store down'
    handleAuth (server/auth.ts:275:20)
    async Object.fetch (server/worker.ts:454:15)
not ok 355 - chat bot: drop reasons read as words
  + 'function Object() { [native code] } (constructor)'
  - 'constructor'
tests/browser-parse.test.ts failed to load:
  SyntaxError: The requested module '../src/parse.ts' does not provide an export named 'acceptedUnreadable'

Item 4, the old parseDemoMessage on messages an extension might post:

"hello" -> {"ok":false,"error":"demo message has no demoPaused switch"}
{"source":"react-devtools-content-script"} -> {"ok":false,"error":"demo message has no demoPaused switch"}
null -> {"ok":false,"error":"demo message has no demoPaused switch"}
[true] -> {"ok":false,"error":"demo message has no demoPaused switch"}

Item 7, the new port-check test against the old NON_SHIPPING rule:

not ok - vite.config.ts may update a string naming a ported file, like vite.config.js
  +     'vite.config.ts differs (base line 1, head line 1)\n' +
  +     '  base: export const SERVED = ["src/ui.js"];\n' +
  +     '  head: export const SERVED = ["src/ui.ts"];\n' +
  +     '2 files compared, 1 different\n'
  -     '2 files compared, 0 different\n'

Tests

  • Unit: 371 before, 374 after, all passing. The new tests are two in tests/auth.test.ts (items 1 and 3) and one in tests/browser-parse.test.ts (acceptedUnreadable, item 5). Items 2 and 4 add assertions to existing tests in tests/worker.test.ts and tests/browser-parse.test.ts.
  • Port tools (bun run test:port, run by CI): 101 before, 102 after.
  • Not checked: the profile-save message (item 5) has a unit test for acceptedUnreadable only. The dashboard wiring has no automated test, and CI doesn't run test:ui. I couldn't open a browser for this PR, so someone should check the message on staging.

Docs

  • docs/CONTRACTS.md §1: only a cookie named exactly mini_session counts, and /auth/* errors get the 503 answer. The bot status section says unknown drop reasons read as themselves. §8 covers parseDemoMessage returning null and acceptedUnreadable.
  • docs/PAGES.md /?channel=: the "may have saved" message.

Follow-ups (not in this PR)

  • handle() in server/worker.ts has more unawaited returns inside the same try as item 3: return internal(...) (about 8 sites) and return refuseSave(...) (3 sites). internal calls a Durable Object fetch that can reject. Turning on @typescript-eslint/return-await with in-try-catch would catch all of them.
  • The shop purchase path on the fighter page has the same unreadable-2xx problem as item 5.

- Sign-out reads only the cookie named exactly mini_session (shared sessionCookie).
- An error thrown inside /auth/* gets the Worker's 503 answer (await handleAuth).
- botDropText looks reasons up in a Map, so "constructor" reads as itself.
- The demo overlay ignores postMessages without a demoPaused field.
- The fighter page says a save may have gone through when a 2xx answer is unreadable (acceptedUnreadable).
- port-check treats vite.config.ts as non-shipping, like vite.config.js.
- Stale comments name vite.config.ts, src/admin.ts and tests/cosmetics.test.ts.
- channel tests assert the alarm is set; the registry Twitch stub answers the moderators call.
@coderabbitai

coderabbitai Bot commented Oct 11, 2026

Copy link
Copy Markdown

Important

  • 🔍 Trigger review

This repository does not receive automatic reviews because it has fewer than 10 stars.

⚙️ Run configuration
  • Configuration used: Repository: nesszer/pixfray/.coderabbit.yaml
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 30757126-3f7f-4d6d-8924-ca1b9e86cade

  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

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.

@Finesssee
Finesssee merged commit 19c6b32 into main Oct 11, 2026
3 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.

1 participant