integrate users/me/meta endpoint into the React and NextJs sdks - #49
integrate users/me/meta endpoint into the React and NextJs sdks#49janithjay wants to merge 1 commit into
Conversation
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (9)
🚧 Files skipped from review as they are similar to previous changes (9)
📝 WalkthroughWalkthroughThe React SDK retrieves user schema metadata during authenticated profile synchronization, exposes it through user contexts, and uses it to render and validate editable profile fields. The Next.js provider supplies a null schema by default. ChangesUser schema integration
Estimated code review effort: 4 (Complex) | ~45 minutes Sequence Diagram(s)sequenceDiagram
participant ThunderIDProvider
participant MetadataAPI
participant UserProvider
participant UserProfile
ThunderIDProvider->>MetadataAPI: Fetch /users/me/meta
MetadataAPI-->>ThunderIDProvider: Return userSchema
ThunderIDProvider->>UserProvider: Pass profile and userSchema
UserProvider-->>UserProfile: Expose userSchema
UserProfile->>UserProfile: Build and validate schema fields
Possibly related PRs
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Warning There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure. 🔧 ESLint
packages/nextjs/src/client/contexts/ThunderID/ThunderIDProvider.tsxESLint skipped: missing config or dependency (missing-dependency). The ESLint configuration references a package that is not available in the sandbox. packages/react/src/api/getUsersMeMeta.tsESLint skipped: missing config or dependency (missing-dependency). The ESLint configuration references a package that is not available in the sandbox. packages/react/src/components/presentation/UserProfile/BaseUserProfile.tsxESLint skipped: the ESLint configuration for this file references a package that is not available in the sandbox.
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 |
d28958f to
8519068
Compare
There was a problem hiding this comment.
Actionable comments posted: 7
🧹 Nitpick comments (4)
packages/react/src/components/presentation/UserProfile/BaseUserProfile.tsx (2)
626-630: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winMove the error style into the stylesheet.
The error element uses an inline style with the hardcoded color
#d32f2f. Every other element in this component uses thestylesobject fromuseStyles(theme, colorScheme). The hardcoded color ignores the theme and the dark color scheme.Add a
fieldErrorentry to the styles module, and apply the vendor CSS class prefix that the component already uses throughwithVendorCSSClassPrefix.🎨 Proposed change
{fieldErrors[schema.name] && ( - <div style={{color: '`#d32f2f`', fontSize: '0.8rem', marginTop: '4px', fontWeight: 500}}> + <div + className={cx(withVendorCSSClassPrefix(bem('user-profile', 'field-error')), styles.fieldError)} + role="alert" + > {fieldErrors[schema.name]} </div> )}The
role="alert"attribute also makes the validation message reachable for screen reader users.🤖 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/react/src/components/presentation/UserProfile/BaseUserProfile.tsx` around lines 626 - 630, Move the inline styling from the field error element in UserProfile to a new fieldError entry in the useStyles(theme, colorScheme) styles module, using theme-aware values and the existing withVendorCSSClassPrefix convention. Apply the resulting prefixed styles class to the error element and add role="alert" so validation messages are announced to screen readers.
680-730: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winResolve the ESLint errors reported across the new schema branch.
The tool reports more than forty errors for Lines 680-730, mostly
no-explicit-any,no-unsafe-member-access, andno-unsafe-assignment. TypinguserSchemaasRecord<string, AttributeSchema>and typing the map callback removes most of them.🧹 Proposed typing
- schemaItems = Object.entries(userSchema) - .filter(([key, metaAttr]: [string, any]) => { + schemaItems = Object.entries(userSchema as Record<string, AttributeSchema>) + .filter(([key, metaAttr]: [string, AttributeSchema]) => { if (metaAttr?.credential) return false; return shouldShowField(key, true); }) - .map(([key, metaAttr]: [string, any]) => { + .map(([key, metaAttr]: [string, AttributeSchema]): Schema => {Also note Line 173: remove the redundant
: booleanannotation on theisSchemaBaseddefault parameter to satisfyno-inferrable-types.🤖 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/react/src/components/presentation/UserProfile/BaseUserProfile.tsx` around lines 680 - 730, Resolve the ESLint errors in renderProfileContent by replacing explicit any usage with the existing AttributeSchema type, typing userSchema as Record<string, AttributeSchema>, and providing safe types for Object.entries filter/map callbacks and accessed values. Ensure schemaItems and derived fields use compatible concrete types without unsafe member access or assignments. Also remove the redundant boolean annotation from the isSchemaBased default parameter.Source: Linters/SAST tools
packages/react/src/contexts/ThunderID/ThunderIDContext.ts (1)
219-222: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winUse
AttributeSchemainstead ofRecord<string, any>across the schema plumbing.packages/react/src/api/getUsersMeMeta.tsexportsAttributeSchemaand returnsschema?: Record<string, AttributeSchema>, but every downstream layer re-declares the value asRecord<string, any>. The producer type is therefore lost at the first hop, and ESLint reportsno-explicit-anyat each site.
packages/react/src/contexts/ThunderID/ThunderIDContext.ts#L219-L222: changeuserSchematoRecord<string, AttributeSchema> | nulland import the type.packages/react/src/contexts/ThunderID/ThunderIDProvider.tsx#L87-L87: change the state generic toRecord<string, AttributeSchema> | null.packages/react/src/contexts/User/UserContext.ts#L34-L34: change the optionaluserSchemaproperty toRecord<string, AttributeSchema> | null.packages/react/src/contexts/User/UserProvider.tsx#L34-L34: change theuserSchemaprop toRecord<string, AttributeSchema> | null.packages/react/src/components/presentation/UserProfile/BaseUserProfile.tsx#L92-L92: change theuserSchemaprop toRecord<string, AttributeSchema> | null, which also removes the unsafe-access errors in the schema branch.Note that
userSchemais required inThunderIDContextPropsbut optional inUserContextProps. Align the optionality as part of this change.🤖 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/react/src/contexts/ThunderID/ThunderIDContext.ts` around lines 219 - 222, Replace the downstream userSchema types with AttributeSchema from getUsersMeMeta, preserving the required ThunderIDContextProps field and aligning UserContextProps with the nullable optional contract. Update packages/react/src/contexts/ThunderID/ThunderIDContext.ts (219-222), packages/react/src/contexts/ThunderID/ThunderIDProvider.tsx (87-87), packages/react/src/contexts/User/UserContext.ts (34-34), packages/react/src/contexts/User/UserProvider.tsx (34-34), and packages/react/src/components/presentation/UserProfile/BaseUserProfile.tsx (92-92) to use Record<string, AttributeSchema> with the appropriate null/optional modifiers and import the type where needed; no other sites require changes.Source: Linters/SAST tools
packages/react/src/api/getUsersMeMeta.ts (1)
19-47: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winMove the users metadata helper to the shared API layer.
getUsersMeMetawraps GET/users/me/meta, but this helper exists only in@thunderid/reactwhile the shared helpers for/users/meprofile endpoints live in@thunderid/javascript. AddgetUsersMeMetato the lower package and re-export it through@thunderid/browserso react/vue wrappers can reuse the same API contract.🤖 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/react/src/api/getUsersMeMeta.ts` around lines 19 - 47, Move the getUsersMeMeta helper and its related types, including AttributeSchema, GetUsersMeMetaConfig, and UsersMeMetaResponse, from `@thunderid/react` into `@thunderid/javascript` alongside the existing /users/me helpers. Re-export the helper and shared types through `@thunderid/browser`, then update the React implementation to reuse that shared export while preserving the GET /users/me/meta contract.Source: Coding guidelines
🤖 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/react/src/api/getUsersMeMeta.ts`:
- Around line 57-81: Fix the lint violations in the metadata fetch flow around
defaultFetcher and the final res.json return: replace || fallbacks with
nullish-coalescing where appropriate, replace HttpResponse<any> with a typed
response payload, and ensure res.json() returns that typed value without an
unsafe return. Preserve the existing fetch behavior and error handling.
- Around line 49-55: Update getUsersMeMeta to define an explicit missing-baseUrl
behavior: preserve baseUrl-derived requests, but avoid constructing
/users/me/meta when baseUrl is absent and add the required import guard, or
require url for metadata-only calls. If metadata endpoint overrides are
supported, add usersMeMeta to RESOURCE_ENDPOINT_KEYS and pass the resolved
endpoint from ThunderIDProvider via resolveResourceEndpoint.
In `@packages/react/src/components/presentation/UserProfile/BaseUserProfile.tsx`:
- Around line 339-347: Update the field update handler containing payload
construction and onUpdate so it awaits the returned promise and handles
rejection without allowing a floating promise; only call
toggleFieldEdit(fieldName) after onUpdate succeeds, leaving the field open when
the update fails. Adjust the handler’s async/dependency setup as needed while
preserving its existing payload behavior.
- Around line 304-330: Localize the required and regex validation messages in
handleFieldSave using new i18n keys and t calls that pass fieldLabel as the
field interpolation; add the corresponding translation entries. Include t in
handleFieldSave’s useCallback dependency array.
- Around line 685-711: Sort the `Object.entries(userSchema)` results in the
schema branch before filtering or mapping, ordering entries by each attribute’s
numeric `displayOrder` and using the field key as the stable fallback for ties
or missing values. Preserve the existing credential filtering and `schemaItems`
mapping behavior so `BaseUserProfile` renders fields in metadata order.
In `@packages/react/src/contexts/ThunderID/ThunderIDProvider.tsx`:
- Line 575: Update the UserProvider invocation to keep userSchema in only one
source, and memoize the profile object derived from userProfile and userSchema
so its reference remains stable when inputs are unchanged. Preserve the
null/absent userProfile behavior without relying on a non-null assertion, and
ensure the existing UserProvider props continue receiving the intended profile
data.
- Around line 158-166: Update the user-schema lifecycle around the existing
metadata fetch and authentication state handling: call setUserSchema with an
empty or undefined value when no user is signed in, and also clear it in the
catch path when getUsersMeMeta fails. Preserve setting the fetched schema on
successful responses.
---
Nitpick comments:
In `@packages/react/src/api/getUsersMeMeta.ts`:
- Around line 19-47: Move the getUsersMeMeta helper and its related types,
including AttributeSchema, GetUsersMeMetaConfig, and UsersMeMetaResponse, from
`@thunderid/react` into `@thunderid/javascript` alongside the existing /users/me
helpers. Re-export the helper and shared types through `@thunderid/browser`, then
update the React implementation to reuse that shared export while preserving the
GET /users/me/meta contract.
In `@packages/react/src/components/presentation/UserProfile/BaseUserProfile.tsx`:
- Around line 626-630: Move the inline styling from the field error element in
UserProfile to a new fieldError entry in the useStyles(theme, colorScheme)
styles module, using theme-aware values and the existing
withVendorCSSClassPrefix convention. Apply the resulting prefixed styles class
to the error element and add role="alert" so validation messages are announced
to screen readers.
- Around line 680-730: Resolve the ESLint errors in renderProfileContent by
replacing explicit any usage with the existing AttributeSchema type, typing
userSchema as Record<string, AttributeSchema>, and providing safe types for
Object.entries filter/map callbacks and accessed values. Ensure schemaItems and
derived fields use compatible concrete types without unsafe member access or
assignments. Also remove the redundant boolean annotation from the isSchemaBased
default parameter.
In `@packages/react/src/contexts/ThunderID/ThunderIDContext.ts`:
- Around line 219-222: Replace the downstream userSchema types with
AttributeSchema from getUsersMeMeta, preserving the required
ThunderIDContextProps field and aligning UserContextProps with the nullable
optional contract. Update
packages/react/src/contexts/ThunderID/ThunderIDContext.ts (219-222),
packages/react/src/contexts/ThunderID/ThunderIDProvider.tsx (87-87),
packages/react/src/contexts/User/UserContext.ts (34-34),
packages/react/src/contexts/User/UserProvider.tsx (34-34), and
packages/react/src/components/presentation/UserProfile/BaseUserProfile.tsx
(92-92) to use Record<string, AttributeSchema> with the appropriate
null/optional modifiers and import the type where needed; no other sites require
changes.
🪄 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: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro Plus
Run ID: ac1d8b94-ee3c-40a3-bb09-ecf476534e66
📒 Files selected for processing (9)
packages/nextjs/src/client/contexts/ThunderID/ThunderIDProvider.tsxpackages/react/src/api/getUsersMeMeta.tspackages/react/src/components/presentation/UserProfile/BaseUserProfile.tsxpackages/react/src/components/presentation/UserProfile/UserProfile.tsxpackages/react/src/contexts/ThunderID/ThunderIDContext.tspackages/react/src/contexts/ThunderID/ThunderIDProvider.tsxpackages/react/src/contexts/User/UserContext.tspackages/react/src/contexts/User/UserProvider.tsxpackages/react/src/index.ts
There was a problem hiding this comment.
Pull request overview
This PR adds support for fetching and consuming user profile schema metadata from the /users/me/meta endpoint, enabling @thunderid/react’s <UserProfile /> to render profile fields dynamically (labels, required-ness, ordering, etc.) based on server-provided schema.
Changes:
- Added a new React API helper (
getUsersMeMeta) and exported it from the React package entrypoint. - Extended React ThunderID/User contexts and providers to fetch and expose
userSchema. - Updated the React
UserProfile/BaseUserProfilecomponents to render/edit fields based on fetched schema metadata.
Reviewed changes
Copilot reviewed 9 out of 9 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| packages/react/src/index.ts | Exports the new getUsersMeMeta helper from the React SDK. |
| packages/react/src/contexts/User/UserProvider.tsx | Plumbs userSchema through the User context provider value. |
| packages/react/src/contexts/User/UserContext.ts | Adds userSchema to the User context contract + default value. |
| packages/react/src/contexts/ThunderID/ThunderIDProvider.tsx | Fetches /users/me/meta, stores userSchema, and passes it to downstream providers/contexts. |
| packages/react/src/contexts/ThunderID/ThunderIDContext.ts | Adds userSchema to the ThunderID context contract + default value. |
| packages/react/src/components/presentation/UserProfile/UserProfile.tsx | Passes userSchema from useUser() into BaseUserProfile. |
| packages/react/src/components/presentation/UserProfile/BaseUserProfile.tsx | Renders profile fields dynamically from userSchema and adds required/regex validation handling. |
| packages/react/src/api/getUsersMeMeta.ts | New helper for authenticated GET /users/me/meta. |
| packages/nextjs/src/client/contexts/ThunderID/ThunderIDProvider.tsx | Adds a userSchema field to the bridged React context value (currently hard-coded to null). |
Suppressed comments (4)
packages/react/src/contexts/ThunderID/ThunderIDProvider.tsx:575
userProfileis initialized asnull, so spreading it ({...userProfile!, userSchema}) will throw at runtime on the first render. This used to be safe when passing the value directly.
Pass userProfile through unchanged and keep userSchema as its own prop/source.
<UserProvider
packages/react/src/contexts/ThunderID/ThunderIDProvider.tsx:163
/users/me/metais always derived fromresolvedBaseUrl, but/users/mealready supports resource-server overrides viaresolveResourceEndpoint('usersMe', config). Ifendpoints.usersMeis configured, this call will hit the wrong host/path.
Derive the meta URL from the resolved usersMe endpoint instead (append /meta).
try {
const metaRes = await getUsersMeMeta({baseUrl: resolvedBaseUrl, instanceId});
if (metaRes?.schema) {
setUserSchema(metaRes.schema);
}
packages/react/src/api/getUsersMeMeta.ts:79
- The thrown error only includes
statusText, which is often empty for non-2xx responses returned by many servers/proxies. Including the status code (and best-effort body) makes this error actionable for SDK consumers.
return res.json();
};
packages/react/src/contexts/ThunderID/ThunderIDProvider.tsx:166
- New behavior adds an additional request to
/users/me/metaand a newuserSchemavalue flowing through context, but the existing ThunderIDProvider tests only cover/users/me. Adding/adjusting tests to mock and assert the meta fetch (and thatuserSchemais exposed) would prevent regressions (e.g., double-fetching, wrong URL, stale schema).
try {
const metaRes = await getUsersMeMeta({baseUrl: resolvedBaseUrl, instanceId});
if (metaRes?.schema) {
setUserSchema(metaRes.schema);
}
} catch (err) {
logger.warn('Failed to fetch user schema metadata from /users/me/meta:', err);
}
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
8519068 to
37217b0
Compare
There was a problem hiding this comment.
♻️ Duplicate comments (2)
packages/react/src/components/presentation/UserProfile/BaseUserProfile.tsx (2)
339-347: 🩺 Stability & Availability | 🟡 Minor | ⚡ Quick winHandle the
onUpdaterejection and only close the field editor on success.
onUpdatereturns a promise. Line 342 does not await it, so a rejection becomes an unhandled promise rejection.toggleFieldEdit(fieldName)at Line 344 also runs immediately, closing the field editor even if the update fails, hiding the failure from the user. A prior review flagged this exact pattern and it was reported as addressed, but the current code still has the unresolved version.🛡️ Proposed fix
- let payload: Record<string, any> = {}; + const payload: Record<string, any> = {}; set(payload, fieldName, fieldValue); - onUpdate(payload); - - toggleFieldEdit(fieldName); + void Promise.resolve(onUpdate(payload)).then(() => { + toggleFieldEdit(fieldName); + });🤖 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/react/src/components/presentation/UserProfile/BaseUserProfile.tsx` around lines 339 - 347, Update the field-update callback around onUpdate and toggleFieldEdit so it awaits the promise returned by onUpdate, handles or propagates any rejection without creating an unhandled promise, and only calls toggleFieldEdit(fieldName) after a successful update; keep the editor open when the update fails.
304-330: 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick winFinish the localization work: use
fieldLabelor drop it, and addtto the dependency array.
fieldLabel(Line 305) is computed but never used, matching the ESLintno-unused-varsfinding. A previous review asked for the field name to be interpolated into the validation messages (t('...', {field: fieldLabel})); the messages at Lines 311 and 323 still don't take it. Either wirefieldLabelinto thet()calls, or remove the dead variable.Also,
tis used at Lines 311 and 323 but is missing fromhandleFieldSave's dependency array (Line 346). If the active locale changes while this callback exists, it keeps calling the stalet.Additionally,
catch (e)at Line 327 never usese; drop the binding (catch {}) to satisfyno-unused-vars.🧹 Proposed fix
- const strVal = String(fieldValue ?? '').trim(); - const fieldLabel = schema.displayName || (schema.name ? startCase(schema.name) : 'Field'); + const strVal = String(fieldValue ?? '').trim(); + const fieldLabel = schema.displayName ?? (schema.name ? startCase(schema.name) : 'Field'); // 1. Required validation if (schema.required && !strVal) { setFieldErrors((prev: Record<string, string>) => ({ ...prev, - [fieldName]: t('validations.required.field.error'), + [fieldName]: t('validations.required.field.error', {field: fieldLabel}), })); return; } // 2. Regex validation if (schema.regex && strVal) { try { const reg = new RegExp(schema.regex); if (!reg.test(strVal)) { setFieldErrors((prev: Record<string, string>) => ({ ...prev, - [fieldName]: t('validation.pattern.invalid'), + [fieldName]: t('validation.pattern.invalid', {field: fieldLabel}), })); return; } - } catch (e) { + } catch { // ignore invalid regex syntax safely } }- [editedUser, flattenedProfile, profile, onUpdate, toggleFieldEdit], + [editedUser, flattenedProfile, profile, onUpdate, toggleFieldEdit, t],🤖 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/react/src/components/presentation/UserProfile/BaseUserProfile.tsx` around lines 304 - 330, Update handleFieldSave to use fieldLabel in the required and pattern validation translation calls with the expected field interpolation, or remove fieldLabel if interpolation is not supported. Add t to handleFieldSave’s dependency array so locale changes use the current translator, and change the unused regex-error catch binding to catch {}.
🧹 Nitpick comments (6)
packages/react/src/contexts/ThunderID/ThunderIDProvider.tsx (1)
87-87: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winType
userSchemausing the existingAttributeSchemacontract instead ofRecord<string, any>.Same as the other files: use
Record<string, AttributeSchema>(fromgetUsersMeMeta.ts) instead ofRecord<string, any> | nullfor this state.🤖 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/react/src/contexts/ThunderID/ThunderIDProvider.tsx` at line 87, Update the userSchema state declaration in ThunderIDProvider to use Record<string, AttributeSchema> from getUsersMeMeta.ts instead of Record<string, any> | null, preserving the existing nullable initial state and setter behavior.packages/react/src/components/presentation/UserProfile/BaseUserProfile.tsx (1)
92-92: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winType
userSchemausing the existingAttributeSchemacontract instead ofRecord<string, any>.
getUsersMeMeta.tsalready definesUsersMeMetaResponse.schema?: Record<string, AttributeSchema>andAttributeSchema. Reuse that type here instead ofRecord<string, any> | null. This removes most of theno-unsafe-member-access/no-unsafe-assignmentESLint findings at Lines 685-711 in one change and keeps the schema contract consistent from the API layer through to this component.🤖 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/react/src/components/presentation/UserProfile/BaseUserProfile.tsx` at line 92, Update the userSchema property in BaseUserProfile to use the existing AttributeSchema contract, matching UsersMeMetaResponse.schema, and remove the broad any/null typing while preserving the optional property behavior.packages/react/src/contexts/ThunderID/ThunderIDContext.ts (1)
219-223: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winType
userSchemausing the existingAttributeSchemacontract instead ofRecord<string, any>.Same as in
BaseUserProfile.tsx: reuseRecord<string, AttributeSchema>fromgetUsersMeMeta.tsinstead ofRecord<string, any> | nullhere, so the schema type stays consistent from the API layer through the context.🤖 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/react/src/contexts/ThunderID/ThunderIDContext.ts` around lines 219 - 223, Update the userSchema property in ThunderIDContext to use the existing Record<string, AttributeSchema> contract imported or defined by getUsersMeMeta.ts, replacing Record<string, any> | null and keeping its API-to-context typing consistent with BaseUserProfile.tsx.packages/react/src/contexts/User/UserContext.ts (1)
34-34: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winType
userSchemausing the existingAttributeSchemacontract instead ofRecord<string, any>.Same as the other files: reuse
Record<string, AttributeSchema>fromgetUsersMeMeta.tshere as well, to keep the publicUserContextPropscontract consistent with the API response shape.🤖 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/react/src/contexts/User/UserContext.ts` at line 34, Update the userSchema field in UserContextProps to use Record<string, AttributeSchema> from the existing getUsersMeMeta contract instead of Record<string, any>, preserving the nullable optional API response shape.packages/react/src/contexts/User/UserProvider.tsx (2)
26-35: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winType
userSchemausing the existingAttributeSchemacontract instead ofRecord<string, any>.Same as the other files: reuse
Record<string, AttributeSchema>fromgetUsersMeMeta.tsfor both theprofile.userSchemaand top-leveluserSchemafields.🤖 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/react/src/contexts/User/UserProvider.tsx` around lines 26 - 35, Update UserProviderProps to use the existing AttributeSchema contract for both profile.userSchema and the top-level userSchema fields. Replace Record<string, any> with Record<string, AttributeSchema>, reusing the AttributeSchema type from getUsersMeMeta.ts and preserving the nullable optional field behavior.
72-82: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winConsider dropping the unused
profile.userSchemafallback path.
profile?.userSchema ?? userSchema ?? null(Line 79) readsuserSchemafrom two places. The only reviewed producer,ThunderIDProvider.tsx, always passesuserSchemaas the separate top-level prop and never embeds it into theuserProfilestate object, soprofile.userSchemais currently dead. Keeping two sources with implicit precedence risks confusion if a future caller sets both differently. Consider droppinguserSchemafromUserProviderProps.profileand relying solely on the top-leveluserSchemaprop, unless another producer outside this review intentionally embeds it inprofile.🤖 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/react/src/contexts/User/UserProvider.tsx` around lines 72 - 82, Remove the embedded profile.userSchema fallback from UserProvider’s contextValue construction and rely on the top-level userSchema prop, preserving null as the final fallback. Update the UserProviderProps profile type to no longer include userSchema, and adjust any affected references while keeping the existing context value behavior unchanged.
🤖 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.
Duplicate comments:
In `@packages/react/src/components/presentation/UserProfile/BaseUserProfile.tsx`:
- Around line 339-347: Update the field-update callback around onUpdate and
toggleFieldEdit so it awaits the promise returned by onUpdate, handles or
propagates any rejection without creating an unhandled promise, and only calls
toggleFieldEdit(fieldName) after a successful update; keep the editor open when
the update fails.
- Around line 304-330: Update handleFieldSave to use fieldLabel in the required
and pattern validation translation calls with the expected field interpolation,
or remove fieldLabel if interpolation is not supported. Add t to
handleFieldSave’s dependency array so locale changes use the current translator,
and change the unused regex-error catch binding to catch {}.
---
Nitpick comments:
In `@packages/react/src/components/presentation/UserProfile/BaseUserProfile.tsx`:
- Line 92: Update the userSchema property in BaseUserProfile to use the existing
AttributeSchema contract, matching UsersMeMetaResponse.schema, and remove the
broad any/null typing while preserving the optional property behavior.
In `@packages/react/src/contexts/ThunderID/ThunderIDContext.ts`:
- Around line 219-223: Update the userSchema property in ThunderIDContext to use
the existing Record<string, AttributeSchema> contract imported or defined by
getUsersMeMeta.ts, replacing Record<string, any> | null and keeping its
API-to-context typing consistent with BaseUserProfile.tsx.
In `@packages/react/src/contexts/ThunderID/ThunderIDProvider.tsx`:
- Line 87: Update the userSchema state declaration in ThunderIDProvider to use
Record<string, AttributeSchema> from getUsersMeMeta.ts instead of Record<string,
any> | null, preserving the existing nullable initial state and setter behavior.
In `@packages/react/src/contexts/User/UserContext.ts`:
- Line 34: Update the userSchema field in UserContextProps to use Record<string,
AttributeSchema> from the existing getUsersMeMeta contract instead of
Record<string, any>, preserving the nullable optional API response shape.
In `@packages/react/src/contexts/User/UserProvider.tsx`:
- Around line 26-35: Update UserProviderProps to use the existing
AttributeSchema contract for both profile.userSchema and the top-level
userSchema fields. Replace Record<string, any> with Record<string,
AttributeSchema>, reusing the AttributeSchema type from getUsersMeMeta.ts and
preserving the nullable optional field behavior.
- Around line 72-82: Remove the embedded profile.userSchema fallback from
UserProvider’s contextValue construction and rely on the top-level userSchema
prop, preserving null as the final fallback. Update the UserProviderProps
profile type to no longer include userSchema, and adjust any affected references
while keeping the existing context value behavior unchanged.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro Plus
Run ID: 655539bc-f217-4983-80b9-7d41f88ad375
📒 Files selected for processing (9)
packages/nextjs/src/client/contexts/ThunderID/ThunderIDProvider.tsxpackages/react/src/api/getUsersMeMeta.tspackages/react/src/components/presentation/UserProfile/BaseUserProfile.tsxpackages/react/src/components/presentation/UserProfile/UserProfile.tsxpackages/react/src/contexts/ThunderID/ThunderIDContext.tspackages/react/src/contexts/ThunderID/ThunderIDProvider.tsxpackages/react/src/contexts/User/UserContext.tspackages/react/src/contexts/User/UserProvider.tsxpackages/react/src/index.ts
🚧 Files skipped from review as they are similar to previous changes (4)
- packages/react/src/index.ts
- packages/nextjs/src/client/contexts/ThunderID/ThunderIDProvider.tsx
- packages/react/src/components/presentation/UserProfile/UserProfile.tsx
- packages/react/src/api/getUsersMeMeta.ts
37217b0 to
8cc117a
Compare
8cc117a to
4bc1a26
Compare
Purpose
Integrates the
/users/me/metaschema endpoint into the React (@thunderid/react) and Next.js (@thunderid/nextjs) SDKs. This allows the<UserProfile />component to dynamically load user profile schema metadata (attribute types, labels, required states, and order) directly from the ThunderID server.Approach
getUsersMeMeta.tsin@thunderid/reactto perform authenticated requests to the/users/me/metaendpoint.UserContextandUserProviderto manage and expose theuserSchemastate.getUsersMeMetaintoThunderIDProviderto automatically fetch user schema metadata upon authentication initialization.BaseUserProfile.tsxto construct and render profile field inputs dynamically based on the fetcheduserSchemametadata.Related Issues
Related PRs
Checklist
breaking changelabel added.Security checks
Summary by CodeRabbit