diff --git a/src/Auth0.ts b/src/Auth0.ts new file mode 100644 index 00000000..baaa43a5 --- /dev/null +++ b/src/Auth0.ts @@ -0,0 +1,64 @@ +import type { IAuth0Client } from './core/interfaces/IAuth0Client'; +import { Auth0ClientFactory } from './factory/Auth0ClientFactory'; +import type { Auth0Options } from './types'; + +/** + * The main Auth0 client class. + * + * This class acts as a facade, creating and delegating to a platform-specific + * client instance (Native or Web) under the hood. + * + * @example + * ``` + * import Auth0 from 'react-native-auth0'; + * + * const auth0 = new Auth0({ + * domain: 'YOUR_AUTH0_DOMAIN', + * clientId: 'YOUR_AUTH0_CLIENT_ID' + * }); + * ``` + */ +export class Auth0 { + private client: IAuth0Client; + + /** + * Creates an instance of the Auth0 client. + * @param options Configuration options for the client. + */ + constructor(options: Auth0Options) { + // The factory detects the platform and returns the appropriate client implementation. + // The rest of this class is completely unaware of whether it's running on native or web. + this.client = Auth0ClientFactory.createClient(options); + } + + /** + * Provides access to the web-based authentication methods. + * @see IWebAuthProvider + */ + get webAuth() { + return this.client.webAuth; + } + + /** + * Provides access to the credentials management methods. + * @see ICredentialsManager + */ + get credentialsManager() { + return this.client.credentialsManager; + } + + /** + * Provides access to direct authentication methods (e.g., password-realm). + * @see IAuthenticationProvider + */ + get auth() { + return this.client.auth; + } + + /** + * Provides access to the Management API (e.g., for user patching). + */ + users(token: string) { + return this.client.users(token); + } +} diff --git a/src/core/models/Auth0User.ts b/src/core/models/Auth0User.ts index cd9c33be..c8b7f20f 100644 --- a/src/core/models/Auth0User.ts +++ b/src/core/models/Auth0User.ts @@ -1,6 +1,6 @@ import { jwtDecode } from 'jwt-decode'; import type { User } from '../../types'; -import { snakeToCamel } from '../utils'; +import { snakeToCamel } from '../utils/stringUtils'; /** * A Set containing all OIDC protocol claims that are part of a standard ID token diff --git a/src/core/services/AuthenticationOrchestrator.ts b/src/core/services/AuthenticationOrchestrator.ts index ea5fcb29..78991626 100644 --- a/src/core/services/AuthenticationOrchestrator.ts +++ b/src/core/services/AuthenticationOrchestrator.ts @@ -30,7 +30,7 @@ import { } from '../models'; import { validateParameters } from '../utils/validation'; import { HttpClient } from './HttpClient'; -import { deepCamelCase } from '../utils'; +import { deepCamelCase, finalizeScope } from '../utils'; // Represents the raw user profile returned by an API (snake_case) type RawUser = { [key: string]: any }; @@ -212,7 +212,7 @@ export class AuthenticationOrchestrator implements IAuthenticationProvider { otp: payload.code, realm: 'email', audience: payload.audience, - scope: payload.scope, + scope: finalizeScope(payload.scope), }; const { json, response } = await this.client.post( @@ -234,7 +234,7 @@ export class AuthenticationOrchestrator implements IAuthenticationProvider { otp: payload.code, realm: 'sms', audience: payload.audience, - scope: payload.scope, + scope: finalizeScope(payload.scope), }; const { json, response } = await this.client.post( diff --git a/src/core/utils/conversion.ts b/src/core/utils/conversion.ts index d4f7cef6..fb2b77a6 100644 --- a/src/core/utils/conversion.ts +++ b/src/core/utils/conversion.ts @@ -1,18 +1,4 @@ -/** - * A private helper that converts a single snake_case or kebab-case string to camelCase. - * e.g., 'user_profile' -> 'userProfile' - */ -export function snakeToCamel(str: string): string { - var parts = str.split('_').filter((part) => part.length > 0); - if (parts.length === 0) return ''; - - return parts.reduce(function (p, c, index) { - if (index === 0) { - return c.charAt(0).toLowerCase() + c.slice(1); - } - return p + c.charAt(0).toUpperCase() + c.slice(1); - }, ''); -} +import { snakeToCamel } from './stringUtils'; /** * Recursively traverses an object or an array and converts all keys from @@ -65,3 +51,6 @@ export function toUrlQueryParams(params: Record): string { } return searchParams.toString(); } + +// Re-export snakeToCamel for backward compatibility +export { snakeToCamel }; diff --git a/src/core/utils/stringUtils.ts b/src/core/utils/stringUtils.ts new file mode 100644 index 00000000..96f0a3e3 --- /dev/null +++ b/src/core/utils/stringUtils.ts @@ -0,0 +1,20 @@ +/** + * Pure string utility functions with no external dependencies. + * This avoids circular dependencies with models. + */ + +/** + * A helper that converts a single snake_case or kebab-case string to camelCase. + * e.g., 'user_profile' -> 'userProfile' + */ +export function snakeToCamel(str: string): string { + var parts = str.split('_').filter((part) => part.length > 0); + if (parts.length === 0) return ''; + + return parts.reduce(function (p, c, index) { + if (index === 0) { + return c.charAt(0).toLowerCase() + c.slice(1); + } + return p + c.charAt(0).toUpperCase() + c.slice(1); + }, ''); +} diff --git a/src/hooks/Auth0Provider.tsx b/src/hooks/Auth0Provider.tsx index 92c75bb0..a05c36d8 100644 --- a/src/hooks/Auth0Provider.tsx +++ b/src/hooks/Auth0Provider.tsx @@ -29,8 +29,8 @@ import type { NativeClearSessionOptions, } from '../types/platform-specific'; import { Auth0User, AuthError } from '../core/models'; -import Auth0 from '../index'; import { Platform } from 'react-native'; +import { Auth0 } from '../Auth0'; export const Auth0Provider = ({ children, diff --git a/src/index.ts b/src/index.ts index b761abe6..a11600fa 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,6 +1,4 @@ -import type { IAuth0Client } from './core/interfaces/IAuth0Client'; -import { Auth0ClientFactory } from './factory/Auth0ClientFactory'; -import type { Auth0Options } from './types'; +import { Auth0 } from './Auth0'; export { AuthError, @@ -8,6 +6,7 @@ export { WebAuthError, } from './core/models'; export { TimeoutError } from './core/utils/fetchWithTimeout'; +export { snakeToCamel, deepCamelCase } from './core/utils/conversion'; export { Auth0Provider } from './hooks/Auth0Provider'; export { useAuth0 } from './hooks/useAuth0'; export * from './types'; @@ -17,65 +16,4 @@ export type { LocalAuthenticationStrategy, } from './types/platform-specific'; -/** - * The main Auth0 client class. - * - * This class acts as a facade, creating and delegating to a platform-specific - * client instance (Native or Web) under the hood. - * - * @example - * ``` - * import Auth0 from 'react-native-auth0'; - * - * const auth0 = new Auth0({ - * domain: 'YOUR_AUTH0_DOMAIN', - * clientId: 'YOUR_AUTH0_CLIENT_ID' - * }); - * ``` - */ -class Auth0 { - private client: IAuth0Client; - - /** - * Creates an instance of the Auth0 client. - * @param options Configuration options for the client. - */ - constructor(options: Auth0Options) { - // The factory detects the platform and returns the appropriate client implementation. - // The rest of this class is completely unaware of whether it's running on native or web. - this.client = Auth0ClientFactory.createClient(options); - } - - /** - * Provides access to the web-based authentication methods. - * @see IWebAuthProvider - */ - get webAuth() { - return this.client.webAuth; - } - - /** - * Provides access to the credentials management methods. - * @see ICredentialsManager - */ - get credentialsManager() { - return this.client.credentialsManager; - } - - /** - * Provides access to direct authentication methods (e.g., password-realm). - * @see IAuthenticationProvider - */ - get auth() { - return this.client.auth; - } - - /** - * Provides access to the Management API (e.g., for user patching). - */ - users(token: string) { - return this.client.users(token); - } -} - export default Auth0;