From 91b3a4ad127b896405d6398f0521223fb5008858 Mon Sep 17 00:00:00 2001 From: Brion Date: Tue, 8 Jul 2025 14:14:59 +0530 Subject: [PATCH 01/12] docs: initiate an internal doc space --- packages/react/docs/OVERVIEW.md | 0 packages/react/docs/README.md | 19 ++ packages/react/docs/components/README.md | 199 ++++++++++++++++++ .../react/docs/getting-started/QUICKSTART.md | 184 ++++++++++++++++ 4 files changed, 402 insertions(+) delete mode 100644 packages/react/docs/OVERVIEW.md create mode 100644 packages/react/docs/README.md create mode 100644 packages/react/docs/components/README.md create mode 100644 packages/react/docs/getting-started/QUICKSTART.md diff --git a/packages/react/docs/OVERVIEW.md b/packages/react/docs/OVERVIEW.md deleted file mode 100644 index e69de29b..00000000 diff --git a/packages/react/docs/README.md b/packages/react/docs/README.md new file mode 100644 index 00000000..8af1702d --- /dev/null +++ b/packages/react/docs/README.md @@ -0,0 +1,19 @@ +# @asgardeo/react - Overview + +The Asgardeo React SDK provides a comprehensive set of hooks, components, and utilities to integrate Asgardeo authentication into your React applications. Built on top of the `@asgardeo/browser` SDK, it offers a React-specific wrapper with pre-built components and React hooks for seamless authentication experiences. + +## Features + +- πŸ” **Complete Authentication Flow**: Sign-in, sign-up, and sign-out functionality +- 🎨 **Pre-built Components**: Ready-to-use UI components for authentication +- πŸͺ **React Hooks**: Powerful hooks for authentication state management +- 🌐 **Multi-language Support**: Built-in internationalization (i18n) support +- 🎭 **Theming & Branding**: Customizable themes and branding options +- 🏒 **Organization Management**: Support for organization-based authentication +- πŸ“± **Social Login**: Built-in support for popular social providers +- πŸ”’ **Type Safe**: Full TypeScript support for better developer experience +- ⚑ **Performance Optimized**: Efficient re-rendering and state management + +## What's Next + +- [Quickstart Guide](./QUICKSTART.md): Get started with a simple integration. diff --git a/packages/react/docs/components/README.md b/packages/react/docs/components/README.md new file mode 100644 index 00000000..66fac4ca --- /dev/null +++ b/packages/react/docs/components/README.md @@ -0,0 +1,199 @@ +# Components Overview + +The Asgardeo React SDK provides a comprehensive set of components to handle authentication, user management, and organization features in your React applications. The components are organized into different categories based on their functionality. + +## Component Categories + +### Action Components + +Action components trigger specific authentication-related actions when users interact with them. + +#### Sign-In Components + +- **`SignInButton`** - A customizable button that initiates the sign-in flow +- **`SignUpButton`** - A button for user registration flows +- **`SignOutButton`** - A button that handles user sign-out + +These components support both render props and traditional props patterns, giving you flexibility in how you implement them. + +```tsx +// Render props pattern + + {({signIn, isLoading}) => ( + + )} + + +// Traditional props pattern +Sign In +``` + +### Control Components + +Control components manage the conditional rendering of content based on authentication state. + +- **`SignedIn`** - Renders children only when the user is authenticated +- **`SignedOut`** - Renders children only when the user is not authenticated +- **`AsgardeoLoading`** - Shows loading state during authentication operations + +```tsx + +
Please sign in to continue
+
+ + +
Welcome! You are signed in.
+
+``` + +### Presentation Components + +Presentation components display user and organization information with built-in styling and functionality. + +#### User Components + +- **`User`** - Provides render props access to user data +- **`UserProfile`** - Displays comprehensive user profile information +- **`UserDropdown`** - A dropdown menu with user info and actions + +#### Organization Components + +- **`Organization`** - Displays organization information +- **`OrganizationProfile`** - Shows detailed organization profile +- **`OrganizationSwitcher`** - Allows switching between organizations +- **`OrganizationList`** - Lists available organizations +- **`CreateOrganization`** - Form for creating new organizations + +#### Authentication UI Components + +- **`SignIn`** - Complete sign-in form with multiple authentication options +- **`SignUp`** - User registration form + +### Sign-In Options + +The SDK includes specialized components for different authentication methods: + +- **`IdentifierFirst`** - Username/email identification step +- **`UsernamePassword`** - Traditional username/password authentication +- **`EmailOtp`** - Email-based OTP authentication +- **`SmsOtp`** - SMS-based OTP authentication +- **`Totp`** - Time-based OTP authentication + +#### Social Login Components + +- **`GoogleButton`** - Google OAuth sign-in +- **`GitHubButton`** - GitHub OAuth sign-in +- **`MicrosoftButton`** - Microsoft OAuth sign-in +- **`FacebookButton`** - Facebook OAuth sign-in +- **`LinkedInButton`** - LinkedIn OAuth sign-in +- **`SignInWithEthereumButton`** - Ethereum wallet authentication +- **`SocialButton`** - Generic social provider button +- **`MultiOptionButton`** - Button supporting multiple authentication options + +### Primitive Components + +Primitive components are low-level UI building blocks that can be used independently: + +#### Form Components +- **`Button`** - Styled button component +- **`TextField`** - Text input field +- **`PasswordField`** - Password input with visibility toggle +- **`Select`** - Dropdown select component +- **`Checkbox`** - Checkbox input +- **`DatePicker`** - Date selection component +- **`OtpField`** - OTP code input +- **`MultiInput`** - Multiple value input +- **`KeyValueInput`** - Key-value pair input + +#### Layout Components +- **`Card`** - Container card component +- **`FormControl`** - Form field wrapper +- **`Divider`** - Visual separator +- **`Popover`** - Overlay component + +#### Display Components +- **`Typography`** - Text styling component +- **`Avatar`** - User avatar display +- **`Logo`** - Logo component +- **`Alert`** - Alert message component +- **`Spinner`** - Loading spinner +- **`InputLabel`** - Form input labels + +#### Icon Components +- **`Icons`** - Collection of icon components including `BuildingAlt` and others + +### Factory Components + +- **`FieldFactory`** - Dynamically creates form fields based on configuration + +## Component Architecture + +### Base vs. Regular Components + +Many components come in two variants: + +1. **Base Components** (e.g., `BaseSignInButton`, `BaseUserProfile`) - Framework-agnostic components that handle core logic +2. **Regular Components** (e.g., `SignInButton`, `UserProfile`) - React-specific wrappers that integrate with Asgardeo context + +### Render Props Pattern + +Many components support the render props pattern, allowing you to customize the rendering while leveraging the component's logic: + +```tsx + + {(user) => ( +
+

Welcome, {user?.given_name}!

+

Email: {user?.email}

+
+ )} +
+``` + +### Context Integration + +Components automatically integrate with the Asgardeo context providers: +- `AsgardeoProvider` - Main authentication context +- `UserProvider` - User data context +- `OrganizationProvider` - Organization context +- `ThemeProvider` - Theming context +- `BrandingProvider` - Branding customization +- `I18nProvider` - Internationalization context + +## Getting Started + +To use these components, wrap your application with the `AsgardeoProvider`: + +```tsx +import { AsgardeoProvider, SignInButton, SignedIn, SignedOut, UserProfile } from '@asgardeo/react' + +function App() { + return ( + + + Sign In + + + + + + + ) +} +``` + +## Browser Support + +All components are designed for client-side React applications (CSR) and require a browser environment. They are not compatible with server-side rendering (SSR) environments. + +## Next Steps + +- [Explore Action Components](./actions/) - Learn about sign-in, sign-out, and sign-up buttons +- [Learn Control Components](./control/) - Understand conditional rendering based on auth state +- [Discover Presentation Components](./presentation/) - Explore user and organization display components +- [Customize with Primitives](./primitives/) - Use low-level UI components for custom implementations diff --git a/packages/react/docs/getting-started/QUICKSTART.md b/packages/react/docs/getting-started/QUICKSTART.md new file mode 100644 index 00000000..01cb2f3c --- /dev/null +++ b/packages/react/docs/getting-started/QUICKSTART.md @@ -0,0 +1,184 @@ +# React Quickstart + +Welcome to the React Quickstart guide! In this document, you will learn to build a React app, add user sign-in and display user profile information using Asgardeo. + +## What You Will Learn + +- Create new React app using Vite +- Install @asgardeo/react package +- Add user sign-in and sign-out +- Display user profile information + +## Prerequisites + +Before you start, ensure you have the following: + +- About 15 minutes +- Asgardeo account +- Install Node.js on your system +- Make sure you have a JavaScript package manager like npm, yarn, or pnpm +- A favorite text editor or IDE + +## Example Source Code + +[React Vite App Sample](../../samples/) + +## 1. Configure an Application in Asgardeo + +1. Sign into the Asgardeo Console and navigate to **Applications** > **New Application**. +2. Select **React** and complete the wizard by providing a suitable name and an authorized redirect URL. + +**Example:** + +- Name: `asgardeo-react` +- Authorized redirect URL: `http://localhost:5173` + +Once you finish creating the application, note down the following values from its **Guide** tab. You will need them to configure Asgardeo React SDK. + +- **Client ID** - The unique identifier for your application. +- **Base URL** - The base URL of your Asgardeo organization. This typically follows the format `https://api.asgardeo.io/t/` + +> **Info**: The authorized redirect URL determines where Asgardeo should send users after they successfully log in. Typically, this will be the web address where your app is hosted. For this guide, we'll use `http://localhost:5173`, as the sample app will be accessible at this URL. + +## 2. Create a React App Using Vite + +Create (scaffold) your new React app using Vite: + +```bash +npm create vite@latest asgardeo-react -- --template react +cd asgardeo-react +npm install +npm run dev +``` + +## 3. Install @asgardeo/react + +Asgardeo React SDK provides all the components and hooks you need to integrate Asgardeo into your app. To get started, simply add the Asgardeo React SDK to the project. Make sure to stop the dev server you started in the previous step. + +```bash +# Using npm +npm install @asgardeo/react + +# Using pnpm +pnpm add @asgardeo/react + +# Using yarn +yarn add @asgardeo/react +``` + +## 4. Add `` to Your App + +The `` serves as a context provider for the SDK. You can integrate this provider to your app by wrapping the root component. + +Add the following changes to the `main.jsx` file. + +> **Important**: Replace below placeholders with your registered organization name in Asgardeo and the generated client-id from the app you registered in Asgardeo. +> +> - `` +> - `https://api.asgardeo.io/t/` + +```jsx +import { StrictMode } from 'react' +import { createRoot } from 'react-dom/client' +import './index.css' +import App from './App.jsx' +import { AsgardeoProvider } from '@asgardeo/react' + +createRoot(document.getElementById('root')).render( + + + + + +) +``` + +## 5. Add Sign-In and Sign-Out to Your App + +Asgardeo SDK provides `SignInButton`, `SignOutButton` components to handle user sign-in and sign-out. You can use these components alongside `SignedIn` and `SignedOut` components to conditionally render content based on the user's logged in state. + +Replace the existing content of the `App.jsx` file with following content: + +```jsx +import { SignedIn, SignedOut, SignInButton, SignOutButton } from '@asgardeo/react' +import './App.css' + +function App() { + return ( +
+ + + + + + +
+ ) +} + +export default App +``` + +## 6. Display Signed-In User's Profile Information + +You can use the `User`, `UserProfile`, or `UserDropdown` components to access and display user profile information in a declarative way. + +- **User**: The `User` component provides a render prop pattern to access user profile information: +- **UserProfile**: The `UserProfile` component provides a declarative way to display and update user profile information. +- **UserDropdown**: The `UserDropdown` component provides a dropdown menu with built-in user information and sign-out functionality. + +```jsx +import { SignedIn, SignedOut, SignInButton, SignOutButton, User, UserDropdown, UserProfile } from '@asgardeo/react' +import './App.css' + +function App() { + return ( + <> +
+ + + + + + + +
+
+ + + {(user) => ( +
+

Welcome back, {user.userName || user.username || user.sub}

+
+ )} +
+ +
+
+ + ) +} + +export default App +``` + +## 7. Run the App + +To run the app, use the following command: + +```bash +npm run dev +``` + +Visit your app's homepage at [http://localhost:5173](http://localhost:5173). + +> **Important**: To try out sign-in and sign-out features, create a test user in Asgardeo by following [this guide](https://wso2.com/asgardeo/docs/guides/users/manage-users/#onboard-a-user). + +## What's Next? + +Now that you have basic authentication working, you can: + +- [Explore all available components](../components/README.md) to enhance your app. From ad9155035aa1487951705ccf4a7c76f2a25e2185 Mon Sep 17 00:00:00 2001 From: Brion Date: Tue, 8 Jul 2025 14:56:03 +0530 Subject: [PATCH 02/12] docs: update README and add detailed documentation for AsgardeoProvider and components overview --- packages/react/docs/README.md | 2 +- .../docs/components/ASGARDEO_PROVIDER.md | 249 ++++++++++++++++++ packages/react/docs/components/OVERVIEW.md | 59 +++++ packages/react/docs/components/README.md | 199 -------------- 4 files changed, 309 insertions(+), 200 deletions(-) create mode 100644 packages/react/docs/components/ASGARDEO_PROVIDER.md create mode 100644 packages/react/docs/components/OVERVIEW.md delete mode 100644 packages/react/docs/components/README.md diff --git a/packages/react/docs/README.md b/packages/react/docs/README.md index 8af1702d..b6ad3796 100644 --- a/packages/react/docs/README.md +++ b/packages/react/docs/README.md @@ -16,4 +16,4 @@ The Asgardeo React SDK provides a comprehensive set of hooks, components, and ut ## What's Next -- [Quickstart Guide](./QUICKSTART.md): Get started with a simple integration. +- [Quickstart Guide](./getting-started/README.md): Get started with a simple integration. diff --git a/packages/react/docs/components/ASGARDEO_PROVIDER.md b/packages/react/docs/components/ASGARDEO_PROVIDER.md new file mode 100644 index 00000000..8bc586f6 --- /dev/null +++ b/packages/react/docs/components/ASGARDEO_PROVIDER.md @@ -0,0 +1,249 @@ +# AsgardeoProvider + +The `AsgardeoProvider` is the root context provider component that configures the Asgardeo React SDK and provides authentication context to your entire React application. It must wrap your application to enable authentication features. + +## Overview + +The `AsgardeoProvider` initializes the Asgardeo authentication client, manages authentication state, and provides context to child components through React Context. It handles token management, user sessions, organization switching, and branding preferences automatically. + +## Props + +All props are based on the `AsgardeoReactConfig` interface, which extends the base configuration from `@asgardeo/javascript`. + +### Required Props + +| Prop | Type | Description | +|------|------|-------------| +| `baseUrl` | `string` | The base URL of your Asgardeo organization. Format: `https://api.asgardeo.io/t/{org_name}` | +| `clientId` | `string` | The client ID obtained from your Asgardeo application registration | + +### Optional Props + +| Prop | Type | Default | Description | +|------|------|---------|-------------| +| `afterSignInUrl` | `string` | `window.location.origin` | URL to redirect users after successful sign-in. Must match configured redirect URIs in Asgardeo | +| `afterSignOutUrl` | `string` | `window.location.origin` | URL to redirect users after sign-out. Must match configured post-logout redirect URIs | +| `scopes` | `string \| string[]` | `["openid"]` | OAuth scopes to request during authentication (e.g., `"openid profile email"` or `["openid", "profile", "email"]`) | +| `organizationHandle` | `string` | Organization handle for organization-specific features like branding. Auto-derived from `baseUrl` if not provided. Required for custom domains | +| `applicationId` | `string` | UUID of the Asgardeo application for application-specific branding and features | +| `signInUrl` | `string` | Custom sign-in page URL. If provided, users will be redirected here instead of Asgardeo's default sign-in page | +| `signUpUrl` | `string` | Custom sign-up page URL. If provided, users will be redirected here instead of Asgardeo's default sign-up page | +| `clientSecret` | `string` | Client secret for confidential clients. Not recommended for browser applications | +| `tokenValidation` | `object` | Token validation configuration for ID tokens including validation flags and clock tolerance | +| Prop | Type | Description | +|------|------|-------------| +| `preferences` | `Preferences` | Configuration object for theming, internationalization, and UI customization | + +### Preferences Object + +The `preferences` prop allows you to customize the UI components provided by the SDK. + +#### Theme Preferences (`preferences.theme`) + +| Property | Type | Default | Description | +|----------|------|---------|-------------| +| `inheritFromBranding` | `boolean` | `true` | Whether to inherit theme from Asgardeo organization/application branding | +| `mode` | `'light' \| 'dark' \| 'system'` | `'system'` | Theme mode. `'system'` follows user's OS preference | +| `overrides` | `RecursivePartial` | `{}` | Custom theme overrides for colors, typography, spacing, etc. | + +#### Internationalization Preferences (`preferences.i18n`) + +| Property | Type | Default | Description | +|----------|------|---------|-------------| +| `language` | `string` | Browser default | Language code for UI text (e.g., `'en-US'`, `'es-ES'`) | +| `fallbackLanguage` | `string` | `'en-US'` | Fallback language when translations aren't available | +| `bundles` | `object` | `{}` | Custom translation bundles to override default text | + +## Usage + +### Basic Setup + +```tsx +import React from 'react'; +import { createRoot } from 'react-dom/client'; +import { AsgardeoProvider } from '@asgardeo/react'; +import App from './App'; + +const root = createRoot(document.getElementById('root')); + +root.render( + + + +); +``` + +### Advanced Configuration + +```tsx +import React from 'react'; +import { AsgardeoProvider } from '@asgardeo/react'; +import App from './App'; + +const config = { + baseUrl: "https://api.asgardeo.io/t/your-org", + clientId: "your-client-id", + afterSignInUrl: "https://yourapp.com/dashboard", + afterSignOutUrl: "https://yourapp.com/", + scopes: ["openid", "profile", "email", "groups"], + organizationHandle: "your-org", + applicationId: "app-uuid", + preferences: { + theme: { + mode: "dark", + inheritFromBranding: true, + overrides: { + primary: "#6366f1", + secondary: "#8b5cf6" + } + }, + i18n: { + language: "en-US", + bundles: { + "en-US": { + "signIn.title": "Welcome Back", + "signUp.title": "Join Us" + } + } + } + } +}; + +function MyApp() { + return ( + + + + ); +} +``` + +### Environment Variables + +You can use environment variables for configuration: + +```tsx +const config = { + baseUrl: process.env.REACT_APP_ASGARDEO_BASE_URL, + clientId: process.env.REACT_APP_ASGARDEO_CLIENT_ID, + afterSignInUrl: process.env.REACT_APP_AFTER_SIGN_IN_URL, + afterSignOutUrl: process.env.REACT_APP_AFTER_SIGN_OUT_URL, +}; +``` + +## Features + +### Automatic State Management + +The provider automatically manages: + +- Authentication state (signed in/out) +- User information and profile +- Loading states during authentication operations +- Token refresh and validation +- Organization context and switching + +### Branding Integration + +When `preferences.theme.inheritFromBranding` is enabled (default), the provider: + +- Fetches branding preferences from Asgardeo +- Applies organization/application-specific themes +- Updates theme dynamically based on branding configuration + +### Error Handling + +The provider includes built-in error handling for: + +- Authentication failures +- Token validation errors +- Network connectivity issues +- Configuration validation + +### Organization Support + +For multi-organization scenarios: + +- Automatically detects organization context +- Supports organization switching +- Manages organization-specific branding and settings + +## Context Value + +The provider makes the following context available to child components via the `useAsgardeo` hook: + +```typescript +{ + // Authentication state + isSignedIn: boolean; + isLoading: boolean; + isInitialized: boolean; + user: User | null; + + // Configuration + baseUrl: string; + organizationHandle: string; + applicationId: string; + signInUrl: string; + signUpUrl: string; + afterSignInUrl: string; + + // Authentication methods + signIn: (options?: SignInOptions) => Promise; + signInSilently: (options?: SignInOptions) => Promise; + signOut: (options?: SignOutOptions) => Promise; + signUp: (payload?: SignUpPayload) => Promise; + + // Organization methods + organization: Organization; + + // Utility methods + fetch: (url: string, options?: RequestConfig) => Promise; +} +``` + +## Best Practices + +1. **Wrap at the root**: Place the provider as high as possible in your component tree +2. **Environment-based config**: Use environment variables for different deployment environments +3. **Error boundaries**: Implement error boundaries to handle authentication errors gracefully +4. **Loading states**: Use the `isLoading` state to show appropriate loading indicators +5. **Secure redirects**: Ensure redirect URLs are properly configured in Asgardeo console + +## Common Issues + +### Redirect URI Mismatch + +Ensure `afterSignInUrl` matches exactly with the redirect URIs configured in your Asgardeo application. + +### CORS Issues + +Make sure your domain is allowed in the Asgardeo application's allowed origins. + +### Token Validation Errors + +Check that your `baseUrl` is correct and accessible, and consider adjusting `tokenValidation.idToken.clockTolerance` if needed. + +## TypeScript Support + +The provider is fully typed with TypeScript. Import the types for better development experience: + +```typescript +import { AsgardeoProvider, AsgardeoProviderProps } from '@asgardeo/react'; + +const config: AsgardeoProviderProps = { + baseUrl: "https://api.asgardeo.io/t/your-org", + clientId: "your-client-id" +}; +``` + +## Related + +- [`useAsgardeo`](./USE_ASGARDEO.md) - Hook to access authentication context +- [`SignIn`](./SIGN_IN.md) - Sign-in component +- [`SignOut`](./SIGN_OUT.md) - Sign-out component +- [Theming Guide](../guides/theming.md) - Customizing component appearance +- [Organization Management](../guides/organizations.md) - Working with organizations diff --git a/packages/react/docs/components/OVERVIEW.md b/packages/react/docs/components/OVERVIEW.md new file mode 100644 index 00000000..f2241d44 --- /dev/null +++ b/packages/react/docs/components/OVERVIEW.md @@ -0,0 +1,59 @@ +# Components Overview + +The Asgardeo React SDK provides a comprehensive set of components to handle authentication, user management, and organization features in your React applications. The components are organized into different categories based on their functionality. + +## Root Components + +Root components are the entry points for integrating Asgardeo authentication into your React application. They provide the necessary context and configuration for the SDK. + +- **`AsgardeoProvider`** - The main provider component that wraps your application, providing authentication context and configuration. + +## Action Components + +Action components trigger specific authentication-related actions when users interact with them. + +### Sign-In Components + +- **`SignInButton`** - A customizable button that initiates the sign-in flow +- **`SignUpButton`** - A button for user registration flows +- **`SignOutButton`** - A button that handles user sign-out + +These components support both render props and traditional props patterns, giving you flexibility in how you implement them. + +## Control Components + +Control components manage the conditional rendering of content based on authentication state. + +- **`SignedIn`** - Renders children only when the user is authenticated +- **`SignedOut`** - Renders children only when the user is not authenticated +- **`Loading`** - Shows loading state during authentication operations + +## Presentation Components + +Presentation components display user and organization information with built-in styling and functionality. + +### User Components + +- **`User`** - Provides render props access to user data +- **`UserProfile`** - Displays comprehensive user profile information +- **`UserDropdown`** - A dropdown menu with user info and actions + +### Organization Components + +- **`Organization`** - Displays organization information +- **`OrganizationProfile`** - Shows detailed organization profile +- **`OrganizationSwitcher`** - Allows switching between organizations +- **`OrganizationList`** - Lists available organizations +- **`CreateOrganization`** - Form for creating new organizations + +### Authentication UI Components + +- **`SignIn`** - Complete sign-in form with multiple authentication options +- **`SignUp`** - User registration form + +## Next Steps + +- [Explore Action Components](./actions/) - Learn about sign-in, sign-out, and sign-up buttons +- [Learn Control Components](./control/) - Understand conditional rendering based on auth state +- [Discover Presentation Components](./presentation/) - Explore user and organization display components +- [Customize with Primitives](./primitives/) - Use low-level UI components for custom implementations diff --git a/packages/react/docs/components/README.md b/packages/react/docs/components/README.md deleted file mode 100644 index 66fac4ca..00000000 --- a/packages/react/docs/components/README.md +++ /dev/null @@ -1,199 +0,0 @@ -# Components Overview - -The Asgardeo React SDK provides a comprehensive set of components to handle authentication, user management, and organization features in your React applications. The components are organized into different categories based on their functionality. - -## Component Categories - -### Action Components - -Action components trigger specific authentication-related actions when users interact with them. - -#### Sign-In Components - -- **`SignInButton`** - A customizable button that initiates the sign-in flow -- **`SignUpButton`** - A button for user registration flows -- **`SignOutButton`** - A button that handles user sign-out - -These components support both render props and traditional props patterns, giving you flexibility in how you implement them. - -```tsx -// Render props pattern - - {({signIn, isLoading}) => ( - - )} - - -// Traditional props pattern -Sign In -``` - -### Control Components - -Control components manage the conditional rendering of content based on authentication state. - -- **`SignedIn`** - Renders children only when the user is authenticated -- **`SignedOut`** - Renders children only when the user is not authenticated -- **`AsgardeoLoading`** - Shows loading state during authentication operations - -```tsx - -
Please sign in to continue
-
- - -
Welcome! You are signed in.
-
-``` - -### Presentation Components - -Presentation components display user and organization information with built-in styling and functionality. - -#### User Components - -- **`User`** - Provides render props access to user data -- **`UserProfile`** - Displays comprehensive user profile information -- **`UserDropdown`** - A dropdown menu with user info and actions - -#### Organization Components - -- **`Organization`** - Displays organization information -- **`OrganizationProfile`** - Shows detailed organization profile -- **`OrganizationSwitcher`** - Allows switching between organizations -- **`OrganizationList`** - Lists available organizations -- **`CreateOrganization`** - Form for creating new organizations - -#### Authentication UI Components - -- **`SignIn`** - Complete sign-in form with multiple authentication options -- **`SignUp`** - User registration form - -### Sign-In Options - -The SDK includes specialized components for different authentication methods: - -- **`IdentifierFirst`** - Username/email identification step -- **`UsernamePassword`** - Traditional username/password authentication -- **`EmailOtp`** - Email-based OTP authentication -- **`SmsOtp`** - SMS-based OTP authentication -- **`Totp`** - Time-based OTP authentication - -#### Social Login Components - -- **`GoogleButton`** - Google OAuth sign-in -- **`GitHubButton`** - GitHub OAuth sign-in -- **`MicrosoftButton`** - Microsoft OAuth sign-in -- **`FacebookButton`** - Facebook OAuth sign-in -- **`LinkedInButton`** - LinkedIn OAuth sign-in -- **`SignInWithEthereumButton`** - Ethereum wallet authentication -- **`SocialButton`** - Generic social provider button -- **`MultiOptionButton`** - Button supporting multiple authentication options - -### Primitive Components - -Primitive components are low-level UI building blocks that can be used independently: - -#### Form Components -- **`Button`** - Styled button component -- **`TextField`** - Text input field -- **`PasswordField`** - Password input with visibility toggle -- **`Select`** - Dropdown select component -- **`Checkbox`** - Checkbox input -- **`DatePicker`** - Date selection component -- **`OtpField`** - OTP code input -- **`MultiInput`** - Multiple value input -- **`KeyValueInput`** - Key-value pair input - -#### Layout Components -- **`Card`** - Container card component -- **`FormControl`** - Form field wrapper -- **`Divider`** - Visual separator -- **`Popover`** - Overlay component - -#### Display Components -- **`Typography`** - Text styling component -- **`Avatar`** - User avatar display -- **`Logo`** - Logo component -- **`Alert`** - Alert message component -- **`Spinner`** - Loading spinner -- **`InputLabel`** - Form input labels - -#### Icon Components -- **`Icons`** - Collection of icon components including `BuildingAlt` and others - -### Factory Components - -- **`FieldFactory`** - Dynamically creates form fields based on configuration - -## Component Architecture - -### Base vs. Regular Components - -Many components come in two variants: - -1. **Base Components** (e.g., `BaseSignInButton`, `BaseUserProfile`) - Framework-agnostic components that handle core logic -2. **Regular Components** (e.g., `SignInButton`, `UserProfile`) - React-specific wrappers that integrate with Asgardeo context - -### Render Props Pattern - -Many components support the render props pattern, allowing you to customize the rendering while leveraging the component's logic: - -```tsx - - {(user) => ( -
-

Welcome, {user?.given_name}!

-

Email: {user?.email}

-
- )} -
-``` - -### Context Integration - -Components automatically integrate with the Asgardeo context providers: -- `AsgardeoProvider` - Main authentication context -- `UserProvider` - User data context -- `OrganizationProvider` - Organization context -- `ThemeProvider` - Theming context -- `BrandingProvider` - Branding customization -- `I18nProvider` - Internationalization context - -## Getting Started - -To use these components, wrap your application with the `AsgardeoProvider`: - -```tsx -import { AsgardeoProvider, SignInButton, SignedIn, SignedOut, UserProfile } from '@asgardeo/react' - -function App() { - return ( - - - Sign In - - - - - - - ) -} -``` - -## Browser Support - -All components are designed for client-side React applications (CSR) and require a browser environment. They are not compatible with server-side rendering (SSR) environments. - -## Next Steps - -- [Explore Action Components](./actions/) - Learn about sign-in, sign-out, and sign-up buttons -- [Learn Control Components](./control/) - Understand conditional rendering based on auth state -- [Discover Presentation Components](./presentation/) - Explore user and organization display components -- [Customize with Primitives](./primitives/) - Use low-level UI components for custom implementations From e47c125d6e9e98e1bb73767e6d416246ba2bc69f Mon Sep 17 00:00:00 2001 From: Brion Date: Tue, 8 Jul 2025 15:08:00 +0530 Subject: [PATCH 03/12] docs: enhance ASGardeoProvider documentation with token validation and preferences details --- .../docs/components/ASGARDEO_PROVIDER.md | 206 +++++------------- 1 file changed, 52 insertions(+), 154 deletions(-) diff --git a/packages/react/docs/components/ASGARDEO_PROVIDER.md b/packages/react/docs/components/ASGARDEO_PROVIDER.md index 8bc586f6..5bd249a1 100644 --- a/packages/react/docs/components/ASGARDEO_PROVIDER.md +++ b/packages/react/docs/components/ASGARDEO_PROVIDER.md @@ -29,11 +29,25 @@ All props are based on the `AsgardeoReactConfig` interface, which extends the ba | `signInUrl` | `string` | Custom sign-in page URL. If provided, users will be redirected here instead of Asgardeo's default sign-in page | | `signUpUrl` | `string` | Custom sign-up page URL. If provided, users will be redirected here instead of Asgardeo's default sign-up page | | `clientSecret` | `string` | Client secret for confidential clients. Not recommended for browser applications | -| `tokenValidation` | `object` | Token validation configuration for ID tokens including validation flags and clock tolerance | -| Prop | Type | Description | -|------|------|-------------| +| `tokenValidation` | `TokenValidation` | Token validation configuration for ID tokens including validation flags and clock tolerance | | `preferences` | `Preferences` | Configuration object for theming, internationalization, and UI customization | +### TokenValidation + +The `tokenValidation` prop allows you to configure how ID tokens are validated. + +| Property | Type | Default | Description | +|----------|------|---------|-------------| +| `idToken` | `IdTokenValidation` | `{}` | Configuration for ID token validation | + +#### IdTokenValidation + +| Property | Type | Default | Description | +|----------|------|---------|-------------| +| `validate` | `boolean` | `true` | Whether to validate the ID token | +| `validateIssuer` | `boolean` | `true` | Whether to validate the issuer | +| `clockTolerance` | `number` | `300` | Allowed clock skew in seconds | + ### Preferences Object The `preferences` prop allows you to customize the UI components provided by the SDK. @@ -44,7 +58,7 @@ The `preferences` prop allows you to customize the UI components provided by the |----------|------|---------|-------------| | `inheritFromBranding` | `boolean` | `true` | Whether to inherit theme from Asgardeo organization/application branding | | `mode` | `'light' \| 'dark' \| 'system'` | `'system'` | Theme mode. `'system'` follows user's OS preference | -| `overrides` | `RecursivePartial` | `{}` | Custom theme overrides for colors, typography, spacing, etc. | +| `overrides` | `ThemeConfig` | `{}` | Custom theme overrides for colors, typography, spacing, etc. | #### Internationalization Preferences (`preferences.i18n`) @@ -83,38 +97,36 @@ import React from 'react'; import { AsgardeoProvider } from '@asgardeo/react'; import App from './App'; -const config = { - baseUrl: "https://api.asgardeo.io/t/your-org", - clientId: "your-client-id", - afterSignInUrl: "https://yourapp.com/dashboard", - afterSignOutUrl: "https://yourapp.com/", - scopes: ["openid", "profile", "email", "groups"], - organizationHandle: "your-org", - applicationId: "app-uuid", - preferences: { - theme: { - mode: "dark", - inheritFromBranding: true, - overrides: { - primary: "#6366f1", - secondary: "#8b5cf6" - } - }, - i18n: { - language: "en-US", - bundles: { - "en-US": { - "signIn.title": "Welcome Back", - "signUp.title": "Join Us" - } - } - } - } -}; - function MyApp() { return ( - + ); @@ -126,124 +138,10 @@ function MyApp() { You can use environment variables for configuration: ```tsx -const config = { - baseUrl: process.env.REACT_APP_ASGARDEO_BASE_URL, - clientId: process.env.REACT_APP_ASGARDEO_CLIENT_ID, - afterSignInUrl: process.env.REACT_APP_AFTER_SIGN_IN_URL, - afterSignOutUrl: process.env.REACT_APP_AFTER_SIGN_OUT_URL, -}; -``` - -## Features - -### Automatic State Management - -The provider automatically manages: - -- Authentication state (signed in/out) -- User information and profile -- Loading states during authentication operations -- Token refresh and validation -- Organization context and switching - -### Branding Integration - -When `preferences.theme.inheritFromBranding` is enabled (default), the provider: - -- Fetches branding preferences from Asgardeo -- Applies organization/application-specific themes -- Updates theme dynamically based on branding configuration - -### Error Handling - -The provider includes built-in error handling for: - -- Authentication failures -- Token validation errors -- Network connectivity issues -- Configuration validation - -### Organization Support - -For multi-organization scenarios: - -- Automatically detects organization context -- Supports organization switching -- Manages organization-specific branding and settings - -## Context Value - -The provider makes the following context available to child components via the `useAsgardeo` hook: - -```typescript -{ - // Authentication state - isSignedIn: boolean; - isLoading: boolean; - isInitialized: boolean; - user: User | null; - - // Configuration - baseUrl: string; - organizationHandle: string; - applicationId: string; - signInUrl: string; - signUpUrl: string; - afterSignInUrl: string; - - // Authentication methods - signIn: (options?: SignInOptions) => Promise; - signInSilently: (options?: SignInOptions) => Promise; - signOut: (options?: SignOutOptions) => Promise; - signUp: (payload?: SignUpPayload) => Promise; - - // Organization methods - organization: Organization; - - // Utility methods - fetch: (url: string, options?: RequestConfig) => Promise; -} + + + ``` - -## Best Practices - -1. **Wrap at the root**: Place the provider as high as possible in your component tree -2. **Environment-based config**: Use environment variables for different deployment environments -3. **Error boundaries**: Implement error boundaries to handle authentication errors gracefully -4. **Loading states**: Use the `isLoading` state to show appropriate loading indicators -5. **Secure redirects**: Ensure redirect URLs are properly configured in Asgardeo console - -## Common Issues - -### Redirect URI Mismatch - -Ensure `afterSignInUrl` matches exactly with the redirect URIs configured in your Asgardeo application. - -### CORS Issues - -Make sure your domain is allowed in the Asgardeo application's allowed origins. - -### Token Validation Errors - -Check that your `baseUrl` is correct and accessible, and consider adjusting `tokenValidation.idToken.clockTolerance` if needed. - -## TypeScript Support - -The provider is fully typed with TypeScript. Import the types for better development experience: - -```typescript -import { AsgardeoProvider, AsgardeoProviderProps } from '@asgardeo/react'; - -const config: AsgardeoProviderProps = { - baseUrl: "https://api.asgardeo.io/t/your-org", - clientId: "your-client-id" -}; -``` - -## Related - -- [`useAsgardeo`](./USE_ASGARDEO.md) - Hook to access authentication context -- [`SignIn`](./SIGN_IN.md) - Sign-in component -- [`SignOut`](./SIGN_OUT.md) - Sign-out component -- [Theming Guide](../guides/theming.md) - Customizing component appearance -- [Organization Management](../guides/organizations.md) - Working with organizations From c228836010148f1ee689cb970f05668ea0c2dac3 Mon Sep 17 00:00:00 2001 From: Brion Date: Tue, 8 Jul 2025 15:11:27 +0530 Subject: [PATCH 04/12] docs: update ASGardeoProvider documentation to include detailed links for tokenValidation and preferences props --- packages/react/docs/components/ASGARDEO_PROVIDER.md | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/packages/react/docs/components/ASGARDEO_PROVIDER.md b/packages/react/docs/components/ASGARDEO_PROVIDER.md index 5bd249a1..d6221d24 100644 --- a/packages/react/docs/components/ASGARDEO_PROVIDER.md +++ b/packages/react/docs/components/ASGARDEO_PROVIDER.md @@ -29,8 +29,12 @@ All props are based on the `AsgardeoReactConfig` interface, which extends the ba | `signInUrl` | `string` | Custom sign-in page URL. If provided, users will be redirected here instead of Asgardeo's default sign-in page | | `signUpUrl` | `string` | Custom sign-up page URL. If provided, users will be redirected here instead of Asgardeo's default sign-up page | | `clientSecret` | `string` | Client secret for confidential clients. Not recommended for browser applications | -| `tokenValidation` | `TokenValidation` | Token validation configuration for ID tokens including validation flags and clock tolerance | -| `preferences` | `Preferences` | Configuration object for theming, internationalization, and UI customization | +| `tokenValidation` | `[TokenValidation](#tokenvalidation)` | Token validation configuration for ID tokens including validation flags and clock tolerance | +| `preferences` | `[Preferences](#preferences)` | Configuration object for theming, internationalization, and UI customization | + +
+ +TokenValidation ### TokenValidation @@ -48,7 +52,9 @@ The `tokenValidation` prop allows you to configure how ID tokens are validated. | `validateIssuer` | `boolean` | `true` | Whether to validate the issuer | | `clockTolerance` | `number` | `300` | Allowed clock skew in seconds | -### Preferences Object +
+ +### Preferences The `preferences` prop allows you to customize the UI components provided by the SDK. From f54252f47335a6aade3f06fd47bc969a784d5591 Mon Sep 17 00:00:00 2001 From: Brion Date: Tue, 8 Jul 2025 15:12:34 +0530 Subject: [PATCH 05/12] docs: update TokenValidation section header to improve visibility --- packages/react/docs/components/ASGARDEO_PROVIDER.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/react/docs/components/ASGARDEO_PROVIDER.md b/packages/react/docs/components/ASGARDEO_PROVIDER.md index d6221d24..7defe5b4 100644 --- a/packages/react/docs/components/ASGARDEO_PROVIDER.md +++ b/packages/react/docs/components/ASGARDEO_PROVIDER.md @@ -34,7 +34,7 @@ All props are based on the `AsgardeoReactConfig` interface, which extends the ba
-TokenValidation +

TokenValidation

### TokenValidation From f44253e5048d697476b24d248fbae0c559eae039 Mon Sep 17 00:00:00 2001 From: Brion Date: Tue, 8 Jul 2025 15:15:25 +0530 Subject: [PATCH 06/12] docs: reorganize props section in ASGardeoProvider documentation for clarity and consistency --- .../docs/components/ASGARDEO_PROVIDER.md | 35 +++++++++---------- 1 file changed, 16 insertions(+), 19 deletions(-) diff --git a/packages/react/docs/components/ASGARDEO_PROVIDER.md b/packages/react/docs/components/ASGARDEO_PROVIDER.md index 7defe5b4..91b62bb1 100644 --- a/packages/react/docs/components/ASGARDEO_PROVIDER.md +++ b/packages/react/docs/components/ASGARDEO_PROVIDER.md @@ -12,31 +12,24 @@ All props are based on the `AsgardeoReactConfig` interface, which extends the ba ### Required Props -| Prop | Type | Description | -|------|------|-------------| -| `baseUrl` | `string` | The base URL of your Asgardeo organization. Format: `https://api.asgardeo.io/t/{org_name}` | -| `clientId` | `string` | The client ID obtained from your Asgardeo application registration | - -### Optional Props - | Prop | Type | Default | Description | |------|------|---------|-------------| +| `baseUrl` | `string` | **REQUIRED** | The base URL of your Asgardeo organization. Format: `https://api.asgardeo.io/t/{org_name}` | +| `clientId` | `string` | **REQUIRED** | The client ID obtained from your Asgardeo application registration | | `afterSignInUrl` | `string` | `window.location.origin` | URL to redirect users after successful sign-in. Must match configured redirect URIs in Asgardeo | | `afterSignOutUrl` | `string` | `window.location.origin` | URL to redirect users after sign-out. Must match configured post-logout redirect URIs | -| `scopes` | `string \| string[]` | `["openid"]` | OAuth scopes to request during authentication (e.g., `"openid profile email"` or `["openid", "profile", "email"]`) | -| `organizationHandle` | `string` | Organization handle for organization-specific features like branding. Auto-derived from `baseUrl` if not provided. Required for custom domains | -| `applicationId` | `string` | UUID of the Asgardeo application for application-specific branding and features | -| `signInUrl` | `string` | Custom sign-in page URL. If provided, users will be redirected here instead of Asgardeo's default sign-in page | -| `signUpUrl` | `string` | Custom sign-up page URL. If provided, users will be redirected here instead of Asgardeo's default sign-up page | -| `clientSecret` | `string` | Client secret for confidential clients. Not recommended for browser applications | -| `tokenValidation` | `[TokenValidation](#tokenvalidation)` | Token validation configuration for ID tokens including validation flags and clock tolerance | -| `preferences` | `[Preferences](#preferences)` | Configuration object for theming, internationalization, and UI customization | +| `scopes` | `string \| string[]` | `["openid profile internal_login"]` | OAuth scopes to request during authentication (e.g., `"openid profile email"` or `["openid", "profile", "email"]`) | +| `organizationHandle` | `string` | - | Organization handle for organization-specific features like branding. Auto-derived from `baseUrl` if not provided. Required for custom domains | +| `applicationId` | `string` | - | UUID of the Asgardeo application for application-specific branding and features | +| `signInUrl` | `string` | - | Custom sign-in page URL. If provided, users will be redirected here instead of Asgardeo's default sign-in page | +| `signUpUrl` | `string` | - | Custom sign-up page URL. If provided, users will be redirected here instead of Asgardeo's default sign-up page | +| `clientSecret` | `string` | - | Client secret for confidential clients. Not recommended for browser applications | +| `tokenValidation` | `[TokenValidation](#tokenvalidation)` | - | Token validation configuration for ID tokens including validation flags and clock tolerance | +| `preferences` | `[Preferences](#preferences)` | - | Configuration object for theming, internationalization, and UI customization |
-

TokenValidation

- -### TokenValidation +

TokenValidation

The `tokenValidation` prop allows you to configure how ID tokens are validated. @@ -54,7 +47,9 @@ The `tokenValidation` prop allows you to configure how ID tokens are validated.
-### Preferences +
+ +

Preferences

The `preferences` prop allows you to customize the UI components provided by the SDK. @@ -74,6 +69,8 @@ The `preferences` prop allows you to customize the UI components provided by the | `fallbackLanguage` | `string` | `'en-US'` | Fallback language when translations aren't available | | `bundles` | `object` | `{}` | Custom translation bundles to override default text | +
+ ## Usage ### Basic Setup From 8adec868dc60d7a15ad7e57b2aa577e0e6b2d744 Mon Sep 17 00:00:00 2001 From: Brion Date: Tue, 8 Jul 2025 15:15:52 +0530 Subject: [PATCH 07/12] docs: update props section in ASGardeoProvider documentation for tokenValidation and preferences --- packages/react/docs/components/ASGARDEO_PROVIDER.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/react/docs/components/ASGARDEO_PROVIDER.md b/packages/react/docs/components/ASGARDEO_PROVIDER.md index 91b62bb1..c92d83e2 100644 --- a/packages/react/docs/components/ASGARDEO_PROVIDER.md +++ b/packages/react/docs/components/ASGARDEO_PROVIDER.md @@ -24,8 +24,8 @@ All props are based on the `AsgardeoReactConfig` interface, which extends the ba | `signInUrl` | `string` | - | Custom sign-in page URL. If provided, users will be redirected here instead of Asgardeo's default sign-in page | | `signUpUrl` | `string` | - | Custom sign-up page URL. If provided, users will be redirected here instead of Asgardeo's default sign-up page | | `clientSecret` | `string` | - | Client secret for confidential clients. Not recommended for browser applications | -| `tokenValidation` | `[TokenValidation](#tokenvalidation)` | - | Token validation configuration for ID tokens including validation flags and clock tolerance | -| `preferences` | `[Preferences](#preferences)` | - | Configuration object for theming, internationalization, and UI customization | +| `tokenValidation` | [TokenValidation](#tokenvalidation) | - | Token validation configuration for ID tokens including validation flags and clock tolerance | +| `preferences` | [Preferences](#preferences) | - | Configuration object for theming, internationalization, and UI customization |
From fdaea9072c5a626efe465ff4d22ed687921981c3 Mon Sep 17 00:00:00 2001 From: Brion Date: Tue, 8 Jul 2025 17:47:03 +0530 Subject: [PATCH 08/12] feat(react): expose `http` from `useAsgardeo` --- packages/react/src/AsgardeoReactClient.ts | 13 ++- packages/react/src/__temp__/api.ts | 3 - .../src/contexts/Asgardeo/AsgardeoContext.ts | 25 ++++-- .../contexts/Asgardeo/AsgardeoProvider.tsx | 83 +++++++++---------- 4 files changed, 66 insertions(+), 58 deletions(-) diff --git a/packages/react/src/AsgardeoReactClient.ts b/packages/react/src/AsgardeoReactClient.ts index 9b2ae5a1..f620a5a8 100644 --- a/packages/react/src/AsgardeoReactClient.ts +++ b/packages/react/src/AsgardeoReactClient.ts @@ -213,7 +213,6 @@ class AsgardeoReactClient e return this.withLoading(async () => { try { const configData = await this.asgardeo.getConfigData(); - const scopes = configData?.scopes; if (!organization.id) { throw new AsgardeoRuntimeError( @@ -241,7 +240,6 @@ class AsgardeoReactClient e return (await this.asgardeo.exchangeToken( exchangeConfig, (user: User) => {}, - () => null, )) as TokenResponse | Response; } catch (error) { throw new AsgardeoRuntimeError( @@ -350,11 +348,12 @@ class AsgardeoReactClient e ); } - async fetch(url: string, options?: HttpRequestConfig): Promise> { - return this.asgardeo.httpRequest({ - url, - ...options, - }); + async request(requestConfig?: HttpRequestConfig): Promise> { + return this.asgardeo.httpRequest(requestConfig); + } + + async requestAll(requestConfigs?: HttpRequestConfig[]): Promise[]> { + return this.asgardeo.httpRequestAll(requestConfigs); } } diff --git a/packages/react/src/__temp__/api.ts b/packages/react/src/__temp__/api.ts index d1784703..e9878d8b 100644 --- a/packages/react/src/__temp__/api.ts +++ b/packages/react/src/__temp__/api.ts @@ -229,7 +229,6 @@ class AuthAPI { public exchangeToken( config: SPACustomGrantConfig, callback: (response: User | Response) => void, - dispatch: (state: AuthStateInterface) => void, ): Promise { return this._client .exchangeToken(config) @@ -245,8 +244,6 @@ class AuthAPI { isSignedIn: true, isLoading: false, }); - - dispatch({...(response as User), isSignedIn: true, isLoading: false}); } callback && callback(response); diff --git a/packages/react/src/contexts/Asgardeo/AsgardeoContext.ts b/packages/react/src/contexts/Asgardeo/AsgardeoContext.ts index ea947754..ac550625 100644 --- a/packages/react/src/contexts/Asgardeo/AsgardeoContext.ts +++ b/packages/react/src/contexts/Asgardeo/AsgardeoContext.ts @@ -61,12 +61,24 @@ export type AsgardeoContextProps = { user: any; organization: Organization; /** - * Custom fetch function to make HTTP requests. - * @param url - The URL to fetch. - * @param options - Optional configuration for the HTTP request. + * HTTP request function to make API calls. + * @param requestConfig - Configuration for the HTTP request. * @returns A promise that resolves to the HTTP response. */ - fetch: (url: string, options?: HttpRequestConfig) => Promise>; + http: { + /** + * Makes an HTTP request using the provided configuration. + * @param requestConfig - Configuration for the HTTP request. + * @returns A promise that resolves to the HTTP response. + */ + request: (requestConfig?: HttpRequestConfig) => Promise>; + /** + * Makes multiple HTTP requests based on the provided configuration. + * @param requestConfigs - Set of configurations for the HTTP requests. + * @returns A promise that resolves to an array of HTTP responses. + */ + requestAll: (requestConfigs?: HttpRequestConfig[]) => Promise[]>; + }; }; /** @@ -88,7 +100,10 @@ const AsgardeoContext: Context = createContext null, + http: { + request: () => null, + requestAll: () => null, + }, }); AsgardeoContext.displayName = 'AsgardeoContext'; diff --git a/packages/react/src/contexts/Asgardeo/AsgardeoProvider.tsx b/packages/react/src/contexts/Asgardeo/AsgardeoProvider.tsx index c587d396..3d61073b 100644 --- a/packages/react/src/contexts/Asgardeo/AsgardeoProvider.tsx +++ b/packages/react/src/contexts/Asgardeo/AsgardeoProvider.tsx @@ -18,18 +18,14 @@ import { AsgardeoRuntimeError, - EmbeddedFlowExecuteRequestPayload, - EmbeddedFlowExecuteResponse, generateFlattenedUserProfile, Organization, SignInOptions, - SignOutOptions, User, UserProfile, getBrandingPreference, GetBrandingPreferenceConfig, BrandingPreference, - HttpRequestConfig, } from '@asgardeo/browser'; import {FC, RefObject, PropsWithChildren, ReactElement, useEffect, useMemo, useRef, useState, useCallback} from 'react'; import AsgardeoContext from './AsgardeoContext'; @@ -339,22 +335,6 @@ const AsgardeoProvider: FC> = ({ } }; - const signUp = async (payload?: EmbeddedFlowExecuteRequestPayload): Promise => { - try { - return await asgardeo.signUp(payload); - } catch (error) { - throw new AsgardeoRuntimeError( - `Error while signing up: ${error.message || error}`, - 'asgardeo-signUp-Error', - 'react', - 'An error occurred while trying to sign up.', - ); - } - }; - - const signOut = async (options?: SignOutOptions, afterSignOut?: () => void): Promise => - asgardeo.signOut(options, afterSignOut); - const switchOrganization = async (organization: Organization): Promise => { try { setIsLoadingSync(true); @@ -391,31 +371,48 @@ const AsgardeoProvider: FC> = ({ })); }; - const fetch = async (url: string, options?: HttpRequestConfig): Promise => { - return asgardeo.fetch(url, options); - }; + const value = useMemo( + () => ({ + applicationId, + organizationHandle: config?.organizationHandle, + signInUrl, + signUpUrl, + afterSignInUrl, + baseUrl, + isInitialized: isInitializedSync, + isLoading: isLoadingSync, + isSignedIn: isSignedInSync, + organization: currentOrganization, + signIn, + signInSilently, + signOut: asgardeo.signOut.bind(asgardeo), + signUp: asgardeo.signUp.bind(asgardeo), + user, + http: { + request: asgardeo.request.bind(asgardeo), + requestAll: asgardeo.requestAll.bind(asgardeo), + }, + }), + [ + applicationId, + config?.organizationHandle, + signInUrl, + signUpUrl, + afterSignInUrl, + baseUrl, + isInitializedSync, + isLoadingSync, + isSignedInSync, + currentOrganization, + signIn, + signInSilently, + user, + asgardeo, + ], + ); return ( - + Date: Tue, 8 Jul 2025 18:25:26 +0530 Subject: [PATCH 09/12] feat(react): expose `getAccessToken` --- packages/browser/src/__legacy__/client.ts | 4 +- .../__legacy__/clients/main-thread-client.ts | 2 +- .../helpers/authentication-helper.ts | 4 +- .../browser/src/__legacy__/models/client.ts | 2 +- .../src/AsgardeoJavaScriptClient.ts | 2 + packages/javascript/src/models/client.ts | 7 + .../docs/guides/ACCESS_PROTECTED_APIS.md | 264 ++++++++++++++++++ packages/react/src/AsgardeoReactClient.ts | 9 +- packages/react/src/__temp__/api.ts | 6 +- .../contexts/Asgardeo/AsgardeoProvider.tsx | 1 + 10 files changed, 287 insertions(+), 14 deletions(-) create mode 100644 packages/react/docs/guides/ACCESS_PROTECTED_APIS.md diff --git a/packages/browser/src/__legacy__/client.ts b/packages/browser/src/__legacy__/client.ts index 0d24c47e..f4b0292e 100755 --- a/packages/browser/src/__legacy__/client.ts +++ b/packages/browser/src/__legacy__/client.ts @@ -813,7 +813,7 @@ export class AsgardeoSPAClient { * * @preserve */ - public async getAccessToken(): Promise { + public async getAccessToken(sessionId?: string): Promise { await this._validateMethod(); if (this._storage && [(BrowserStorage.WebWorker, BrowserStorage.BrowserMemory)].includes(this._storage)) { @@ -827,7 +827,7 @@ export class AsgardeoSPAClient { } const mainThreadClient = this._client as MainThreadClientInterface; - return mainThreadClient.getAccessToken(); + return mainThreadClient.getAccessToken(sessionId); } /** diff --git a/packages/browser/src/__legacy__/clients/main-thread-client.ts b/packages/browser/src/__legacy__/clients/main-thread-client.ts index 72573016..0bdb7222 100755 --- a/packages/browser/src/__legacy__/clients/main-thread-client.ts +++ b/packages/browser/src/__legacy__/clients/main-thread-client.ts @@ -380,7 +380,7 @@ export const MainThreadClient = async ( const getOpenIDProviderEndpoints = async (): Promise => _authenticationHelper.getOpenIDProviderEndpoints(); - const getAccessToken = async (): Promise => _authenticationHelper.getAccessToken(); + const getAccessToken = async (sessionId?: string): Promise => _authenticationHelper.getAccessToken(sessionId); const getStorageManager = async (): Promise> => _authenticationHelper.getStorageManager(); diff --git a/packages/browser/src/__legacy__/helpers/authentication-helper.ts b/packages/browser/src/__legacy__/helpers/authentication-helper.ts index 6a556bf5..dc75514a 100644 --- a/packages/browser/src/__legacy__/helpers/authentication-helper.ts +++ b/packages/browser/src/__legacy__/helpers/authentication-helper.ts @@ -679,8 +679,8 @@ export class AuthenticationHelper { - return this._authenticationClient.getAccessToken(); + public async getAccessToken(sessionId?: string): Promise { + return this._authenticationClient.getAccessToken(sessionId); } public async getIDPAccessToken(): Promise { diff --git a/packages/browser/src/__legacy__/models/client.ts b/packages/browser/src/__legacy__/models/client.ts index 023f5d1b..72c2b746 100755 --- a/packages/browser/src/__legacy__/models/client.ts +++ b/packages/browser/src/__legacy__/models/client.ts @@ -64,7 +64,7 @@ export interface MainThreadClientInterface { getConfigData(): Promise>; getIdToken(): Promise; getOpenIDProviderEndpoints(): Promise; - getAccessToken(): Promise; + getAccessToken(sessionId?: string): Promise; getStorageManager(): Promise>; isSignedIn(): Promise; reInitialize(config: Partial>): Promise; diff --git a/packages/javascript/src/AsgardeoJavaScriptClient.ts b/packages/javascript/src/AsgardeoJavaScriptClient.ts index 97d3db18..50d1013e 100644 --- a/packages/javascript/src/AsgardeoJavaScriptClient.ts +++ b/packages/javascript/src/AsgardeoJavaScriptClient.ts @@ -78,6 +78,8 @@ abstract class AsgardeoJavaScriptClient implements AsgardeoClient abstract signUp(options?: SignUpOptions): Promise; abstract signUp(payload: EmbeddedFlowExecuteRequestPayload): Promise; abstract signUp(payload?: unknown): Promise | Promise; + + abstract getAccessToken(sessionId?: string): Promise; } export default AsgardeoJavaScriptClient; diff --git a/packages/javascript/src/models/client.ts b/packages/javascript/src/models/client.ts index ee497f55..a6c28c06 100644 --- a/packages/javascript/src/models/client.ts +++ b/packages/javascript/src/models/client.ts @@ -187,4 +187,11 @@ export interface AsgardeoClient { * @returns A promise that resolves to an EmbeddedFlowExecuteResponse containing the flow execution details. */ signUp(payload: EmbeddedFlowExecuteRequestPayload): Promise; + + /** + * Retrieves the access token for the current session. + * @param sessionId - Optional session ID to retrieve the access token for a specific session. + * @returns A promise that resolves to the access token string. + */ + getAccessToken(sessionId?: string): Promise; } diff --git a/packages/react/docs/guides/ACCESS_PROTECTED_APIS.md b/packages/react/docs/guides/ACCESS_PROTECTED_APIS.md new file mode 100644 index 00000000..ac7ae391 --- /dev/null +++ b/packages/react/docs/guides/ACCESS_PROTECTED_APIS.md @@ -0,0 +1,264 @@ +# Accessing Protected APIs + +This guide shows how to make authenticated API calls to protected resources using the Asgardeo React SDK. The SDK provides an authenticated `http` module that automatically handles authentication headers and token refresh. + +## Overview + +When your application is wrapped with `AsgardeoProvider`, you can use the `useAsgardeo` hook to access the authenticated `http` module. This module has the following features: + +- Includes the necessary authentication headers (Bearer token) +- Handles token refresh when tokens expire +- Provides methods like `request()` and `requestAll()` for making API calls + +## Basic Usage + +```tsx +import React, { useEffect, useState } from 'react'; +import { useAsgardeo } from '@asgardeo/react'; + +export default function UserProfile() { + const { http, isSignedIn } = useAsgardeo(); + const [userData, setUserData] = useState(null); + + useEffect(() => { + if (!isSignedIn) { + return; + } + + (async () => { + try { + const response = await http.request({ + url: 'https://api.asgardeo.io/t//scim2/Me', + headers: { + Accept: 'application/json', + 'Content-Type': 'application/scim+json', + }, + method: 'GET', + }); + + setUserData(response.data); + } catch (error) { + console.error('Error fetching user data:', error); + } + })(); + }, [http, isSignedIn]); + + if (!isSignedIn) { + return
Please sign in to view your profile.
; + } + + return ( +
+

User Profile

+ {userData && ( +
{JSON.stringify(userData, null, 2)}
+ )} +
+ ); +} +``` + +## Multiple API Calls with `requestAll()` + +When you need to make multiple API calls simultaneously, you can use the `http.requestAll()` method: + +```tsx +import React, { useEffect, useState } from 'react'; +import { useAsgardeo } from '@asgardeo/react'; + +export default function UserProfile() { + const { http, isSignedIn } = useAsgardeo(); + const [userData, setUserData] = useState({ + profile: null, + discoverableApplications: [], + }); + + useEffect(() => { + if (!isSignedIn) { + return; + } + + const requests = []; + + requests.push({ + headers: { + Accept: 'application/json', + 'Content-Type': 'application/json', + }, + method: 'GET', + url: 'https://api.asgardeo.io/t//api/users/v1/me/applications', + }); + + requests.push({ + headers: { + Accept: 'application/json', + 'Content-Type': 'application/scim+json', + }, + method: 'GET', + url: 'https://api.asgardeo.io/t//scim2/Me', + }); + + (async () => { + try { + const response = await http.requestAll(requests); + + setUserData({ + discoverableApplications: response[0].data.applications, + profile: response[1].data, + }); + } catch (error) { + console.error('Error fetching data:', error); + } + })(); + }, [http, isSignedIn]); + + return
{JSON.stringify(userData, null, 4)}
; +} +``` + +## Making Different Types of API Calls + +### GET Request + +```tsx +const fetchUsers = async () => { + try { + const response = await http.request({ + url: 'https://api.asgardeo.io/t//scim2/Users', + headers: { + Accept: 'application/json', + 'Content-Type': 'application/scim+json', + }, + method: 'GET', + }); + + return response.data; + } catch (error) { + console.error('Error fetching users:', error); + throw error; + } +}; +``` + +### POST Request + +```tsx +const createUser = async (userData) => { + try { + const response = await http.request({ + url: 'https://api.asgardeo.io/t//scim2/Users', + headers: { + Accept: 'application/json', + 'Content-Type': 'application/scim+json', + }, + method: 'POST', + data: userData, + }); + + return response.data; + } catch (error) { + console.error('Error creating user:', error); + throw error; + } +}; +``` + +### PUT Request + +```tsx +const updateUser = async (userId, userData) => { + try { + const response = await http.request({ + url: `https://api.asgardeo.io/t//scim2/Users/${userId}`, + headers: { + Accept: 'application/json', + 'Content-Type': 'application/scim+json', + }, + method: 'PUT', + data: userData, + }); + + return response.data; + } catch (error) { + console.error('Error updating user:', error); + throw error; + } +}; +``` + +### DELETE Request + +```tsx +const deleteUser = async (userId) => { + try { + const response = await http.request({ + url: `https://api.asgardeo.io/t//scim2/Users/${userId}`, + headers: { + Accept: 'application/json', + }, + method: 'DELETE', + }); + + return true; + } catch (error) { + console.error('Error deleting user:', error); + throw error; + } +}; +``` + +## Bring your own HTTP Client + +If you prefer to use your own HTTP client (like the native `fetch` API), you can use the `getAccessToken()` method to manually add the authorization header: + +```tsx +import React, { useEffect, useState } from 'react'; +import { useAsgardeo } from '@asgardeo/react'; + +export default function UserProfile() { + const { isSignedIn, getAccessToken } = useAsgardeo(); + const [userData, setUserData] = useState(null); + + useEffect(() => { + if (!isSignedIn) { + return; + } + + (async () => { + try { + const response = await fetch('https://api.asgardeo.io/t//scim2/Me', { + headers: { + Accept: 'application/json', + 'Content-Type': 'application/scim+json', + Authorization: `Bearer ${await getAccessToken()}`, + }, + method: 'GET', + }); + + if (!response.ok) { + throw new Error(`HTTP error! status: ${response.status}`); + } + + const responseData = await response.json(); + + setUserData(responseData); + } catch (error) { + console.error('Error fetching data:', error); + } + })(); + }, [isSignedIn, getAccessToken]); + + if (!isSignedIn) { + return
Please sign in to view your profile.
; + } + + return ( +
+

User Profile

+ {userData && ( +
{JSON.stringify(userData, null, 2)}
+ )} +
+ ); +} +``` diff --git a/packages/react/src/AsgardeoReactClient.ts b/packages/react/src/AsgardeoReactClient.ts index f620a5a8..f605d968 100644 --- a/packages/react/src/AsgardeoReactClient.ts +++ b/packages/react/src/AsgardeoReactClient.ts @@ -237,10 +237,7 @@ class AsgardeoReactClient e signInRequired: true, }; - return (await this.asgardeo.exchangeToken( - exchangeConfig, - (user: User) => {}, - )) as TokenResponse | Response; + return (await this.asgardeo.exchangeToken(exchangeConfig, (user: User) => {})) as TokenResponse | Response; } catch (error) { throw new AsgardeoRuntimeError( `Failed to switch organization: ${error.message || error}`, @@ -355,6 +352,10 @@ class AsgardeoReactClient e async requestAll(requestConfigs?: HttpRequestConfig[]): Promise[]> { return this.asgardeo.httpRequestAll(requestConfigs); } + + override async getAccessToken(sessionId?: string): Promise { + return this.asgardeo.getAccessToken(sessionId); + } } export default AsgardeoReactClient; diff --git a/packages/react/src/__temp__/api.ts b/packages/react/src/__temp__/api.ts index e9878d8b..f9dc3834 100644 --- a/packages/react/src/__temp__/api.ts +++ b/packages/react/src/__temp__/api.ts @@ -29,8 +29,6 @@ import { OIDCEndpoints, SignInConfig, SPACustomGrantConfig, - initializeEmbeddedSignInFlow, - processOpenIDScopes, } from '@asgardeo/browser'; import {AuthStateInterface} from './models'; @@ -323,8 +321,8 @@ class AuthAPI { * * @return {Promise} - A Promise that resolves with the access token. */ - public async getAccessToken(): Promise { - return this._client.getAccessToken(); + public async getAccessToken(sessionId?: string): Promise { + return this._client.getAccessToken(sessionId); } /** diff --git a/packages/react/src/contexts/Asgardeo/AsgardeoProvider.tsx b/packages/react/src/contexts/Asgardeo/AsgardeoProvider.tsx index 3d61073b..b6c55d37 100644 --- a/packages/react/src/contexts/Asgardeo/AsgardeoProvider.tsx +++ b/packages/react/src/contexts/Asgardeo/AsgardeoProvider.tsx @@ -379,6 +379,7 @@ const AsgardeoProvider: FC> = ({ signUpUrl, afterSignInUrl, baseUrl, + getAccessToken: asgardeo.getAccessToken.bind(asgardeo), isInitialized: isInitializedSync, isLoading: isLoadingSync, isSignedIn: isSignedInSync, From 1d4f6e631a96b3e59e8c4be08b227ca6360a990f Mon Sep 17 00:00:00 2001 From: Brion Date: Tue, 8 Jul 2025 18:25:37 +0530 Subject: [PATCH 10/12] docs: update environment variable placeholder for organization name in QUICKSTART and README docs: modify default scopes format in ASGardeoProvider documentation --- packages/nextjs/QUICKSTART.md | 2 +- packages/nextjs/README.md | 2 +- packages/react/docs/components/ASGARDEO_PROVIDER.md | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/nextjs/QUICKSTART.md b/packages/nextjs/QUICKSTART.md index 4ef1d3b4..7781965d 100644 --- a/packages/nextjs/QUICKSTART.md +++ b/packages/nextjs/QUICKSTART.md @@ -72,7 +72,7 @@ Create a `.env` file in your project root and add the following environment vari **.env** ```bash -NEXT_PUBLIC_ASGARDEO_BASE_URL="https://api.asgardeo.io/t/" +NEXT_PUBLIC_ASGARDEO_BASE_URL="https://api.asgardeo.io/t/" NEXT_PUBLIC_ASGARDEO_CLIENT_ID="" ASGARDEO_CLIENT_SECRET="" ``` diff --git a/packages/nextjs/README.md b/packages/nextjs/README.md index 7d24da4b..336a678a 100644 --- a/packages/nextjs/README.md +++ b/packages/nextjs/README.md @@ -28,7 +28,7 @@ yarn add @asgardeo/nextjs 1. Create a `.env.local` file with your Asgardeo configuration: ```bash -NEXT_PUBLIC_ASGARDEO_BASE_URL=https://api.asgardeo.io/t/ +NEXT_PUBLIC_ASGARDEO_BASE_URL=https://api.asgardeo.io/t/ NEXT_PUBLIC_ASGARDEO_CLIENT_ID= NEXT_PUBLIC_ASGARDEO_CLIENT_SECRET= ``` diff --git a/packages/react/docs/components/ASGARDEO_PROVIDER.md b/packages/react/docs/components/ASGARDEO_PROVIDER.md index c92d83e2..a4000622 100644 --- a/packages/react/docs/components/ASGARDEO_PROVIDER.md +++ b/packages/react/docs/components/ASGARDEO_PROVIDER.md @@ -18,7 +18,7 @@ All props are based on the `AsgardeoReactConfig` interface, which extends the ba | `clientId` | `string` | **REQUIRED** | The client ID obtained from your Asgardeo application registration | | `afterSignInUrl` | `string` | `window.location.origin` | URL to redirect users after successful sign-in. Must match configured redirect URIs in Asgardeo | | `afterSignOutUrl` | `string` | `window.location.origin` | URL to redirect users after sign-out. Must match configured post-logout redirect URIs | -| `scopes` | `string \| string[]` | `["openid profile internal_login"]` | OAuth scopes to request during authentication (e.g., `"openid profile email"` or `["openid", "profile", "email"]`) | +| `scopes` | `string \| string[]` | `openid profile internal_login` | OAuth scopes to request during authentication (e.g., `"openid profile email"` or `["openid", "profile", "email"]`) | | `organizationHandle` | `string` | - | Organization handle for organization-specific features like branding. Auto-derived from `baseUrl` if not provided. Required for custom domains | | `applicationId` | `string` | - | UUID of the Asgardeo application for application-specific branding and features | | `signInUrl` | `string` | - | Custom sign-in page URL. If provided, users will be redirected here instead of Asgardeo's default sign-in page | From ecf451ac7b0e93ed11e018db3c7fa6c997870e51 Mon Sep 17 00:00:00 2001 From: Brion Date: Tue, 8 Jul 2025 20:37:13 +0530 Subject: [PATCH 11/12] docs: update internal doc --- packages/react/docs/README.md | 2 +- packages/react/docs/components/OVERVIEW.md | 2 +- ...ARDEO_PROVIDER.md => asgardeo-provider.md} | 0 .../react/docs/components/sign-in-button.md | 338 +++++++++++++ .../react/docs/getting-started/QUICKSTART.md | 2 +- ...ED_APIS.md => accessing-protected-apis.md} | 0 pnpm-lock.yaml | 453 +++++++++++++++++- 7 files changed, 788 insertions(+), 9 deletions(-) rename packages/react/docs/components/{ASGARDEO_PROVIDER.md => asgardeo-provider.md} (100%) create mode 100644 packages/react/docs/components/sign-in-button.md rename packages/react/docs/guides/{ACCESS_PROTECTED_APIS.md => accessing-protected-apis.md} (100%) diff --git a/packages/react/docs/README.md b/packages/react/docs/README.md index b6ad3796..f149c2f9 100644 --- a/packages/react/docs/README.md +++ b/packages/react/docs/README.md @@ -16,4 +16,4 @@ The Asgardeo React SDK provides a comprehensive set of hooks, components, and ut ## What's Next -- [Quickstart Guide](./getting-started/README.md): Get started with a simple integration. +- [Quickstart Guide](./getting-started/overview.md): Get started with a simple integration. diff --git a/packages/react/docs/components/OVERVIEW.md b/packages/react/docs/components/OVERVIEW.md index f2241d44..bf7887d9 100644 --- a/packages/react/docs/components/OVERVIEW.md +++ b/packages/react/docs/components/OVERVIEW.md @@ -6,7 +6,7 @@ The Asgardeo React SDK provides a comprehensive set of components to handle auth Root components are the entry points for integrating Asgardeo authentication into your React application. They provide the necessary context and configuration for the SDK. -- **`AsgardeoProvider`** - The main provider component that wraps your application, providing authentication context and configuration. +- [**`AsgardeoProvider`**](./asgardeo-provider.md) - The main provider component that wraps your application, providing authentication context and configuration. ## Action Components diff --git a/packages/react/docs/components/ASGARDEO_PROVIDER.md b/packages/react/docs/components/asgardeo-provider.md similarity index 100% rename from packages/react/docs/components/ASGARDEO_PROVIDER.md rename to packages/react/docs/components/asgardeo-provider.md diff --git a/packages/react/docs/components/sign-in-button.md b/packages/react/docs/components/sign-in-button.md new file mode 100644 index 00000000..64dc0a98 --- /dev/null +++ b/packages/react/docs/components/sign-in-button.md @@ -0,0 +1,338 @@ +# SignInButton + +The `SignInButton` component provides a pre-built, customizable button that handles user authentication through the Asgardeo identity provider. It supports both render props and traditional props patterns, making it flexible for various UI implementations. + +## Overview + +The `SignInButton` component automatically integrates with the Asgardeo authentication context and handles the sign-in flow including loading states, error handling, and redirection. It leverages the `useAsgardeo` hook to access authentication methods and can be customized with preferences for internationalization and theming. + +## Basic Usage + +### Traditional Props Pattern + +```tsx +import React from 'react'; +import { SignInButton } from '@asgardeo/react'; + +function LoginPage() { + return ( +
+

Welcome to Our App

+ Sign In +
+ ); +} +``` + +### With Custom Styling + +```tsx +import React from 'react'; +import { SignInButton } from '@asgardeo/react'; + +function CustomLoginPage() { + return ( + + Get Started + + ); +} +``` + +## Advanced Usage + +### Render Props Pattern + +The render props pattern gives you full control over the button's appearance and behavior while still leveraging the authentication logic: + +```tsx +import React from 'react'; +import { SignInButton } from '@asgardeo/react'; + +function AdvancedLoginPage() { + return ( + + {({ signIn, isLoading }) => ( + + )} + + ); +} +``` + +### Custom Click Handler + +```tsx +import React from 'react'; +import { SignInButton } from '@asgardeo/react'; + +function TrackingLoginPage() { + const handleSignInClick = (event) => { + // Track analytics event + analytics.track('sign_in_button_clicked'); + console.log('User initiated sign-in process'); + }; + + return ( + + Sign In + + ); +} +``` + +### Component-Level Internationalization + +```tsx +import React from 'react'; +import { SignInButton } from '@asgardeo/react'; + +function LocalizedLoginPage() { + return ( + + {/* Will use localized text from preferences */} + + ); +} +``` + +## Props + +The `SignInButton` component accepts all standard HTML button attributes plus the following: + +### SignInButtonProps + +| Prop | Type | Default | Description | +|------|------|---------|-------------| +| `children` | `ReactNode \| ((props: RenderProps) => ReactNode)` | Localized "Sign In" text | Button content or render function | +| `onClick` | `(event: MouseEvent) => void` | - | Custom click handler called after sign-in initiation | +| `className` | `string` | - | Additional CSS classes to apply to the button | +| `style` | `CSSProperties` | - | Inline styles to apply to the button | +| `preferences` | `Preferences` | - | Component-level configuration for theming and internationalization | +| `disabled` | `boolean` | `false` | Whether the button is disabled (overridden during loading) | +| `type` | `"button" \| "submit" \| "reset"` | `"button"` | HTML button type | + +### Render Props + +When using the render props pattern, the function receives the following props: + +| Prop | Type | Description | +|------|------|-------------| +| `signIn` | `() => Promise` | Function to initiate the sign-in process | +| `isLoading` | `boolean` | Whether the sign-in process is currently in progress | + +## Preferences + +The `preferences` prop allows you to customize the component's behavior and appearance. + +| Property | Type | Default | Description | +|----------|------|---------|-------------| +| `i18n` | `I18nConfig` | - | Internationalization configuration for custom translations | +| `theme` | `ThemeConfig` | - | Theme configuration for styling customization | + +### I18nConfig + +| Property | Type | Description | +|----------|------|-------------| +| `bundles` | `Record }>` | Translation bundles keyed by locale | + +For the SignInButton, the relevant translation key is: + +- `elements.buttons.signIn` - The default button text + + +## Behavior + +### Authentication Flow + +1. **Initial State**: Button displays with default or custom text +2. **Click Event**: User clicks the button, triggering the sign-in process +3. **Loading State**: Button becomes disabled and shows loading indicator +4. **Navigation**: User is redirected to Asgardeo sign-in page or custom sign-in URL +5. **Completion**: After successful authentication, user returns to the application + +### Custom Sign-In URL + +If a `signInUrl` is configured in the `AsgardeoProvider`, the button will navigate to that URL instead of initiating the OAuth flow directly: + +```tsx +// In your AsgardeoProvider configuration + + + +``` + +### Error Handling + +The component automatically handles sign-in errors and throws an `AsgardeoRuntimeError` with detailed information: + +```tsx +// Error details include: +// - Error message +// - Error code: 'SignInButton-handleSignIn-RuntimeError-001' +// - Package: 'react' +// - User-friendly message +``` + +## Accessibility + +The `SignInButton` component includes accessibility features: + +- **Keyboard Navigation**: Fully keyboard accessible +- **Screen Readers**: Proper ARIA attributes and semantic HTML +- **Loading States**: Disabled state prevents multiple submissions +- **Focus Management**: Maintains focus states for keyboard users + +## Integration with BaseSignInButton + +The `SignInButton` is built on top of `BaseSignInButton`, which provides the core functionality. If you need more control or want to build a custom implementation, you can use `BaseSignInButton` directly: + +```tsx +import React, { useState } from 'react'; +import { BaseSignInButton } from '@asgardeo/react'; +import { useAsgardeo } from '@asgardeo/react'; + +function CustomSignInButton() { + const { signIn } = useAsgardeo(); + const [isLoading, setIsLoading] = useState(false); + + const handleSignIn = async () => { + setIsLoading(true); + try { + await signIn(); + } finally { + setIsLoading(false); + } + }; + + return ( + + Custom Sign In Implementation + + ); +} +``` + +## Best Practices + +### 1. Consistent Styling + +Maintain consistent button styling across your application: + +```tsx +// Create a styled wrapper +const StyledSignInButton = styled(SignInButton)` + background: var(--primary-color); + color: white; + border-radius: 8px; + padding: 12px 24px; + font-weight: 600; + + &:hover { + background: var(--primary-hover-color); + } +`; +``` + +### 2. Loading States + +Always provide clear feedback during the sign-in process: + +```tsx + + {({ isLoading }) => ( + <> + {isLoading && } + {isLoading ? 'Signing in...' : 'Sign In'} + + )} + +``` + +### 3. Error Boundaries + +Wrap your authentication components in error boundaries to handle potential errors gracefully: + +```tsx +Something went wrong}> + Sign In + +``` + +### 4. Responsive Design + +Ensure your sign-in button works well on all device sizes: + +```tsx + + Sign In + +``` + +## Common Issues + +### Button Not Working + +- Ensure `AsgardeoProvider` is properly configured and wrapping your component +- Check that all required configuration props are provided +- Verify network connectivity and Asgardeo service availability + +### Custom Styling Not Applied + +- Check CSS specificity and ensure your styles are not being overridden +- Use browser developer tools to inspect the rendered element +- Consider using CSS-in-JS solutions or CSS modules for better style isolation + +### Translation Not Showing + +- Verify the translation key `elements.buttons.signIn` exists in your bundles +- Check that the locale is correctly set in your preferences +- Ensure the `preferences` prop is passed correctly + +## Related Components + +- [`AsgardeoProvider`](./asgardeo-provider.md) - Required context provider for authentication +- [`BaseSignInButton`](#integration-with-basesigninbutton) - Lower-level component for custom implementations +- [`SignOutButton`](./sign-out-button.md) - Companion component for signing out users diff --git a/packages/react/docs/getting-started/QUICKSTART.md b/packages/react/docs/getting-started/QUICKSTART.md index 01cb2f3c..36a4ee18 100644 --- a/packages/react/docs/getting-started/QUICKSTART.md +++ b/packages/react/docs/getting-started/QUICKSTART.md @@ -181,4 +181,4 @@ Visit your app's homepage at [http://localhost:5173](http://localhost:5173). Now that you have basic authentication working, you can: -- [Explore all available components](../components/README.md) to enhance your app. +- [Explore all available components](../components/overview.md) to enhance your app. diff --git a/packages/react/docs/guides/ACCESS_PROTECTED_APIS.md b/packages/react/docs/guides/accessing-protected-apis.md similarity index 100% rename from packages/react/docs/guides/ACCESS_PROTECTED_APIS.md rename to packages/react/docs/guides/accessing-protected-apis.md diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index b5a41242..9e87d82d 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -49,7 +49,7 @@ importers: devDependencies: vitepress: specifier: ^1.2.2 - version: 1.6.3(@algolia/client-search@5.25.0)(@types/node@24.0.3)(@types/react@18.3.23)(axios@1.9.0)(fuse.js@7.1.0)(jwt-decode@4.0.0)(lightningcss@1.30.1)(postcss@8.5.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.89.0)(search-insights@2.17.3)(terser@5.39.2)(typescript@5.8.3) + version: 1.6.3(@algolia/client-search@5.25.0)(@types/node@24.0.3)(@types/react@18.3.23)(axios@1.9.0)(fuse.js@7.1.0)(jwt-decode@4.0.0)(lightningcss@1.30.1)(postcss@8.5.6)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.89.0)(search-insights@2.17.3)(terser@5.39.2)(typescript@5.8.3) packages/browser: dependencies: @@ -446,7 +446,7 @@ importers: version: 0.1.3 '@vitejs/plugin-vue': specifier: ^5.0.0 - version: 5.2.4(vite@6.3.5(@types/node@20.17.50)(jiti@2.4.2)(lightningcss@1.30.1)(sass@1.89.0)(terser@5.39.2)(yaml@2.8.0))(vue@3.5.14(typescript@5.1.6)) + version: 5.2.4(vite@7.0.2(@types/node@20.17.50)(jiti@2.4.2)(lightningcss@1.30.1)(sass@1.89.0)(terser@5.39.2)(yaml@2.8.0))(vue@3.5.14(typescript@5.1.6)) base64url: specifier: ^3.0.1 version: 3.0.1 @@ -545,6 +545,46 @@ importers: specifier: ^2.2.2 version: 2.2.10(typescript@5.1.6) + samples/asgardeo-react: + dependencies: + '@asgardeo/react': + specifier: workspace:^ + version: link:../../packages/react + react: + specifier: ^19.1.0 + version: 19.1.0 + react-dom: + specifier: ^19.1.0 + version: 19.1.0(react@19.1.0) + devDependencies: + '@eslint/js': + specifier: ^9.29.0 + version: 9.30.1 + '@types/react': + specifier: ^19.1.8 + version: 19.1.8 + '@types/react-dom': + specifier: ^19.1.6 + version: 19.1.6(@types/react@19.1.8) + '@vitejs/plugin-react': + specifier: ^4.5.2 + version: 4.6.0(vite@7.0.2(@types/node@24.0.3)(jiti@2.4.2)(lightningcss@1.30.1)(sass@1.89.0)(terser@5.39.2)(yaml@2.8.0)) + eslint: + specifier: ^9.29.0 + version: 9.30.1(jiti@2.4.2) + eslint-plugin-react-hooks: + specifier: ^5.2.0 + version: 5.2.0(eslint@9.30.1(jiti@2.4.2)) + eslint-plugin-react-refresh: + specifier: ^0.4.20 + version: 0.4.20(eslint@9.30.1(jiti@2.4.2)) + globals: + specifier: ^16.2.0 + version: 16.3.0 + vite: + specifier: ^7.0.0 + version: 7.0.2(@types/node@24.0.3)(jiti@2.4.2)(lightningcss@1.30.1)(sass@1.89.0)(terser@5.39.2)(yaml@2.8.0) + samples/teamspace-react: dependencies: '@asgardeo/react': @@ -732,6 +772,10 @@ packages: resolution: {integrity: sha512-IaaGWsQqfsQWVLqMn9OB92MNN7zukfVA4s7KKAI0KfrrDsZ0yhi5uV4baBuLuN7n3vsZpwP8asPPcVwApxvjBQ==} engines: {node: '>=6.9.0'} + '@babel/core@7.28.0': + resolution: {integrity: sha512-UlLAnTPrFdNGoFtbSXwcGFQBtQZJCNjaN6hQNP3UPvuNXT1i82N26KL3dZeIpNalWywr9IuQuncaAfUaS1g6sQ==} + engines: {node: '>=6.9.0'} + '@babel/eslint-parser@7.27.1': resolution: {integrity: sha512-q8rjOuadH0V6Zo4XLMkJ3RMQ9MSBqwaDByyYB0izsYdaIWGNLmEblbCOf1vyFHICcg16CD7Fsi51vcQnYxmt6Q==} engines: {node: ^10.13.0 || ^12.13.0 || >=14.0.0} @@ -743,10 +787,18 @@ packages: resolution: {integrity: sha512-UnJfnIpc/+JO0/+KRVQNGU+y5taA5vCbwN8+azkX6beii/ZF+enZJSOKo11ZSzGJjlNfJHfQtmQT8H+9TXPG2w==} engines: {node: '>=6.9.0'} + '@babel/generator@7.28.0': + resolution: {integrity: sha512-lJjzvrbEeWrhB4P3QBsH7tey117PjLZnDbLiQEKjQ/fNJTjuq4HSqgFA+UNSwZT8D7dxxbnuSBMsa1lrWzKlQg==} + engines: {node: '>=6.9.0'} + '@babel/helper-compilation-targets@7.27.2': resolution: {integrity: sha512-2+1thGUUWWjLTYTHZWK1n8Yga0ijBz1XAhUXcKy81rd5g6yh7hGqMp45v7cadSbEHc9G3OTv45SyneRN3ps4DQ==} engines: {node: '>=6.9.0'} + '@babel/helper-globals@7.28.0': + resolution: {integrity: sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw==} + engines: {node: '>=6.9.0'} + '@babel/helper-module-imports@7.27.1': resolution: {integrity: sha512-0gSFWUPNXNopqtIPQvlD5WgXYI5GY2kP2cCvoT8kczjbfcfuIljTbcWrulD1CIPIX2gt1wghbDy08yE1p+/r3w==} engines: {node: '>=6.9.0'} @@ -757,6 +809,12 @@ packages: peerDependencies: '@babel/core': ^7.0.0 + '@babel/helper-module-transforms@7.27.3': + resolution: {integrity: sha512-dSOvYwvyLsWBeIRyOeHXp5vPj5l1I011r52FM1+r1jCERv+aFXYk4whgQccYEGYxK2H3ZAIA8nuPkQ0HaUo3qg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + '@babel/helper-plugin-utils@7.27.1': resolution: {integrity: sha512-1gn1Up5YXka3YYAHGKpbideQ5Yjf1tDa9qYcgysz+cNCXukyLl6DjPXhD3VRwSb8c0J9tA4b2+rHEZtc6R0tlw==} engines: {node: '>=6.9.0'} @@ -777,11 +835,20 @@ packages: resolution: {integrity: sha512-FCvFTm0sWV8Fxhpp2McP5/W53GPllQ9QeQ7SiqGWjMf/LVG07lFa5+pgK05IRhVwtvafT22KF+ZSnM9I545CvQ==} engines: {node: '>=6.9.0'} + '@babel/helpers@7.27.6': + resolution: {integrity: sha512-muE8Tt8M22638HU31A3CgfSUciwz1fhATfoVai05aPXGor//CdWDCbnlY1yvBPo07njuVOCNGCSp/GTt12lIug==} + engines: {node: '>=6.9.0'} + '@babel/parser@7.27.2': resolution: {integrity: sha512-QYLs8299NA7WM/bZAdp+CviYYkVoYXlDW2rzliy3chxd1PQjej7JORuMJDJXJUb9g0TT+B99EwaVLKmX+sPXWw==} engines: {node: '>=6.0.0'} hasBin: true + '@babel/parser@7.28.0': + resolution: {integrity: sha512-jVZGvOxOuNSsuQuLRTh13nU0AogFlw32w/MT+LV6D3sP5WdbW61E77RnkbaO2dUvmPAYrBDJXGn5gGS6tH4j8g==} + engines: {node: '>=6.0.0'} + hasBin: true + '@babel/plugin-transform-react-jsx-self@7.27.1': resolution: {integrity: sha512-6UzkCs+ejGdZ5mFFC/OCUrv028ab2fp1znZmCZjAOBKiBK2jXD1O+BPSfX8X2qjJ75fZBMSnQn3Rq2mrBJK2mw==} engines: {node: '>=6.9.0'} @@ -806,10 +873,18 @@ packages: resolution: {integrity: sha512-ZCYtZciz1IWJB4U61UPu4KEaqyfj+r5T1Q5mqPo+IBpcG9kHv30Z0aD8LXPgC1trYa6rK0orRyAhqUgk4MjmEg==} engines: {node: '>=6.9.0'} + '@babel/traverse@7.28.0': + resolution: {integrity: sha512-mGe7UK5wWyh0bKRfupsUchrQGqvDbZDbKJw+kcRGSmdHVYrv+ltd0pnpDTVpiTqnaBru9iEvA8pz8W46v0Amwg==} + engines: {node: '>=6.9.0'} + '@babel/types@7.27.1': resolution: {integrity: sha512-+EzkxvLNfiUeKMgy/3luqfsCWFRXLb7U6wNQTk60tovuckwB15B191tJWvpp4HjiQWdJkCxO3Wbvc6jlk3Xb2Q==} engines: {node: '>=6.9.0'} + '@babel/types@7.28.0': + resolution: {integrity: sha512-jYnje+JyZG5YThjHiF28oT4SIZLnYOcSBb6+SDaFIyzDVSkXQmQQYclJ2R+YxcdmK0AX6x1E5OQNtuh3jHDrUg==} + engines: {node: '>=6.9.0'} + '@bcoe/v8-coverage@1.0.2': resolution: {integrity: sha512-6zABk/ECA/QYSCQ1NGiVwwbQerUCZ+TQbp64Q3AgmfNvurHH0j8TtXa1qbShXA6qqkpAj4V5W8pP6mLe1mcMqA==} engines: {node: '>=18'} @@ -1260,10 +1335,18 @@ packages: resolution: {integrity: sha512-fxlS1kkIjx8+vy2SjuCB94q3htSNrufYTXubwiBFeaQHbH6Ipi43gFJq2zCMt6PHhImH3Xmr0NksKDvchWlpQQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@eslint/config-array@0.21.0': + resolution: {integrity: sha512-ENIdc4iLu0d93HeYirvKmrzshzofPw6VkZRKQGe9Nv46ZnWUzcF1xV01dcvEg/1wXUR61OmmlSfyeyO7EvjLxQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@eslint/config-helpers@0.2.2': resolution: {integrity: sha512-+GPzk8PlG0sPpzdU5ZvIRMPidzAnZDl/s9L+y13iodqvb8leL53bTannOrQ/Im7UkpsmFU5Ily5U60LWixnmLg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@eslint/config-helpers@0.3.0': + resolution: {integrity: sha512-ViuymvFmcJi04qdZeDc2whTHryouGcDlaxPqarTD0ZE10ISpxGUVZGZDx4w01upyIynL3iu6IXH2bS1NhclQMw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@eslint/core@0.14.0': resolution: {integrity: sha512-qIbV0/JZr7iSDjqAc60IqbLdsj9GDt16xQtWD+B78d/HAlvysGdZZ6rpJHGAc2T0FQx1X6thsSPdnoiGKdNtdg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} @@ -1284,6 +1367,10 @@ packages: resolution: {integrity: sha512-fnqSjGWd/CoIp4EXIxWVK/sHA6DOHN4+8Ix2cX5ycOY7LG0UY8nHCU5pIp2eaE1Mc7Qd8kHspYNzYXT2ojPLzg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@eslint/js@9.30.1': + resolution: {integrity: sha512-zXhuECFlyep42KZUhWjfvsmXGX39W8K8LFb8AWXM9gSV9dQB+MrJGLKvW6Zw0Ggnbpw0VHTtrhFXYe3Gym18jg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@eslint/object-schema@2.1.6': resolution: {integrity: sha512-RBMg5FRL0I0gs51M/guSAj5/e14VQ4tpZnQNWwuDT66P14I43ItmPfIZRhO9fUVIPOAQXU47atlywZ/czoqFPA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} @@ -1480,6 +1567,9 @@ packages: resolution: {integrity: sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + '@jridgewell/gen-mapping@0.3.12': + resolution: {integrity: sha512-OuLGC46TjB5BbN1dH8JULVVZY4WTdkF7tV9Ys6wLL1rubZnCMstOhNHueU5bLCrnRuDhKPDM4g6sw4Bel5Gzqg==} + '@jridgewell/gen-mapping@0.3.8': resolution: {integrity: sha512-imAbBGkb+ebQyxKgzv5Hu2nmROxoDOXHh80evxdoXNOrvAnVx7zimzc1Oo5h9RlfV4vPXaE2iM5pOFbvOCClWA==} engines: {node: '>=6.0.0'} @@ -1501,6 +1591,9 @@ packages: '@jridgewell/trace-mapping@0.3.25': resolution: {integrity: sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==} + '@jridgewell/trace-mapping@0.3.29': + resolution: {integrity: sha512-uw6guiW/gcAGPDhLmd77/6lW8QLeiV5RUTsAX46Db6oLhGaVj4lhnPwb184s1bkc8kdVg/+h988dro8GRDpmYQ==} + '@jspm/core@2.1.0': resolution: {integrity: sha512-3sRl+pkyFY/kLmHl0cgHiFp2xEqErA8N3ECjMs7serSUBmoJ70lBa0PG5t0IM6WJgdZNyyI0R8YFfi5wM8+mzg==} @@ -1788,6 +1881,9 @@ packages: '@types/react': optional: true + '@rolldown/pluginutils@1.0.0-beta.19': + resolution: {integrity: sha512-3FL3mnMbPu0muGOCaKAhhFEYmqv9eTfPSJRJmANrCwtgK8VuxpsZDGK+m0LYAGoyO8+0j5uRe4PeyPDK1yA/hA==} + '@rolldown/pluginutils@1.0.0-beta.9': resolution: {integrity: sha512-e9MeMtVWo186sgvFFJOPGy7/d2j2mZhLJIdVW0C/xDluuOvymEATqz6zKsP0ZmXGzQtqlyjz5sC1sYQUoJG98w==} @@ -2168,12 +2264,20 @@ packages: peerDependencies: '@types/react': ^19.0.0 + '@types/react-dom@19.1.6': + resolution: {integrity: sha512-4hOiT/dwO8Ko0gV1m/TJZYk3y0KBnY9vzDh7W+DH17b2HFSOGgdj33dhihPeuy3l0q23+4e+hoXHV6hCC4dCXw==} + peerDependencies: + '@types/react': ^19.0.0 + '@types/react@18.3.23': resolution: {integrity: sha512-/LDXMQh55EzZQ0uVAZmKKhfENivEvWz6E+EYzh+/MCjMhNsotd+ZHhBGIjFDTi6+fz0OhQQQLbTgdQIxxCsC0w==} '@types/react@19.1.5': resolution: {integrity: sha512-piErsCVVbpMMT2r7wbawdZsq4xMvIAhQuac2gedQHysu1TZYEigE6pnFfgZT+/jQnrRuF5r+SHzuehFjfRjr4g==} + '@types/react@19.1.8': + resolution: {integrity: sha512-AwAfQ2Wa5bCx9WP8nZL2uMZWod7J7/JSplxbTmBQ5ms6QpqNYm672H0Vu9ZVKVngQ+ii4R/byguVEUZQyeg44g==} + '@types/resolve@1.20.2': resolution: {integrity: sha512-60BCwRFOZCQhDncwQdxxeOEEkbc5dIMccYLwbxsS4TUNeVECQ/pBJ0j09mrHOl/JJvpRPGwO9SvE4nR2Nb/a4Q==} @@ -2382,6 +2486,12 @@ packages: peerDependencies: vite: ^4.2.0 || ^5.0.0 || ^6.0.0 + '@vitejs/plugin-react@4.6.0': + resolution: {integrity: sha512-5Kgff+m8e2PB+9j51eGHEpn5kUzRKH2Ry0qGoe8ItJg7pqnkPrYPkDQZGgGmTa0EGarHrkjLvOdU3b1fzI8otQ==} + engines: {node: ^14.18.0 || >=16.0.0} + peerDependencies: + vite: ^4.2.0 || ^5.0.0 || ^6.0.0 || ^7.0.0-beta.0 + '@vitejs/plugin-vue@5.2.4': resolution: {integrity: sha512-7Yx/SXSOcQq5HiiV3orevHUFn+pmMB4cgbEkDYgnkUWb0WfeQ/wa2yFv6D5ICiCQOVpjA7vYDXrC7AGO8yjDHA==} engines: {node: ^18.0.0 || >=20.0.0} @@ -2637,6 +2747,11 @@ packages: engines: {node: '>=0.4.0'} hasBin: true + acorn@8.15.0: + resolution: {integrity: sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==} + engines: {node: '>=0.4.0'} + hasBin: true + agent-base@7.1.3: resolution: {integrity: sha512-jRR5wdylq8CkOe6hei19GGZnxM6rBGwFl3Bg0YItGDimvjGtAvdZk4Pu6Cl4u4Igsws4a1fd1Vq3ezrhn4KmFw==} engines: {node: '>= 14'} @@ -3644,6 +3759,10 @@ packages: resolution: {integrity: sha512-pUNxi75F8MJ/GdeKtVLSbYg4ZI34J6C0C7sbL4YOp2exGwen7ZsuBqKzUhXd0qMQ362yET3z+uPwKeg/0C2XCQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + eslint-scope@8.4.0: + resolution: {integrity: sha512-sNXOfKCn74rt8RICKMvJS7XKV/Xk9kA7DyJr8mJik3S7Cwgy3qlkkmyS2uQB3jiJg6VNdZd/pDBJu0nvG2NlTg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + eslint-utils@2.1.0: resolution: {integrity: sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==} engines: {node: '>=6'} @@ -3670,6 +3789,10 @@ packages: resolution: {integrity: sha512-UyLnSehNt62FFhSwjZlHmeokpRK59rcz29j+F1/aDgbkbRTk7wIc9XzdoasMUbRNKDM0qQt/+BJ4BrpFeABemw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + eslint-visitor-keys@4.2.1: + resolution: {integrity: sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + eslint@8.57.0: resolution: {integrity: sha512-dZ6+mexnaTIbSBZWgou51U6OmzIhYM2VcNdtiTtI7qPNZm35Akpr0f6vtw3w1Kmn5PYo+tZVfh13WrhpS6oLqQ==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} @@ -3686,10 +3809,24 @@ packages: jiti: optional: true + eslint@9.30.1: + resolution: {integrity: sha512-zmxXPNMOXmwm9E0yQLi5uqXHs7uq2UIiqEKo3Gq+3fwo1XrJ+hijAZImyF7hclW3E6oHz43Yk3RP8at6OTKflQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + hasBin: true + peerDependencies: + jiti: '*' + peerDependenciesMeta: + jiti: + optional: true + espree@10.3.0: resolution: {integrity: sha512-0QYC8b24HWY8zjRnDTL6RiHfDbAWn63qb4LMj1Z4b076A4une81+z03Kg7l7mn/48PUTqoLptSXez8oknU8Clg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + espree@10.4.0: + resolution: {integrity: sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + espree@9.6.1: resolution: {integrity: sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} @@ -3790,6 +3927,14 @@ packages: picomatch: optional: true + fdir@6.4.6: + resolution: {integrity: sha512-hiFoqpyZcfNm1yc4u8oWCf9A2c4D3QjCrks3zmoVKVxpQRzmPNar1hUJcBG2RQHvEVGDN+Jm81ZheVLAQMK6+w==} + peerDependencies: + picomatch: ^3 || ^4 + peerDependenciesMeta: + picomatch: + optional: true + figures@3.2.0: resolution: {integrity: sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==} engines: {node: '>=8'} @@ -3998,6 +4143,10 @@ packages: resolution: {integrity: sha512-aibexHNbb/jiUSObBgpHLj+sIuUmJnYcgXBlrfsiDZ9rt4aF2TFRbyLgZ2iFQuVZ1K5Mx3FVkbKRSgKrbK3K2g==} engines: {node: '>=18'} + globals@16.3.0: + resolution: {integrity: sha512-bqWEnJ1Nt3neqx2q5SFfGS8r/ahumIakg3HcwtNlrVlwXIeNumWn/c7Pn/wKzGhf6SaW6H6uWXLqC30STCMchQ==} + engines: {node: '>=18'} + globalthis@1.0.4: resolution: {integrity: sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==} engines: {node: '>= 0.4'} @@ -5359,6 +5508,10 @@ packages: resolution: {integrity: sha512-dle9A3yYxlBSrt8Fu+IpjGT8SY8hN0mlaA6GY8t0P5PjIOZemULz/E2Bnm/2dcUOena75OTNkHI76uZBNUUq3A==} engines: {node: ^10 || ^12 || >=14} + postcss@8.5.6: + resolution: {integrity: sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==} + engines: {node: ^10 || ^12 || >=14} + preact@10.26.7: resolution: {integrity: sha512-43xS+QYc1X1IPbw03faSgY6I6OYWcLrJRv3hU0+qMOfh/XCHcP0MX2CVjNARYR2cC/guu975sta4OcjlczxD7g==} @@ -6045,6 +6198,10 @@ packages: resolution: {integrity: sha512-mEwzpUgrLySlveBwEVDMKk5B57bhLPYovRfPAXD5gA/98Opn0rCDj3GtLwFvCvH5RK9uPCExUROW5NjDwvqkxw==} engines: {node: '>=12.0.0'} + tinyglobby@0.2.14: + resolution: {integrity: sha512-tX5e7OM1HnYr2+a2C/4V0htOcSQcoSTH9KgJnVvNm5zm/cyEWKJ7j7YutsH9CxMdtOkkLFy2AHrMci9IM8IPZQ==} + engines: {node: '>=12.0.0'} + tinypool@1.0.2: resolution: {integrity: sha512-al6n+QEANGFOMf/dmUMsuS5/r9B06uwlyNjZZql/zv8J7ybHCgoihBNORZCY2mzUuAnomQa2JdhyHKzZxPCrFA==} engines: {node: ^18.0.0 || >=20.0.0} @@ -6349,6 +6506,46 @@ packages: yaml: optional: true + vite@7.0.2: + resolution: {integrity: sha512-hxdyZDY1CM6SNpKI4w4lcUc3Mtkd9ej4ECWVHSMrOdSinVc2zYOAppHeGc/hzmRo3pxM5blMzkuWHOJA/3NiFw==} + engines: {node: ^20.19.0 || >=22.12.0} + hasBin: true + peerDependencies: + '@types/node': ^20.19.0 || >=22.12.0 + jiti: '>=1.21.0' + less: ^4.0.0 + lightningcss: ^1.21.0 + sass: ^1.70.0 + sass-embedded: ^1.70.0 + stylus: '>=0.54.8' + sugarss: ^5.0.0 + terser: ^5.16.0 + tsx: ^4.8.1 + yaml: ^2.4.2 + peerDependenciesMeta: + '@types/node': + optional: true + jiti: + optional: true + less: + optional: true + lightningcss: + optional: true + sass: + optional: true + sass-embedded: + optional: true + stylus: + optional: true + sugarss: + optional: true + terser: + optional: true + tsx: + optional: true + yaml: + optional: true + vitepress@1.6.3: resolution: {integrity: sha512-fCkfdOk8yRZT8GD9BFqusW3+GggWYZ/rYncOfmgcDtP3ualNHCAg+Robxp2/6xfH1WwPHtGpPwv7mbA3qomtBw==} hasBin: true @@ -6751,6 +6948,26 @@ snapshots: transitivePeerDependencies: - supports-color + '@babel/core@7.28.0': + dependencies: + '@ampproject/remapping': 2.3.0 + '@babel/code-frame': 7.27.1 + '@babel/generator': 7.28.0 + '@babel/helper-compilation-targets': 7.27.2 + '@babel/helper-module-transforms': 7.27.3(@babel/core@7.28.0) + '@babel/helpers': 7.27.6 + '@babel/parser': 7.28.0 + '@babel/template': 7.27.2 + '@babel/traverse': 7.28.0 + '@babel/types': 7.28.0 + convert-source-map: 2.0.0 + debug: 4.4.1 + gensync: 1.0.0-beta.2 + json5: 2.2.3 + semver: 6.3.1 + transitivePeerDependencies: + - supports-color + '@babel/eslint-parser@7.27.1(@babel/core@7.27.1)(eslint@8.57.0)': dependencies: '@babel/core': 7.27.1 @@ -6767,6 +6984,14 @@ snapshots: '@jridgewell/trace-mapping': 0.3.25 jsesc: 3.1.0 + '@babel/generator@7.28.0': + dependencies: + '@babel/parser': 7.28.0 + '@babel/types': 7.28.0 + '@jridgewell/gen-mapping': 0.3.12 + '@jridgewell/trace-mapping': 0.3.29 + jsesc: 3.1.0 + '@babel/helper-compilation-targets@7.27.2': dependencies: '@babel/compat-data': 7.27.2 @@ -6775,6 +7000,8 @@ snapshots: lru-cache: 5.1.1 semver: 6.3.1 + '@babel/helper-globals@7.28.0': {} + '@babel/helper-module-imports@7.27.1': dependencies: '@babel/traverse': 7.27.1 @@ -6791,6 +7018,15 @@ snapshots: transitivePeerDependencies: - supports-color + '@babel/helper-module-transforms@7.27.3(@babel/core@7.28.0)': + dependencies: + '@babel/core': 7.28.0 + '@babel/helper-module-imports': 7.27.1 + '@babel/helper-validator-identifier': 7.27.1 + '@babel/traverse': 7.28.0 + transitivePeerDependencies: + - supports-color + '@babel/helper-plugin-utils@7.27.1': {} '@babel/helper-string-parser@7.27.1': {} @@ -6804,20 +7040,39 @@ snapshots: '@babel/template': 7.27.2 '@babel/types': 7.27.1 + '@babel/helpers@7.27.6': + dependencies: + '@babel/template': 7.27.2 + '@babel/types': 7.28.0 + '@babel/parser@7.27.2': dependencies: '@babel/types': 7.27.1 + '@babel/parser@7.28.0': + dependencies: + '@babel/types': 7.28.0 + '@babel/plugin-transform-react-jsx-self@7.27.1(@babel/core@7.27.1)': dependencies: '@babel/core': 7.27.1 '@babel/helper-plugin-utils': 7.27.1 + '@babel/plugin-transform-react-jsx-self@7.27.1(@babel/core@7.28.0)': + dependencies: + '@babel/core': 7.28.0 + '@babel/helper-plugin-utils': 7.27.1 + '@babel/plugin-transform-react-jsx-source@7.27.1(@babel/core@7.27.1)': dependencies: '@babel/core': 7.27.1 '@babel/helper-plugin-utils': 7.27.1 + '@babel/plugin-transform-react-jsx-source@7.27.1(@babel/core@7.28.0)': + dependencies: + '@babel/core': 7.28.0 + '@babel/helper-plugin-utils': 7.27.1 + '@babel/runtime@7.27.1': {} '@babel/template@7.27.2': @@ -6838,11 +7093,28 @@ snapshots: transitivePeerDependencies: - supports-color + '@babel/traverse@7.28.0': + dependencies: + '@babel/code-frame': 7.27.1 + '@babel/generator': 7.28.0 + '@babel/helper-globals': 7.28.0 + '@babel/parser': 7.28.0 + '@babel/template': 7.27.2 + '@babel/types': 7.28.0 + debug: 4.4.1 + transitivePeerDependencies: + - supports-color + '@babel/types@7.27.1': dependencies: '@babel/helper-string-parser': 7.27.1 '@babel/helper-validator-identifier': 7.27.1 + '@babel/types@7.28.0': + dependencies: + '@babel/helper-string-parser': 7.27.1 + '@babel/helper-validator-identifier': 7.27.1 + '@bcoe/v8-coverage@1.0.2': {} '@changesets/apply-release-plan@7.0.12': @@ -7236,6 +7508,11 @@ snapshots: eslint: 9.28.0(jiti@2.4.2) eslint-visitor-keys: 3.4.3 + '@eslint-community/eslint-utils@4.7.0(eslint@9.30.1(jiti@2.4.2))': + dependencies: + eslint: 9.30.1(jiti@2.4.2) + eslint-visitor-keys: 3.4.3 + '@eslint-community/regexpp@4.12.1': {} '@eslint/config-array@0.20.0': @@ -7246,8 +7523,18 @@ snapshots: transitivePeerDependencies: - supports-color + '@eslint/config-array@0.21.0': + dependencies: + '@eslint/object-schema': 2.1.6 + debug: 4.4.1 + minimatch: 3.1.2 + transitivePeerDependencies: + - supports-color + '@eslint/config-helpers@0.2.2': {} + '@eslint/config-helpers@0.3.0': {} + '@eslint/core@0.14.0': dependencies: '@types/json-schema': 7.0.15 @@ -7284,6 +7571,8 @@ snapshots: '@eslint/js@9.28.0': {} + '@eslint/js@9.30.1': {} + '@eslint/object-schema@2.1.6': {} '@eslint/plugin-kit@0.3.1': @@ -7445,6 +7734,11 @@ snapshots: dependencies: '@sinclair/typebox': 0.27.8 + '@jridgewell/gen-mapping@0.3.12': + dependencies: + '@jridgewell/sourcemap-codec': 1.5.0 + '@jridgewell/trace-mapping': 0.3.29 + '@jridgewell/gen-mapping@0.3.8': dependencies: '@jridgewell/set-array': 1.2.1 @@ -7468,6 +7762,11 @@ snapshots: '@jridgewell/resolve-uri': 3.1.2 '@jridgewell/sourcemap-codec': 1.5.0 + '@jridgewell/trace-mapping@0.3.29': + dependencies: + '@jridgewell/resolve-uri': 3.1.2 + '@jridgewell/sourcemap-codec': 1.5.0 + '@jspm/core@2.1.0': {} '@manypkg/find-root@1.1.0': @@ -7678,6 +7977,8 @@ snapshots: optionalDependencies: '@types/react': 19.1.5 + '@rolldown/pluginutils@1.0.0-beta.19': {} + '@rolldown/pluginutils@1.0.0-beta.9': {} '@rollup/plugin-commonjs@25.0.8(rollup@4.40.2)': @@ -8020,6 +8321,10 @@ snapshots: dependencies: '@types/react': 19.1.5 + '@types/react-dom@19.1.6(@types/react@19.1.8)': + dependencies: + '@types/react': 19.1.8 + '@types/react@18.3.23': dependencies: '@types/prop-types': 15.7.15 @@ -8030,6 +8335,10 @@ snapshots: dependencies: csstype: 3.1.3 + '@types/react@19.1.8': + dependencies: + csstype: 3.1.3 + '@types/resolve@1.20.2': {} '@types/semver@7.7.0': {} @@ -8406,14 +8715,26 @@ snapshots: transitivePeerDependencies: - supports-color + '@vitejs/plugin-react@4.6.0(vite@7.0.2(@types/node@24.0.3)(jiti@2.4.2)(lightningcss@1.30.1)(sass@1.89.0)(terser@5.39.2)(yaml@2.8.0))': + dependencies: + '@babel/core': 7.28.0 + '@babel/plugin-transform-react-jsx-self': 7.27.1(@babel/core@7.28.0) + '@babel/plugin-transform-react-jsx-source': 7.27.1(@babel/core@7.28.0) + '@rolldown/pluginutils': 1.0.0-beta.19 + '@types/babel__core': 7.20.5 + react-refresh: 0.17.0 + vite: 7.0.2(@types/node@24.0.3)(jiti@2.4.2)(lightningcss@1.30.1)(sass@1.89.0)(terser@5.39.2)(yaml@2.8.0) + transitivePeerDependencies: + - supports-color + '@vitejs/plugin-vue@5.2.4(vite@5.4.19(@types/node@24.0.3)(lightningcss@1.30.1)(sass@1.89.0)(terser@5.39.2))(vue@3.5.14(typescript@5.8.3))': dependencies: vite: 5.4.19(@types/node@24.0.3)(lightningcss@1.30.1)(sass@1.89.0)(terser@5.39.2) vue: 3.5.14(typescript@5.8.3) - '@vitejs/plugin-vue@5.2.4(vite@6.3.5(@types/node@20.17.50)(jiti@2.4.2)(lightningcss@1.30.1)(sass@1.89.0)(terser@5.39.2)(yaml@2.8.0))(vue@3.5.14(typescript@5.1.6))': + '@vitejs/plugin-vue@5.2.4(vite@7.0.2(@types/node@20.17.50)(jiti@2.4.2)(lightningcss@1.30.1)(sass@1.89.0)(terser@5.39.2)(yaml@2.8.0))(vue@3.5.14(typescript@5.1.6))': dependencies: - vite: 6.3.5(@types/node@20.17.50)(jiti@2.4.2)(lightningcss@1.30.1)(sass@1.89.0)(terser@5.39.2)(yaml@2.8.0) + vite: 7.0.2(@types/node@20.17.50)(jiti@2.4.2)(lightningcss@1.30.1)(sass@1.89.0)(terser@5.39.2)(yaml@2.8.0) vue: 3.5.14(typescript@5.1.6) '@vitest/browser@3.1.3(playwright@1.52.0)(vite@6.3.5(@types/node@22.15.30)(jiti@2.4.2)(lightningcss@1.30.1)(sass@1.89.0)(terser@5.39.2)(yaml@2.8.0))(vitest@3.1.3)': @@ -8784,8 +9105,14 @@ snapshots: dependencies: acorn: 8.14.1 + acorn-jsx@5.3.2(acorn@8.15.0): + dependencies: + acorn: 8.15.0 + acorn@8.14.1: {} + acorn@8.15.0: {} + agent-base@7.1.3: optional: true @@ -10033,10 +10360,18 @@ snapshots: dependencies: eslint: 9.28.0(jiti@2.4.2) + eslint-plugin-react-hooks@5.2.0(eslint@9.30.1(jiti@2.4.2)): + dependencies: + eslint: 9.30.1(jiti@2.4.2) + eslint-plugin-react-refresh@0.4.20(eslint@9.28.0(jiti@2.4.2)): dependencies: eslint: 9.28.0(jiti@2.4.2) + eslint-plugin-react-refresh@0.4.20(eslint@9.30.1(jiti@2.4.2)): + dependencies: + eslint: 9.30.1(jiti@2.4.2) + eslint-plugin-react@7.37.5(eslint@8.57.0): dependencies: array-includes: 3.1.8 @@ -10128,6 +10463,11 @@ snapshots: esrecurse: 4.3.0 estraverse: 5.3.0 + eslint-scope@8.4.0: + dependencies: + esrecurse: 4.3.0 + estraverse: 5.3.0 + eslint-utils@2.1.0: dependencies: eslint-visitor-keys: 1.3.0 @@ -10145,6 +10485,8 @@ snapshots: eslint-visitor-keys@4.2.0: {} + eslint-visitor-keys@4.2.1: {} + eslint@8.57.0: dependencies: '@eslint-community/eslint-utils': 4.7.0(eslint@8.57.0) @@ -10230,12 +10572,60 @@ snapshots: transitivePeerDependencies: - supports-color + eslint@9.30.1(jiti@2.4.2): + dependencies: + '@eslint-community/eslint-utils': 4.7.0(eslint@9.30.1(jiti@2.4.2)) + '@eslint-community/regexpp': 4.12.1 + '@eslint/config-array': 0.21.0 + '@eslint/config-helpers': 0.3.0 + '@eslint/core': 0.14.0 + '@eslint/eslintrc': 3.3.1 + '@eslint/js': 9.30.1 + '@eslint/plugin-kit': 0.3.1 + '@humanfs/node': 0.16.6 + '@humanwhocodes/module-importer': 1.0.1 + '@humanwhocodes/retry': 0.4.3 + '@types/estree': 1.0.7 + '@types/json-schema': 7.0.15 + ajv: 6.12.6 + chalk: 4.1.2 + cross-spawn: 7.0.6 + debug: 4.4.1 + escape-string-regexp: 4.0.0 + eslint-scope: 8.4.0 + eslint-visitor-keys: 4.2.1 + espree: 10.4.0 + esquery: 1.6.0 + esutils: 2.0.3 + fast-deep-equal: 3.1.3 + file-entry-cache: 8.0.0 + find-up: 5.0.0 + glob-parent: 6.0.2 + ignore: 5.3.2 + imurmurhash: 0.1.4 + is-glob: 4.0.3 + json-stable-stringify-without-jsonify: 1.0.1 + lodash.merge: 4.6.2 + minimatch: 3.1.2 + natural-compare: 1.4.0 + optionator: 0.9.4 + optionalDependencies: + jiti: 2.4.2 + transitivePeerDependencies: + - supports-color + espree@10.3.0: dependencies: acorn: 8.14.1 acorn-jsx: 5.3.2(acorn@8.14.1) eslint-visitor-keys: 4.2.0 + espree@10.4.0: + dependencies: + acorn: 8.15.0 + acorn-jsx: 5.3.2(acorn@8.15.0) + eslint-visitor-keys: 4.2.1 + espree@9.6.1: dependencies: acorn: 8.14.1 @@ -10347,6 +10737,10 @@ snapshots: optionalDependencies: picomatch: 4.0.2 + fdir@6.4.6(picomatch@4.0.2): + optionalDependencies: + picomatch: 4.0.2 + figures@3.2.0: dependencies: escape-string-regexp: 1.0.5 @@ -10586,6 +10980,8 @@ snapshots: globals@16.1.0: {} + globals@16.3.0: {} + globalthis@1.0.4: dependencies: define-properties: 1.2.1 @@ -11941,6 +12337,12 @@ snapshots: picocolors: 1.1.1 source-map-js: 1.2.1 + postcss@8.5.6: + dependencies: + nanoid: 3.3.11 + picocolors: 1.1.1 + source-map-js: 1.2.1 + preact@10.26.7: {} prelude-ls@1.2.1: {} @@ -12822,6 +13224,11 @@ snapshots: fdir: 6.4.4(picomatch@4.0.2) picomatch: 4.0.2 + tinyglobby@0.2.14: + dependencies: + fdir: 6.4.6(picomatch@4.0.2) + picomatch: 4.0.2 + tinypool@1.0.2: {} tinyrainbow@2.0.0: {} @@ -13153,7 +13560,41 @@ snapshots: terser: 5.39.2 yaml: 2.8.0 - vitepress@1.6.3(@algolia/client-search@5.25.0)(@types/node@24.0.3)(@types/react@18.3.23)(axios@1.9.0)(fuse.js@7.1.0)(jwt-decode@4.0.0)(lightningcss@1.30.1)(postcss@8.5.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.89.0)(search-insights@2.17.3)(terser@5.39.2)(typescript@5.8.3): + vite@7.0.2(@types/node@20.17.50)(jiti@2.4.2)(lightningcss@1.30.1)(sass@1.89.0)(terser@5.39.2)(yaml@2.8.0): + dependencies: + esbuild: 0.25.4 + fdir: 6.4.6(picomatch@4.0.2) + picomatch: 4.0.2 + postcss: 8.5.6 + rollup: 4.40.2 + tinyglobby: 0.2.14 + optionalDependencies: + '@types/node': 20.17.50 + fsevents: 2.3.3 + jiti: 2.4.2 + lightningcss: 1.30.1 + sass: 1.89.0 + terser: 5.39.2 + yaml: 2.8.0 + + vite@7.0.2(@types/node@24.0.3)(jiti@2.4.2)(lightningcss@1.30.1)(sass@1.89.0)(terser@5.39.2)(yaml@2.8.0): + dependencies: + esbuild: 0.25.4 + fdir: 6.4.6(picomatch@4.0.2) + picomatch: 4.0.2 + postcss: 8.5.6 + rollup: 4.40.2 + tinyglobby: 0.2.14 + optionalDependencies: + '@types/node': 24.0.3 + fsevents: 2.3.3 + jiti: 2.4.2 + lightningcss: 1.30.1 + sass: 1.89.0 + terser: 5.39.2 + yaml: 2.8.0 + + vitepress@1.6.3(@algolia/client-search@5.25.0)(@types/node@24.0.3)(@types/react@18.3.23)(axios@1.9.0)(fuse.js@7.1.0)(jwt-decode@4.0.0)(lightningcss@1.30.1)(postcss@8.5.6)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.89.0)(search-insights@2.17.3)(terser@5.39.2)(typescript@5.8.3): dependencies: '@docsearch/css': 3.8.2 '@docsearch/js': 3.8.2(@algolia/client-search@5.25.0)(@types/react@18.3.23)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(search-insights@2.17.3) @@ -13174,7 +13615,7 @@ snapshots: vite: 5.4.19(@types/node@24.0.3)(lightningcss@1.30.1)(sass@1.89.0)(terser@5.39.2) vue: 3.5.14(typescript@5.8.3) optionalDependencies: - postcss: 8.5.3 + postcss: 8.5.6 transitivePeerDependencies: - '@algolia/client-search' - '@types/node' From 399a2e14473c545a3c549aa626a028f1640f227f Mon Sep 17 00:00:00 2001 From: Brion Date: Tue, 8 Jul 2025 21:01:37 +0530 Subject: [PATCH 12/12] =?UTF-8?q?chore:=20add=20changeset=20=F0=9F=A6=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .changeset/warm-dots-obey.md | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 .changeset/warm-dots-obey.md diff --git a/.changeset/warm-dots-obey.md b/.changeset/warm-dots-obey.md new file mode 100644 index 00000000..6e480ed1 --- /dev/null +++ b/.changeset/warm-dots-obey.md @@ -0,0 +1,8 @@ +--- +'@asgardeo/javascript': patch +'@asgardeo/browser': patch +'@asgardeo/nextjs': patch +'@asgardeo/react': patch +--- + +Expose `http` module instead of `fetch`