Add NestJS SDK (@thunderid/nestjs)#26
Conversation
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (4)
✅ Files skipped from review due to trivial changes (1)
📝 WalkthroughWalkthroughAdds the ChangesNestJS SDK
Estimated code review effort: 4 (Complex) | ~45 minutes Sequence Diagram(s)sequenceDiagram
participant NestController
participant ThunderIDGuard
participant ThunderIDService
participant ThunderIDExpressClient
NestController->>ThunderIDGuard: canActivate(context)
ThunderIDGuard->>ThunderIDService: isSignedIn(req)
ThunderIDService->>ThunderIDExpressClient: initialize and check session
ThunderIDExpressClient-->>ThunderIDService: signed-in status
ThunderIDGuard->>ThunderIDService: getUser(req)
ThunderIDService->>ThunderIDExpressClient: retrieve authenticated user
ThunderIDExpressClient-->>ThunderIDGuard: User
ThunderIDGuard-->>NestController: allow request with req.thunderIDUser
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
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. Comment |
There was a problem hiding this comment.
Actionable comments posted: 5
🧹 Nitpick comments (1)
packages/nestjs/src/__tests__/ThunderIDGuard.test.ts (1)
56-64: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winUse the shared
THUNDERID_CONFIGconstant here. Replace the raw'THUNDERID_CONFIG'literal in the assertion so the test stays aligned with the exported token.🤖 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 `@packages/nestjs/src/__tests__/ThunderIDGuard.test.ts` around lines 56 - 64, Replace the raw 'THUNDERID_CONFIG' token in the forRoot registration test with the shared exported THUNDERID_CONFIG constant, importing it if necessary, so the assertion remains aligned with the module’s provider token.
🤖 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.
Inline comments:
In `@packages/nestjs/README.md`:
- Around line 51-57: Clarify the no-token path in the login example’s `login`
method: either add an `else` response handling branch for when `signIn` returns
without tokens, or document that `this.thunderID.signIn` completes the OIDC
redirect internally in that case.
In `@packages/nestjs/src/index.ts`:
- Line 38: Make the `@thunderid/express` re-export in packages/nestjs/src/index.ts
resolvable during lint by configuring ESLint’s import resolver to include
workspace source paths or ensuring the workspace dependency is built/available
before pnpm lint; verify the NestJS lint step passes.
In `@packages/nestjs/src/ThunderIDService.ts`:
- Around line 125-127: Update ThunderIDService.isSignOutSuccess to safely handle
Express 5 query values by returning true only when req.query['state'] is a
string equal to 'sign_out_success'; explicitly guard against arrays, ParsedQs
values, and undefined before comparing.
- Around line 69-79: Update ensureInitialized to clear the cached initPromise
when client.initialize rejects, while preserving the rejection for the current
caller. Add a catch handler around the initialization promise that resets
this.initPromise to undefined before rethrowing the original error, allowing
subsequent requests to retry initialization.
In `@packages/nestjs/tsconfig.spec.json`:
- Around line 3-7: Update packages/nestjs/tsconfig.spec.json to replace "jest"
with the Vitest type definitions in compilerOptions.types, and remove the
obsolete test-configs and jest.config.js entries from the include configuration.
---
Nitpick comments:
In `@packages/nestjs/src/__tests__/ThunderIDGuard.test.ts`:
- Around line 56-64: Replace the raw 'THUNDERID_CONFIG' token in the forRoot
registration test with the shared exported THUNDERID_CONFIG constant, importing
it if necessary, so the assertion remains aligned with the module’s provider
token.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro Plus
Run ID: dc97789a-eeaa-42c3-9bc8-65ddbdeb98a3
⛔ Files ignored due to path filters (1)
pnpm-lock.yamlis excluded by!**/pnpm-lock.yaml
📒 Files selected for processing (22)
README.mdpackages/nestjs/.editorconfigpackages/nestjs/.gitignorepackages/nestjs/.prettierignorepackages/nestjs/README.mdpackages/nestjs/eslint.config.jspackages/nestjs/package.jsonpackages/nestjs/prettier.config.jspackages/nestjs/rolldown.config.jspackages/nestjs/src/ThunderIDModule.tspackages/nestjs/src/ThunderIDService.tspackages/nestjs/src/__tests__/ThunderIDGuard.test.tspackages/nestjs/src/constants/InjectionTokens.tspackages/nestjs/src/decorators/CurrentUser.tspackages/nestjs/src/guards/ThunderIDGuard.tspackages/nestjs/src/index.tspackages/nestjs/src/models/config.tspackages/nestjs/tsconfig.eslint.jsonpackages/nestjs/tsconfig.jsonpackages/nestjs/tsconfig.lib.jsonpackages/nestjs/tsconfig.spec.jsonpackages/nestjs/vitest.config.ts
| export {THUNDERID_CONFIG} from './constants/InjectionTokens'; | ||
|
|
||
| // Re-export everything from the Express SDK (includes the Node and JavaScript SDK re-exports) | ||
| export * from '@thunderid/express'; |
There was a problem hiding this comment.
📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
pnpm --filter `@thunderid/nestjs` lint
pnpm --filter `@thunderid/express` build
pnpm --filter `@thunderid/nestjs` lintRepository: thunder-id/javascript-sdks
Length of output: 11447
🏁 Script executed:
#!/bin/bash
set -euo pipefail
printf '\n== workspace files ==\n'
git ls-files 'pnpm-workspace.yaml' 'package.json' '.eslintrc*' 'eslint.config.*' 'packages/nestjs/package.json' 'packages/express/package.json' 'packages/node/package.json' 'packages/*/package.json' | sed 's#^`#-` #'
printf '\n== workspace root package.json ==\n'
cat -n package.json | sed -n '1,220p'
printf '\n== pnpm-workspace.yaml ==\n'
cat -n pnpm-workspace.yaml | sed -n '1,120p'
printf '\n== eslint config files ==\n'
for f in .eslintrc .eslintrc.json .eslintrc.js .eslintrc.cjs .eslintrc.mjs eslint.config.js eslint.config.mjs eslint.config.cjs; do
if [ -f "$f" ]; then
echo "--- $f ---"
cat -n "$f" | sed -n '1,260p'
fi
done
printf '\n== package manifests ==\n'
for f in packages/nestjs/package.json packages/express/package.json packages/node/package.json; do
echo "--- $f ---"
cat -n "$f" | sed -n '1,220p'
doneRepository: thunder-id/javascript-sdks
Length of output: 12884
🏁 Script executed:
#!/bin/bash
set -euo pipefail
printf '\n== express package files ==\n'
git ls-files 'packages/express/*' | sed 's#^`#-` #'
printf '\n== express tsconfig files ==\n'
for f in packages/express/tsconfig*.json; do
echo "--- $f ---"
cat -n "$f" | sed -n '1,260p'
done
printf '\n== express source entrypoints ==\n'
for f in packages/express/src/index.ts packages/express/src/index.js packages/express/src/index.mts packages/express/src/index.cts; do
if [ -f "$f" ]; then
echo "--- $f ---"
cat -n "$f" | sed -n '1,220p'
fi
done
printf '\n== any workspace source exports or path aliases referencing `@thunderid/express` ==\n'
rg -n --hidden --glob '!**/dist/**' --glob '!**/node_modules/**' '`@thunderid/express`|paths|exports' packages/express packages/nestjs package.json pnpm-workspace.yaml eslint.config.jsRepository: thunder-id/javascript-sdks
Length of output: 6599
Make the workspace re-export lint-resolvable. packages/nestjs/src/index.ts:38 re-exports @thunderid/express, but ESLint can’t resolve that workspace package in the current setup. Point the resolver at workspace source or make the dependency chain available before pnpm lint; otherwise the NestJS lint step stays red.
🧰 Tools
🪛 ESLint
[error] 38-38: Unable to resolve path to module '@thunderid/express'.
(import-x/no-unresolved)
🤖 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 `@packages/nestjs/src/index.ts` at line 38, Make the `@thunderid/express`
re-export in packages/nestjs/src/index.ts resolvable during lint by configuring
ESLint’s import resolver to include workspace source paths or ensuring the
workspace dependency is built/available before pnpm lint; verify the NestJS lint
step passes.
Source: Linters/SAST tools
- Reset cached init promise on failure so transient startup errors recover - Handle array/missing state query values in isSignOutSuccess (Express 5) - Replace Jest types and drop dead include entries in tsconfig.spec.json - Clarify sign-in redirect behavior in README and service docs
Purpose
Adds
@thunderid/nestjs, a NestJS SDK built on top of@thunderid/express.NestJS is widely used in enterprise Node.js backends, and every major auth
vendor (Auth0, Clerk, etc.) ships a NestJS integration — this fills that gap
in the ThunderID JavaScript ecosystem.
Approach
Thin idiomatic-NestJS wrapper over the existing Express SDK (no re-implemented
auth logic), mirroring how
@thunderid/expresswraps@thunderid/node:ThunderIDModule.forRoot(config)ThunderIDServicesignIn,signOut,isSignOutSuccess,isSignedIn,getUseroverThunderIDExpressClientThunderIDGuardprotect()middleware (401 on no/invalid session)@CurrentUser()Everything from
@thunderid/express(and transitivelynode/javascript) isre-exported. Response handling stays in the consumer's controllers instead of
config hooks (
onSignIn/onError), which is the idiomatic NestJS shape.Build/lint/test setup is copied from
packages/express(rolldown ESM+CJS,tsc declarations, shared eslint/prettier/vitest configs). Works with NestJS
apps on the default Express platform; requires
cookie-parser(same as theExpress SDK).
Testing
packed npm tarball (registry versions of
@thunderid/express@0.2.5,@thunderid/node@0.2.3,@thunderid/javascript@0.3.10) against a localmock OIDC provider (discovery, authorize, token, JWKS, end-session):
/login→ 302 to/oauth2/authorizewith PKCE (S256), session cookie set@CurrentUser()/logout→ cookie cleared, redirect to end-session endpoint,state=sign_out_successround-trip, session invalidated (401 after)moduleResolution: nodenextwithnoImplicitAny— this required adding a"types"condition to theexportsmap (withexportspresent, TypeScript ignores the top-level"types"field). Note: the other packages in this repo that use bare{"import", "require"}exports (javascript,node,browser,react,express) have the same latent issue fornodenextconsumers — happy tofix those in a follow-up PR.
Related
samples/nestjs/quickstartapp can follow in separate PRs.Summary by CodeRabbit
@thunderid/nestjsSDK, includingThunderIDModule.forRoot,ThunderIDServicesign-in/sign-out handling, andThunderIDGuardroute protection.@CurrentUser()decorator for retrieving the authenticated user from requests.CurrentUser-related request user attachment, andforRootmodule configuration.@thunderid/nestjspackage in the Packages table and added the package’s README.