@habeetat/sdk-react 0.1.0-dev.20260330160419.ec63152 → 0.1.0-dev.20260403141840.b34ffd7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -96,7 +96,7 @@ function HabeetatData({
96
96
  subscription: null
97
97
  });
98
98
  const apiUrl = react.useMemo(() => platformUrl.replace(/\/$/, ""), [platformUrl]);
99
- const fetchApi = react.useCallback(
99
+ const fetchApiImpl = react.useCallback(
100
100
  async (endpoint) => {
101
101
  let token;
102
102
  try {
@@ -119,30 +119,34 @@ function HabeetatData({
119
119
  },
120
120
  [apiUrl, tokenResource, tenantSlug, appId, getAccessToken]
121
121
  );
122
+ const fetchApiRef = react.useRef(fetchApiImpl);
123
+ react.useEffect(() => {
124
+ fetchApiRef.current = fetchApiImpl;
125
+ }, [fetchApiImpl]);
122
126
  const refreshContext = react.useCallback(async () => {
123
127
  try {
124
- const context = await fetchApi(sdkCore.SDK_ENDPOINTS.CONTEXT);
128
+ const context = await fetchApiRef.current(sdkCore.SDK_ENDPOINTS.CONTEXT);
125
129
  setState((prev) => ({ ...prev, context, error: null }));
126
130
  } catch (error) {
127
131
  setState((prev) => ({ ...prev, error }));
128
132
  }
129
- }, [fetchApi]);
133
+ }, []);
130
134
  const refreshFeatures = react.useCallback(async () => {
131
135
  try {
132
- const features = await fetchApi(sdkCore.SDK_ENDPOINTS.FEATURES);
136
+ const features = await fetchApiRef.current(sdkCore.SDK_ENDPOINTS.FEATURES);
133
137
  setState((prev) => ({ ...prev, features, error: null }));
134
138
  } catch (error) {
135
139
  setState((prev) => ({ ...prev, error }));
136
140
  }
137
- }, [fetchApi]);
141
+ }, []);
138
142
  const refreshSubscription = react.useCallback(async () => {
139
143
  try {
140
- const subscription = await fetchApi(sdkCore.SDK_ENDPOINTS.SUBSCRIPTION);
144
+ const subscription = await fetchApiRef.current(sdkCore.SDK_ENDPOINTS.SUBSCRIPTION);
141
145
  setState((prev) => ({ ...prev, subscription, error: null }));
142
146
  } catch (error) {
143
147
  setState((prev) => ({ ...prev, error }));
144
148
  }
145
- }, [fetchApi]);
149
+ }, []);
146
150
  const hasPermission = react.useCallback(
147
151
  (permission) => state.context?.permissions?.includes(permission) ?? false,
148
152
  [state.context?.permissions]
@@ -171,9 +175,9 @@ function HabeetatData({
171
175
  setState((prev) => ({ ...prev, isLoading: true }));
172
176
  try {
173
177
  const [context, features, subscription] = await Promise.all([
174
- fetchApi(sdkCore.SDK_ENDPOINTS.CONTEXT).catch(() => null),
175
- fetchApi(sdkCore.SDK_ENDPOINTS.FEATURES).catch(() => null),
176
- fetchApi(sdkCore.SDK_ENDPOINTS.SUBSCRIPTION).catch(() => null)
178
+ fetchApiRef.current(sdkCore.SDK_ENDPOINTS.CONTEXT).catch(() => null),
179
+ fetchApiRef.current(sdkCore.SDK_ENDPOINTS.FEATURES).catch(() => null),
180
+ fetchApiRef.current(sdkCore.SDK_ENDPOINTS.SUBSCRIPTION).catch(() => null)
177
181
  ]);
178
182
  setState({ isLoading: false, error: null, context, features, subscription });
179
183
  } catch (error) {
@@ -181,7 +185,7 @@ function HabeetatData({
181
185
  }
182
186
  };
183
187
  fetchAll();
184
- }, [fetchApi]);
188
+ }, []);
185
189
  const contextValue = react.useMemo(
186
190
  () => ({
187
191
  ...state,
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/context/HabeetatContext.ts","../src/provider/HabeetatProvider.tsx","../src/hooks/useHabeetat.ts","../src/hooks/usePermissions.ts","../src/hooks/useFeatures.ts","../src/hooks/useSubscription.ts","../src/hooks/useAuth.ts","../src/hooks/useSignIn.ts","../src/hooks/useSignOut.ts","../src/logger/HabeetatLoggerClient.ts","../src/hooks/useLogger.ts","../src/hooks/useAnalytics.ts","../src/components/RequirePermission.tsx","../src/components/RequireFeature.tsx"],"names":["createContext","useHandleSignInCallback","jsx","Fragment","useLogto","useRef","useEffect","useState","useMemo","useCallback","SDK_ENDPOINTS","LogtoProvider","useContext"],"mappings":"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","file":"index.js","sourcesContent":["import { createContext } from 'react';\nimport type { SdkContext, SdkFeaturesState, SdkSubscription } from '@habeetat/sdk-core';\n\n/**\n * Habeetat SDK state\n */\nexport interface HabeetatState {\n /** Whether the SDK is loading initial data */\n isLoading: boolean;\n /** Error if any occurred */\n error: Error | null;\n /** SDK context (user, tenant, permissions) */\n context: SdkContext | null;\n /** Feature flags */\n features: SdkFeaturesState | null;\n /** Subscription info */\n subscription: SdkSubscription | null;\n}\n\n/**\n * Habeetat SDK context value\n */\nexport interface HabeetatContextValue extends HabeetatState {\n /** Refresh context from server */\n refreshContext: () => Promise<void>;\n /** Refresh features from server */\n refreshFeatures: () => Promise<void>;\n /** Refresh subscription from server */\n refreshSubscription: () => Promise<void>;\n /** Check if user has permission */\n hasPermission: (permission: string) => boolean;\n /** Check if user has any of the permissions */\n hasAnyPermission: (permissions: string[]) => boolean;\n /** Check if user has all permissions */\n hasAllPermissions: (permissions: string[]) => boolean;\n /** Check if feature is enabled */\n isFeatureEnabled: (key: string) => boolean;\n /** Get access token for API calls */\n getAccessToken: () => Promise<string | null>;\n /** Platform SDK API base URL (for internal use by useLogger) */\n platformUrl: string | null;\n /** App name for analytics tracking */\n appName?: string;\n /** Current tenant slug */\n tenantSlug?: string;\n /** Logger configuration */\n loggerConfig?: { enabled?: boolean; level?: import('@habeetat/sdk-core').LogLevel };\n}\n\n/**\n * Default context value\n */\nconst defaultContextValue: HabeetatContextValue = {\n isLoading: true,\n error: null,\n context: null,\n features: null,\n subscription: null,\n refreshContext: async () => {},\n refreshFeatures: async () => {},\n refreshSubscription: async () => {},\n hasPermission: () => false,\n hasAnyPermission: () => false,\n hasAllPermissions: () => false,\n isFeatureEnabled: () => false,\n getAccessToken: async () => null,\n platformUrl: null,\n};\n\n/**\n * Habeetat React Context\n */\nexport const HabeetatContext = createContext<HabeetatContextValue>(defaultContextValue);\n","import {\n useState,\n useEffect,\n useCallback,\n useMemo,\n useRef,\n type ReactNode,\n} from 'react';\nimport { LogtoProvider, useLogto, useHandleSignInCallback } from '@logto/react';\nimport { SDK_ENDPOINTS } from '@habeetat/sdk-core';\nimport type { SdkContext, SdkFeaturesState, SdkSubscription } from '@habeetat/sdk-core';\nimport { HabeetatContext, type HabeetatContextValue, type HabeetatState } from '../context/HabeetatContext';\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\nexport interface LogtoConfig {\n /** Logto endpoint (e.g. https://iam.yourdomain.com) */\n endpoint: string;\n /** OIDC application ID registered in Logto */\n appId: string;\n /** API resources to request access tokens for */\n resources?: string[];\n /** Additional OIDC scopes */\n scopes?: string[];\n}\n\nexport interface HabeetatProviderProps {\n /** Logto OIDC configuration — replaces the need for a separate LogtoProvider */\n logto: LogtoConfig;\n /** Platform SDK base URL (e.g. https://api.yourdomain.com/sdk/v1) */\n platformUrl: string;\n /** API resource identifier for access-token requests; defaults to platformUrl */\n logtoResource?: string;\n /** App slug registered in Habeetat */\n appId?: string;\n /** App name used as app_id when tracking analytics events */\n appName?: string;\n /** Tenant slug */\n tenantSlug?: string;\n /**\n * Redirect to Logto automatically when the user is not authenticated.\n * A ref guard prevents redirect loops.\n */\n autoSignIn?: boolean;\n /** Path that handles the OIDC callback (default: '/callback') */\n callbackPath?: string;\n /** Rendered while auth state is loading */\n loadingFallback?: ReactNode;\n /** Centralized logging configuration */\n logging?: { enabled?: boolean; level?: import('@habeetat/sdk-core').LogLevel };\n children: ReactNode;\n}\n\n// ---------------------------------------------------------------------------\n// Callback handler — isolated so useHandleSignInCallback can be called\n// without breaking hooks rules in the main inner component\n// ---------------------------------------------------------------------------\n\ninterface CallbackHandlerProps {\n loadingFallback?: ReactNode;\n}\n\nfunction CallbackHandler({ loadingFallback }: CallbackHandlerProps) {\n const { isLoading } = useHandleSignInCallback(() => {\n window.location.href = '/';\n });\n\n if (isLoading) return loadingFallback ? <>{loadingFallback}</> : null;\n return null;\n}\n\n// ---------------------------------------------------------------------------\n// Inner provider — runs inside LogtoProvider so it can call useLogto()\n// ---------------------------------------------------------------------------\n\ninterface InnerProps {\n platformUrl: string;\n logtoResource?: string;\n appId?: string;\n appName?: string;\n tenantSlug?: string;\n autoSignIn?: boolean;\n callbackPath: string;\n loadingFallback?: ReactNode;\n logging?: { enabled?: boolean; level?: import('@habeetat/sdk-core').LogLevel };\n children: ReactNode;\n}\n\nfunction HabeetatInner({\n platformUrl,\n logtoResource,\n appId,\n appName,\n tenantSlug,\n autoSignIn,\n callbackPath,\n loadingFallback,\n logging,\n children,\n}: InnerProps) {\n const { isAuthenticated, isLoading: logtoLoading, getAccessToken, signIn } = useLogto();\n\n const tokenResource = logtoResource ?? platformUrl;\n const signInCalled = useRef(false);\n\n const isCallback =\n typeof window !== 'undefined' &&\n window.location.pathname === callbackPath;\n\n // Auto sign-in redirect\n useEffect(() => {\n if (isCallback || logtoLoading || isAuthenticated || !autoSignIn || signInCalled.current)\n return;\n signInCalled.current = true;\n const redirectUri =\n typeof window !== 'undefined'\n ? `${window.location.origin}${callbackPath}`\n : callbackPath;\n signIn(redirectUri);\n }, [isCallback, logtoLoading, isAuthenticated, autoSignIn, signIn, callbackPath]);\n\n // Delegate to callback handler when on the callback path\n if (isCallback) {\n return <CallbackHandler loadingFallback={loadingFallback} />;\n }\n\n if (logtoLoading) {\n return loadingFallback ? <>{loadingFallback}</> : null;\n }\n\n return (\n <HabeetatData\n platformUrl={platformUrl}\n logtoResource={logtoResource}\n appId={appId}\n appName={appName}\n tenantSlug={tenantSlug}\n getAccessToken={getAccessToken}\n tokenResource={tokenResource}\n loadingFallback={loadingFallback}\n logging={logging}\n >\n {children}\n </HabeetatData>\n );\n}\n\n// ---------------------------------------------------------------------------\n// Data layer — fetches SDK context/features/subscription\n// ---------------------------------------------------------------------------\n\ninterface DataProps {\n platformUrl: string;\n logtoResource?: string;\n appId?: string;\n appName?: string;\n tenantSlug?: string;\n tokenResource: string;\n getAccessToken: (resource?: string) => Promise<string | undefined>;\n loadingFallback?: ReactNode;\n logging?: { enabled?: boolean; level?: import('@habeetat/sdk-core').LogLevel };\n children: ReactNode;\n}\n\nfunction HabeetatData({\n platformUrl,\n appId,\n appName,\n tenantSlug,\n tokenResource,\n getAccessToken,\n logging,\n children,\n}: DataProps) {\n const [state, setState] = useState<HabeetatState>({\n isLoading: true,\n error: null,\n context: null,\n features: null,\n subscription: null,\n });\n\n const apiUrl = useMemo(() => platformUrl.replace(/\\/$/, ''), [platformUrl]);\n\n const fetchApi = useCallback(\n async <T,>(endpoint: string): Promise<T> => {\n let token: string | undefined;\n try {\n token = await getAccessToken(tokenResource);\n } catch (err) {\n throw new Error(`Failed to get access token: ${err}`);\n }\n if (!token) throw new Error('No access token available');\n\n const url = new URL(endpoint, apiUrl);\n if (tenantSlug) url.searchParams.set('tenantSlug', tenantSlug);\n if (appId) url.searchParams.set('appId', appId);\n\n const response = await fetch(url.toString(), {\n headers: {\n Authorization: `Bearer ${token}`,\n 'Content-Type': 'application/json',\n },\n });\n if (!response.ok) throw new Error(`API error: ${response.status}`);\n return response.json() as Promise<T>;\n },\n [apiUrl, tokenResource, tenantSlug, appId, getAccessToken],\n );\n\n const refreshContext = useCallback(async () => {\n try {\n const context = await fetchApi<SdkContext>(SDK_ENDPOINTS.CONTEXT);\n setState((prev) => ({ ...prev, context, error: null }));\n } catch (error) {\n setState((prev) => ({ ...prev, error: error as Error }));\n }\n }, [fetchApi]);\n\n const refreshFeatures = useCallback(async () => {\n try {\n const features = await fetchApi<SdkFeaturesState>(SDK_ENDPOINTS.FEATURES);\n setState((prev) => ({ ...prev, features, error: null }));\n } catch (error) {\n setState((prev) => ({ ...prev, error: error as Error }));\n }\n }, [fetchApi]);\n\n const refreshSubscription = useCallback(async () => {\n try {\n const subscription = await fetchApi<SdkSubscription>(SDK_ENDPOINTS.SUBSCRIPTION);\n setState((prev) => ({ ...prev, subscription, error: null }));\n } catch (error) {\n setState((prev) => ({ ...prev, error: error as Error }));\n }\n }, [fetchApi]);\n\n const hasPermission = useCallback(\n (permission: string) => state.context?.permissions?.includes(permission) ?? false,\n [state.context?.permissions],\n );\n\n const hasAnyPermission = useCallback(\n (permissions: string[]) => permissions.some((p) => state.context?.permissions?.includes(p)),\n [state.context?.permissions],\n );\n\n const hasAllPermissions = useCallback(\n (permissions: string[]) => permissions.every((p) => state.context?.permissions?.includes(p)),\n [state.context?.permissions],\n );\n\n const isFeatureEnabled = useCallback(\n (key: string) => state.features?.features?.[key] ?? false,\n [state.features?.features],\n );\n\n const getToken = useCallback(async (): Promise<string | null> => {\n try {\n return (await getAccessToken(tokenResource)) ?? null;\n } catch {\n return null;\n }\n }, [getAccessToken, tokenResource]);\n\n // Fetch SDK data on mount\n useEffect(() => {\n const fetchAll = async () => {\n setState((prev) => ({ ...prev, isLoading: true }));\n try {\n const [context, features, subscription] = await Promise.all([\n fetchApi<SdkContext>(SDK_ENDPOINTS.CONTEXT).catch(() => null),\n fetchApi<SdkFeaturesState>(SDK_ENDPOINTS.FEATURES).catch(() => null),\n fetchApi<SdkSubscription>(SDK_ENDPOINTS.SUBSCRIPTION).catch(() => null),\n ]);\n setState({ isLoading: false, error: null, context, features, subscription });\n } catch (error) {\n setState((prev) => ({ ...prev, isLoading: false, error: error as Error }));\n }\n };\n\n fetchAll();\n }, [fetchApi]);\n\n const contextValue: HabeetatContextValue = useMemo(\n () => ({\n ...state,\n refreshContext,\n refreshFeatures,\n refreshSubscription,\n hasPermission,\n hasAnyPermission,\n hasAllPermissions,\n isFeatureEnabled,\n getAccessToken: getToken,\n platformUrl: apiUrl,\n appName,\n tenantSlug,\n loggerConfig: logging,\n }),\n [\n state,\n refreshContext,\n refreshFeatures,\n refreshSubscription,\n hasPermission,\n hasAnyPermission,\n hasAllPermissions,\n isFeatureEnabled,\n getToken,\n apiUrl,\n appName,\n tenantSlug,\n logging,\n ],\n );\n\n return (\n <HabeetatContext.Provider value={contextValue}>\n {children}\n </HabeetatContext.Provider>\n );\n}\n\n// ---------------------------------------------------------------------------\n// Public provider — wraps LogtoProvider so callers don't need to\n// ---------------------------------------------------------------------------\n\n/**\n * HabeetatProvider — single provider for Habeetat auth + SDK context.\n *\n * Internally wraps `LogtoProvider` from `@logto/react`, so you no longer\n * need to install or import that package in your application.\n *\n * @example\n * ```tsx\n * import { HabeetatProvider } from '@habeetat/sdk-react';\n *\n * <HabeetatProvider\n * logto={{\n * endpoint: 'https://iam.example.com',\n * appId: 'abc123',\n * resources: ['https://api.example.com/api'],\n * }}\n * platformUrl=\"https://api.example.com/sdk/v1\"\n * tenantSlug=\"acme\"\n * autoSignIn\n * callbackPath=\"/callback\"\n * >\n * <App />\n * </HabeetatProvider>\n * ```\n */\nexport function HabeetatProvider({\n logto,\n platformUrl,\n logtoResource,\n appId,\n appName,\n tenantSlug,\n autoSignIn = false,\n callbackPath = '/callback',\n loadingFallback,\n logging,\n children,\n}: HabeetatProviderProps) {\n const logtoConfig = useMemo(\n () => ({\n endpoint: logto.endpoint,\n appId: logto.appId,\n ...(logto.resources && { resources: logto.resources }),\n ...(logto.scopes && { scopes: logto.scopes }),\n }),\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [logto.endpoint, logto.appId, logto.resources, logto.scopes],\n );\n\n return (\n <LogtoProvider config={logtoConfig}>\n <HabeetatInner\n platformUrl={platformUrl}\n logtoResource={logtoResource}\n appId={appId}\n appName={appName}\n tenantSlug={tenantSlug}\n autoSignIn={autoSignIn}\n callbackPath={callbackPath}\n loadingFallback={loadingFallback}\n logging={logging}\n >\n {children}\n </HabeetatInner>\n </LogtoProvider>\n );\n}\n","import { useContext } from 'react';\nimport { HabeetatContext, type HabeetatContextValue } from '../context/HabeetatContext';\n\n/**\n * Hook to access Habeetat SDK context\n * \n * @example\n * ```tsx\n * function MyComponent() {\n * const { context, isLoading, error } = useHabeetat();\n * \n * if (isLoading) return <Spinner />;\n * if (error) return <Error message={error.message} />;\n * \n * return <div>Hello, {context?.user.name}</div>;\n * }\n * ```\n */\nexport function useHabeetat(): HabeetatContextValue {\n const context = useContext(HabeetatContext);\n \n if (!context) {\n throw new Error('useHabeetat must be used within a HabeetatProvider');\n }\n \n return context;\n}\n","import { useHabeetat } from './useHabeetat';\n\n/**\n * Hook for permission checks\n * \n * @example\n * ```tsx\n * function ContactsPage() {\n * const { hasPermission, hasAnyPermission } = usePermissions();\n * \n * const canRead = hasPermission('contacts:read');\n * const canWrite = hasPermission('contacts:write');\n * const canManage = hasAnyPermission(['contacts:delete', 'contacts:admin']);\n * \n * return (\n * <div>\n * {canRead && <ContactsList />}\n * {canWrite && <AddContactButton />}\n * {canManage && <ManageContactsButton />}\n * </div>\n * );\n * }\n * ```\n */\nexport function usePermissions() {\n const { context, hasPermission, hasAnyPermission, hasAllPermissions } = useHabeetat();\n \n return {\n /** All user permissions */\n permissions: context?.permissions ?? [],\n /** All user roles */\n roles: context?.roles ?? [],\n /** Check if user has a specific permission */\n hasPermission,\n /** Check if user has any of the specified permissions */\n hasAnyPermission,\n /** Check if user has all of the specified permissions */\n hasAllPermissions,\n };\n}\n","import { useHabeetat } from './useHabeetat';\n\n/**\n * Hook for feature flag checks\n * \n * @example\n * ```tsx\n * function DealsPage() {\n * const { isEnabled, features } = useFeatures();\n * \n * if (!isEnabled('crm.deals.enabled')) {\n * return <UpgradePrompt feature=\"Deals\" />;\n * }\n * \n * return <DealsList />;\n * }\n * ```\n */\nexport function useFeatures() {\n const { features, isFeatureEnabled, refreshFeatures } = useHabeetat();\n \n return {\n /** All feature flags */\n features: features?.features ?? {},\n /** Feature source (plan, tenant, etc.) */\n source: features?.source,\n /** Plan code if source is plan */\n planCode: features?.planCode,\n /** Check if a feature is enabled */\n isEnabled: isFeatureEnabled,\n /** Refresh features from server */\n refresh: refreshFeatures,\n };\n}\n","import { useHabeetat } from './useHabeetat';\n\n/**\n * Hook for subscription and plan info\n */\nexport function useSubscription() {\n const { subscription, refreshSubscription } = useHabeetat();\n \n return {\n /** Current subscription */\n subscription,\n /** Current plan */\n plan: subscription?.plan,\n /** Plan limits */\n limits: subscription?.limits ?? {},\n /** Current usage */\n usage: subscription?.usage ?? {},\n /** Subscription status */\n status: subscription?.status,\n /** Check if subscription is active */\n isActive: subscription?.status === 'active' || subscription?.status === 'trialing',\n /** Check if in trial */\n isTrialing: subscription?.status === 'trialing',\n /** Check limit */\n checkLimit: (key: string, increment = 0): boolean => {\n const limit = subscription?.limits?.[key];\n const current = subscription?.usage?.[key] ?? 0;\n if (limit === undefined) return true;\n return current + increment <= limit;\n },\n /** Refresh subscription */\n refresh: refreshSubscription,\n };\n}\n","import { useLogto } from '@logto/react';\n\nexport interface AuthState {\n isAuthenticated: boolean;\n isLoading: boolean;\n}\n\n/**\n * Returns basic Logto auth state: `{ isAuthenticated, isLoading }`.\n */\nexport function useAuth(): AuthState {\n const { isAuthenticated, isLoading } = useLogto();\n return { isAuthenticated, isLoading };\n}\n","import { useLogto } from '@logto/react';\n\n/**\n * Returns a `signIn(redirectUri)` function that initiates the Logto sign-in flow.\n * The `redirectUri` must match one of the redirect URIs registered in Logto.\n */\nexport function useSignIn(): (redirectUri: string) => Promise<void> {\n const { signIn } = useLogto();\n return signIn;\n}\n","import { useLogto } from '@logto/react';\n\n/**\n * Returns a `signOut(postLogoutRedirectUri?)` function.\n */\nexport function useSignOut(): (postLogoutRedirectUri?: string) => Promise<void> {\n const { signOut } = useLogto();\n return signOut as (postLogoutRedirectUri?: string) => Promise<void>;\n}\n","import type { LogLevel } from '@habeetat/sdk-core';\nimport { SDK_ENDPOINTS } from '@habeetat/sdk-core';\n\nconst LOG_LEVEL_PRIORITY: Record<LogLevel, number> = {\n debug: 0,\n info: 1,\n warn: 2,\n error: 3,\n};\n\nexport interface FrontendLoggerConfig {\n /** Enable/disable logging (default: true) */\n enabled?: boolean;\n /** Minimum log level to emit (default: 'debug') */\n level?: LogLevel;\n /** Number of log records to buffer before flushing (default: 10) */\n batchSize?: number;\n /** Flush interval in milliseconds (default: 5000) */\n flushInterval?: number;\n}\n\ninterface LogEntry {\n level: LogLevel;\n message: string;\n tenantId?: string;\n context?: Record<string, unknown>;\n timestamp: string;\n source: 'frontend';\n serviceName?: string;\n}\n\n/**\n * Frontend logging client that batches log entries and sends them\n * to the platform backend via POST /sdk/v1/logs/batch.\n *\n * This class is framework-agnostic (no React dependency).\n */\nexport class HabeetatLoggerClient {\n private buffer: LogEntry[] = [];\n private flushTimer: ReturnType<typeof setInterval> | null = null;\n private readonly enabled: boolean;\n private readonly minLevel: number;\n private readonly batchSize: number;\n\n constructor(\n private readonly apiUrl: string,\n private readonly getAccessToken: () => Promise<string | null>,\n private readonly defaultAttributes: {\n tenantId?: string;\n appId?: string;\n userId?: string;\n serviceName?: string;\n },\n config?: FrontendLoggerConfig,\n ) {\n this.enabled = config?.enabled ?? true;\n this.minLevel = LOG_LEVEL_PRIORITY[config?.level ?? 'debug'];\n this.batchSize = config?.batchSize ?? 10;\n\n const interval = config?.flushInterval ?? 5000;\n if (this.enabled && interval > 0) {\n this.flushTimer = setInterval(() => this.flush(), interval);\n }\n }\n\n log(level: LogLevel, message: string, context?: Record<string, unknown>): void {\n if (!this.enabled) return;\n if (LOG_LEVEL_PRIORITY[level] < this.minLevel) return;\n\n this.buffer.push({\n level,\n message,\n tenantId: this.defaultAttributes.tenantId,\n context: {\n ...context,\n ...(this.defaultAttributes.appId && { appId: this.defaultAttributes.appId }),\n ...(this.defaultAttributes.userId && { userId: this.defaultAttributes.userId }),\n },\n timestamp: new Date().toISOString(),\n source: 'frontend',\n serviceName: this.defaultAttributes.serviceName,\n });\n\n if (this.buffer.length >= this.batchSize) {\n this.flush();\n }\n }\n\n debug(message: string, context?: Record<string, unknown>): void {\n this.log('debug', message, context);\n }\n\n info(message: string, context?: Record<string, unknown>): void {\n this.log('info', message, context);\n }\n\n warn(message: string, context?: Record<string, unknown>): void {\n this.log('warn', message, context);\n }\n\n error(message: string, context?: Record<string, unknown>): void {\n this.log('error', message, context);\n }\n\n /**\n * Flush buffered log entries to the backend.\n * Best-effort: failures are silently ignored.\n */\n async flush(): Promise<void> {\n if (this.buffer.length === 0) return;\n\n const entries = this.buffer.splice(0);\n\n try {\n const token = await this.getAccessToken();\n if (!token) return;\n\n const url = `${this.apiUrl}${SDK_ENDPOINTS.LOGS_BATCH}`;\n await fetch(url, {\n method: 'POST',\n headers: {\n Authorization: `Bearer ${token}`,\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify({ logs: entries }),\n });\n } catch {\n // Frontend logging is best-effort — silently drop on failure\n }\n }\n\n /**\n * Flush remaining logs and stop the timer.\n * Call this on component unmount.\n */\n destroy(): void {\n if (this.flushTimer) {\n clearInterval(this.flushTimer);\n this.flushTimer = null;\n }\n this.flush();\n }\n}\n","import { useRef, useEffect, useCallback, useMemo, useContext } from 'react';\nimport { HabeetatContext } from '../context/HabeetatContext';\nimport {\n HabeetatLoggerClient,\n type FrontendLoggerConfig,\n} from '../logger/HabeetatLoggerClient';\nimport type { LogLevel } from '@habeetat/sdk-core';\n\nexport interface UseLoggerReturn {\n log: (level: LogLevel, message: string, context?: Record<string, unknown>) => void;\n debug: (message: string, context?: Record<string, unknown>) => void;\n info: (message: string, context?: Record<string, unknown>) => void;\n warn: (message: string, context?: Record<string, unknown>) => void;\n error: (message: string, context?: Record<string, unknown>) => void;\n flush: () => Promise<void>;\n}\n\n/**\n * React hook that provides a logger connected to the Habeetat\n * centralized logging system (SigNoz via the backend).\n *\n * Logs are automatically enriched with user, tenant, and app context\n * from the HabeetatProvider.\n *\n * @example\n * ```tsx\n * function MyComponent() {\n * const logger = useLogger();\n *\n * const handleClick = () => {\n * logger.info('Button clicked', { buttonId: 'submit' });\n * };\n * }\n * ```\n */\nexport function useLogger(config?: FrontendLoggerConfig): UseLoggerReturn {\n const {\n platformUrl,\n getAccessToken,\n context: sdkContext,\n loggerConfig,\n } = useContext(HabeetatContext);\n\n const clientRef = useRef<HabeetatLoggerClient | null>(null);\n\n // Merge provider-level config with hook-level overrides\n const mergedConfig = useMemo<FrontendLoggerConfig>(\n () => ({\n enabled: config?.enabled ?? loggerConfig?.enabled ?? true,\n level: config?.level ?? loggerConfig?.level ?? 'debug',\n batchSize: config?.batchSize,\n flushInterval: config?.flushInterval,\n }),\n [config, loggerConfig],\n );\n\n // Recreate client when dependencies change\n useEffect(() => {\n if (!platformUrl) return;\n\n clientRef.current?.destroy();\n clientRef.current = new HabeetatLoggerClient(\n platformUrl,\n getAccessToken,\n {\n tenantId: sdkContext?.tenant?.id,\n appId: sdkContext?.app?.id,\n userId: sdkContext?.user?.id,\n },\n mergedConfig,\n );\n\n return () => {\n clientRef.current?.destroy();\n clientRef.current = null;\n };\n }, [platformUrl, getAccessToken, sdkContext?.tenant?.id, sdkContext?.app?.id, sdkContext?.user?.id, mergedConfig]);\n\n const log = useCallback(\n (level: LogLevel, message: string, context?: Record<string, unknown>) => {\n clientRef.current?.log(level, message, context);\n },\n [],\n );\n\n const debug = useCallback(\n (message: string, context?: Record<string, unknown>) => {\n clientRef.current?.debug(message, context);\n },\n [],\n );\n\n const info = useCallback(\n (message: string, context?: Record<string, unknown>) => {\n clientRef.current?.info(message, context);\n },\n [],\n );\n\n const warn = useCallback(\n (message: string, context?: Record<string, unknown>) => {\n clientRef.current?.warn(message, context);\n },\n [],\n );\n\n const error = useCallback(\n (message: string, context?: Record<string, unknown>) => {\n clientRef.current?.error(message, context);\n },\n [],\n );\n\n const flush = useCallback(async () => {\n await clientRef.current?.flush();\n }, []);\n\n return useMemo(\n () => ({ log, debug, info, warn, error, flush }),\n [log, debug, info, warn, error, flush],\n );\n}\n","import { useCallback } from 'react';\nimport { useHabeetat } from './useHabeetat';\n\ninterface TrackEventInput {\n eventName: string;\n properties?: Record<string, unknown>;\n sessionId?: string;\n timestamp?: string;\n}\n\nexport interface UseAnalyticsReturn {\n track: (events: TrackEventInput | TrackEventInput[]) => Promise<void>;\n}\n\n/**\n * Hook for tracking analytics events.\n * The `appName` is injected automatically from the HabeetatProvider config.\n *\n * @example\n * ```tsx\n * const { track } = useAnalytics();\n * await track({ eventName: 'button_click', properties: { button: 'save' } });\n * ```\n */\nexport function useAnalytics(): UseAnalyticsReturn {\n const { getAccessToken, platformUrl, appName, tenantSlug } = useHabeetat();\n\n const track = useCallback(async (events: TrackEventInput | TrackEventInput[]) => {\n if (!platformUrl || !tenantSlug) return;\n\n const token = await getAccessToken();\n if (!token) return;\n\n const eventList = Array.isArray(events) ? events : [events];\n\n await fetch(`${platformUrl}/analytics/track`, {\n method: 'POST',\n headers: {\n Authorization: `Bearer ${token}`,\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify({\n tenantId: tenantSlug,\n ...(appName && { appId: appName }),\n events: eventList,\n }),\n });\n }, [getAccessToken, platformUrl, appName, tenantSlug]);\n\n return { track };\n}\n","import { type ReactNode } from 'react';\nimport { usePermissions } from '../hooks/usePermissions';\n\ninterface RequirePermissionProps {\n permission: string;\n children: ReactNode;\n fallback?: ReactNode;\n}\n\n/**\n * Component that renders children only if user has the required permission\n */\nexport function RequirePermission({ permission, children, fallback = null }: RequirePermissionProps) {\n const { hasPermission } = usePermissions();\n \n if (!hasPermission(permission)) {\n return <>{fallback}</>;\n }\n \n return <>{children}</>;\n}\n","import { type ReactNode } from 'react';\nimport { useFeatures } from '../hooks/useFeatures';\n\ninterface RequireFeatureProps {\n flag: string;\n children: ReactNode;\n fallback?: ReactNode;\n}\n\n/**\n * Component that renders children only if the feature flag is enabled\n */\nexport function RequireFeature({ flag, children, fallback = null }: RequireFeatureProps) {\n const { isEnabled } = useFeatures();\n \n if (!isEnabled(flag)) {\n return <>{fallback}</>;\n }\n \n return <>{children}</>;\n}\n"]}
1
+ {"version":3,"sources":["../src/context/HabeetatContext.ts","../src/provider/HabeetatProvider.tsx","../src/hooks/useHabeetat.ts","../src/hooks/usePermissions.ts","../src/hooks/useFeatures.ts","../src/hooks/useSubscription.ts","../src/hooks/useAuth.ts","../src/hooks/useSignIn.ts","../src/hooks/useSignOut.ts","../src/logger/HabeetatLoggerClient.ts","../src/hooks/useLogger.ts","../src/hooks/useAnalytics.ts","../src/components/RequirePermission.tsx","../src/components/RequireFeature.tsx"],"names":["createContext","useHandleSignInCallback","jsx","Fragment","useLogto","useRef","useEffect","useState","useMemo","useCallback","SDK_ENDPOINTS","LogtoProvider","useContext"],"mappings":"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","file":"index.js","sourcesContent":["import { createContext } from 'react';\nimport type { SdkContext, SdkFeaturesState, SdkSubscription } from '@habeetat/sdk-core';\n\n/**\n * Habeetat SDK state\n */\nexport interface HabeetatState {\n /** Whether the SDK is loading initial data */\n isLoading: boolean;\n /** Error if any occurred */\n error: Error | null;\n /** SDK context (user, tenant, permissions) */\n context: SdkContext | null;\n /** Feature flags */\n features: SdkFeaturesState | null;\n /** Subscription info */\n subscription: SdkSubscription | null;\n}\n\n/**\n * Habeetat SDK context value\n */\nexport interface HabeetatContextValue extends HabeetatState {\n /** Refresh context from server */\n refreshContext: () => Promise<void>;\n /** Refresh features from server */\n refreshFeatures: () => Promise<void>;\n /** Refresh subscription from server */\n refreshSubscription: () => Promise<void>;\n /** Check if user has permission */\n hasPermission: (permission: string) => boolean;\n /** Check if user has any of the permissions */\n hasAnyPermission: (permissions: string[]) => boolean;\n /** Check if user has all permissions */\n hasAllPermissions: (permissions: string[]) => boolean;\n /** Check if feature is enabled */\n isFeatureEnabled: (key: string) => boolean;\n /** Get access token for API calls */\n getAccessToken: () => Promise<string | null>;\n /** Platform SDK API base URL (for internal use by useLogger) */\n platformUrl: string | null;\n /** App name for analytics tracking */\n appName?: string;\n /** Current tenant slug */\n tenantSlug?: string;\n /** Logger configuration */\n loggerConfig?: { enabled?: boolean; level?: import('@habeetat/sdk-core').LogLevel };\n}\n\n/**\n * Default context value\n */\nconst defaultContextValue: HabeetatContextValue = {\n isLoading: true,\n error: null,\n context: null,\n features: null,\n subscription: null,\n refreshContext: async () => {},\n refreshFeatures: async () => {},\n refreshSubscription: async () => {},\n hasPermission: () => false,\n hasAnyPermission: () => false,\n hasAllPermissions: () => false,\n isFeatureEnabled: () => false,\n getAccessToken: async () => null,\n platformUrl: null,\n};\n\n/**\n * Habeetat React Context\n */\nexport const HabeetatContext = createContext<HabeetatContextValue>(defaultContextValue);\n","import {\n useState,\n useEffect,\n useCallback,\n useMemo,\n useRef,\n type ReactNode,\n} from 'react';\nimport { LogtoProvider, useLogto, useHandleSignInCallback } from '@logto/react';\nimport { SDK_ENDPOINTS } from '@habeetat/sdk-core';\nimport type { SdkContext, SdkFeaturesState, SdkSubscription } from '@habeetat/sdk-core';\nimport { HabeetatContext, type HabeetatContextValue, type HabeetatState } from '../context/HabeetatContext';\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\nexport interface LogtoConfig {\n /** Logto endpoint (e.g. https://iam.yourdomain.com) */\n endpoint: string;\n /** OIDC application ID registered in Logto */\n appId: string;\n /** API resources to request access tokens for */\n resources?: string[];\n /** Additional OIDC scopes */\n scopes?: string[];\n}\n\nexport interface HabeetatProviderProps {\n /** Logto OIDC configuration — replaces the need for a separate LogtoProvider */\n logto: LogtoConfig;\n /** Platform SDK base URL (e.g. https://api.yourdomain.com/sdk/v1) */\n platformUrl: string;\n /** API resource identifier for access-token requests; defaults to platformUrl */\n logtoResource?: string;\n /** App slug registered in Habeetat */\n appId?: string;\n /** App name used as app_id when tracking analytics events */\n appName?: string;\n /** Tenant slug */\n tenantSlug?: string;\n /**\n * Redirect to Logto automatically when the user is not authenticated.\n * A ref guard prevents redirect loops.\n */\n autoSignIn?: boolean;\n /** Path that handles the OIDC callback (default: '/callback') */\n callbackPath?: string;\n /** Rendered while auth state is loading */\n loadingFallback?: ReactNode;\n /** Centralized logging configuration */\n logging?: { enabled?: boolean; level?: import('@habeetat/sdk-core').LogLevel };\n children: ReactNode;\n}\n\n// ---------------------------------------------------------------------------\n// Callback handler — isolated so useHandleSignInCallback can be called\n// without breaking hooks rules in the main inner component\n// ---------------------------------------------------------------------------\n\ninterface CallbackHandlerProps {\n loadingFallback?: ReactNode;\n}\n\nfunction CallbackHandler({ loadingFallback }: CallbackHandlerProps) {\n const { isLoading } = useHandleSignInCallback(() => {\n window.location.href = '/';\n });\n\n if (isLoading) return loadingFallback ? <>{loadingFallback}</> : null;\n return null;\n}\n\n// ---------------------------------------------------------------------------\n// Inner provider — runs inside LogtoProvider so it can call useLogto()\n// ---------------------------------------------------------------------------\n\ninterface InnerProps {\n platformUrl: string;\n logtoResource?: string;\n appId?: string;\n appName?: string;\n tenantSlug?: string;\n autoSignIn?: boolean;\n callbackPath: string;\n loadingFallback?: ReactNode;\n logging?: { enabled?: boolean; level?: import('@habeetat/sdk-core').LogLevel };\n children: ReactNode;\n}\n\nfunction HabeetatInner({\n platformUrl,\n logtoResource,\n appId,\n appName,\n tenantSlug,\n autoSignIn,\n callbackPath,\n loadingFallback,\n logging,\n children,\n}: InnerProps) {\n const { isAuthenticated, isLoading: logtoLoading, getAccessToken, signIn } = useLogto();\n\n const tokenResource = logtoResource ?? platformUrl;\n const signInCalled = useRef(false);\n\n const isCallback =\n typeof window !== 'undefined' &&\n window.location.pathname === callbackPath;\n\n // Auto sign-in redirect\n useEffect(() => {\n if (isCallback || logtoLoading || isAuthenticated || !autoSignIn || signInCalled.current)\n return;\n signInCalled.current = true;\n const redirectUri =\n typeof window !== 'undefined'\n ? `${window.location.origin}${callbackPath}`\n : callbackPath;\n signIn(redirectUri);\n }, [isCallback, logtoLoading, isAuthenticated, autoSignIn, signIn, callbackPath]);\n\n // Delegate to callback handler when on the callback path\n if (isCallback) {\n return <CallbackHandler loadingFallback={loadingFallback} />;\n }\n\n if (logtoLoading) {\n return loadingFallback ? <>{loadingFallback}</> : null;\n }\n\n return (\n <HabeetatData\n platformUrl={platformUrl}\n logtoResource={logtoResource}\n appId={appId}\n appName={appName}\n tenantSlug={tenantSlug}\n getAccessToken={getAccessToken}\n tokenResource={tokenResource}\n loadingFallback={loadingFallback}\n logging={logging}\n >\n {children}\n </HabeetatData>\n );\n}\n\n// ---------------------------------------------------------------------------\n// Data layer — fetches SDK context/features/subscription\n// ---------------------------------------------------------------------------\n\ninterface DataProps {\n platformUrl: string;\n logtoResource?: string;\n appId?: string;\n appName?: string;\n tenantSlug?: string;\n tokenResource: string;\n getAccessToken: (resource?: string) => Promise<string | undefined>;\n loadingFallback?: ReactNode;\n logging?: { enabled?: boolean; level?: import('@habeetat/sdk-core').LogLevel };\n children: ReactNode;\n}\n\nfunction HabeetatData({\n platformUrl,\n appId,\n appName,\n tenantSlug,\n tokenResource,\n getAccessToken,\n logging,\n children,\n}: DataProps) {\n const [state, setState] = useState<HabeetatState>({\n isLoading: true,\n error: null,\n context: null,\n features: null,\n subscription: null,\n });\n\n const apiUrl = useMemo(() => platformUrl.replace(/\\/$/, ''), [platformUrl]);\n\n const fetchApiImpl = useCallback(\n async <T,>(endpoint: string): Promise<T> => {\n let token: string | undefined;\n try {\n token = await getAccessToken(tokenResource);\n } catch (err) {\n throw new Error(`Failed to get access token: ${err}`);\n }\n if (!token) throw new Error('No access token available');\n\n const url = new URL(endpoint, apiUrl);\n if (tenantSlug) url.searchParams.set('tenantSlug', tenantSlug);\n if (appId) url.searchParams.set('appId', appId);\n\n const response = await fetch(url.toString(), {\n headers: {\n Authorization: `Bearer ${token}`,\n 'Content-Type': 'application/json',\n },\n });\n if (!response.ok) throw new Error(`API error: ${response.status}`);\n return response.json() as Promise<T>;\n },\n [apiUrl, tokenResource, tenantSlug, appId, getAccessToken],\n );\n\n const fetchApiRef = useRef(fetchApiImpl);\n useEffect(() => { fetchApiRef.current = fetchApiImpl; }, [fetchApiImpl]);\n\n const refreshContext = useCallback(async () => {\n try {\n const context = await fetchApiRef.current<SdkContext>(SDK_ENDPOINTS.CONTEXT);\n setState((prev) => ({ ...prev, context, error: null }));\n } catch (error) {\n setState((prev) => ({ ...prev, error: error as Error }));\n }\n }, []);\n\n const refreshFeatures = useCallback(async () => {\n try {\n const features = await fetchApiRef.current<SdkFeaturesState>(SDK_ENDPOINTS.FEATURES);\n setState((prev) => ({ ...prev, features, error: null }));\n } catch (error) {\n setState((prev) => ({ ...prev, error: error as Error }));\n }\n }, []);\n\n const refreshSubscription = useCallback(async () => {\n try {\n const subscription = await fetchApiRef.current<SdkSubscription>(SDK_ENDPOINTS.SUBSCRIPTION);\n setState((prev) => ({ ...prev, subscription, error: null }));\n } catch (error) {\n setState((prev) => ({ ...prev, error: error as Error }));\n }\n }, []);\n\n const hasPermission = useCallback(\n (permission: string) => state.context?.permissions?.includes(permission) ?? false,\n [state.context?.permissions],\n );\n\n const hasAnyPermission = useCallback(\n (permissions: string[]) => permissions.some((p) => state.context?.permissions?.includes(p)),\n [state.context?.permissions],\n );\n\n const hasAllPermissions = useCallback(\n (permissions: string[]) => permissions.every((p) => state.context?.permissions?.includes(p)),\n [state.context?.permissions],\n );\n\n const isFeatureEnabled = useCallback(\n (key: string) => state.features?.features?.[key] ?? false,\n [state.features?.features],\n );\n\n const getToken = useCallback(async (): Promise<string | null> => {\n try {\n return (await getAccessToken(tokenResource)) ?? null;\n } catch {\n return null;\n }\n }, [getAccessToken, tokenResource]);\n\n // Fetch SDK data on mount — runs once; fetchApiRef always points to the latest fetchApiImpl\n useEffect(() => {\n const fetchAll = async () => {\n setState((prev) => ({ ...prev, isLoading: true }));\n try {\n const [context, features, subscription] = await Promise.all([\n fetchApiRef.current<SdkContext>(SDK_ENDPOINTS.CONTEXT).catch(() => null),\n fetchApiRef.current<SdkFeaturesState>(SDK_ENDPOINTS.FEATURES).catch(() => null),\n fetchApiRef.current<SdkSubscription>(SDK_ENDPOINTS.SUBSCRIPTION).catch(() => null),\n ]);\n setState({ isLoading: false, error: null, context, features, subscription });\n } catch (error) {\n setState((prev) => ({ ...prev, isLoading: false, error: error as Error }));\n }\n };\n\n fetchAll();\n }, []);\n\n const contextValue: HabeetatContextValue = useMemo(\n () => ({\n ...state,\n refreshContext,\n refreshFeatures,\n refreshSubscription,\n hasPermission,\n hasAnyPermission,\n hasAllPermissions,\n isFeatureEnabled,\n getAccessToken: getToken,\n platformUrl: apiUrl,\n appName,\n tenantSlug,\n loggerConfig: logging,\n }),\n [\n state,\n refreshContext,\n refreshFeatures,\n refreshSubscription,\n hasPermission,\n hasAnyPermission,\n hasAllPermissions,\n isFeatureEnabled,\n getToken,\n apiUrl,\n appName,\n tenantSlug,\n logging,\n ],\n );\n\n return (\n <HabeetatContext.Provider value={contextValue}>\n {children}\n </HabeetatContext.Provider>\n );\n}\n\n// ---------------------------------------------------------------------------\n// Public provider — wraps LogtoProvider so callers don't need to\n// ---------------------------------------------------------------------------\n\n/**\n * HabeetatProvider — single provider for Habeetat auth + SDK context.\n *\n * Internally wraps `LogtoProvider` from `@logto/react`, so you no longer\n * need to install or import that package in your application.\n *\n * @example\n * ```tsx\n * import { HabeetatProvider } from '@habeetat/sdk-react';\n *\n * <HabeetatProvider\n * logto={{\n * endpoint: 'https://iam.example.com',\n * appId: 'abc123',\n * resources: ['https://api.example.com/api'],\n * }}\n * platformUrl=\"https://api.example.com/sdk/v1\"\n * tenantSlug=\"acme\"\n * autoSignIn\n * callbackPath=\"/callback\"\n * >\n * <App />\n * </HabeetatProvider>\n * ```\n */\nexport function HabeetatProvider({\n logto,\n platformUrl,\n logtoResource,\n appId,\n appName,\n tenantSlug,\n autoSignIn = false,\n callbackPath = '/callback',\n loadingFallback,\n logging,\n children,\n}: HabeetatProviderProps) {\n const logtoConfig = useMemo(\n () => ({\n endpoint: logto.endpoint,\n appId: logto.appId,\n ...(logto.resources && { resources: logto.resources }),\n ...(logto.scopes && { scopes: logto.scopes }),\n }),\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [logto.endpoint, logto.appId, logto.resources, logto.scopes],\n );\n\n return (\n <LogtoProvider config={logtoConfig}>\n <HabeetatInner\n platformUrl={platformUrl}\n logtoResource={logtoResource}\n appId={appId}\n appName={appName}\n tenantSlug={tenantSlug}\n autoSignIn={autoSignIn}\n callbackPath={callbackPath}\n loadingFallback={loadingFallback}\n logging={logging}\n >\n {children}\n </HabeetatInner>\n </LogtoProvider>\n );\n}\n","import { useContext } from 'react';\nimport { HabeetatContext, type HabeetatContextValue } from '../context/HabeetatContext';\n\n/**\n * Hook to access Habeetat SDK context\n * \n * @example\n * ```tsx\n * function MyComponent() {\n * const { context, isLoading, error } = useHabeetat();\n * \n * if (isLoading) return <Spinner />;\n * if (error) return <Error message={error.message} />;\n * \n * return <div>Hello, {context?.user.name}</div>;\n * }\n * ```\n */\nexport function useHabeetat(): HabeetatContextValue {\n const context = useContext(HabeetatContext);\n \n if (!context) {\n throw new Error('useHabeetat must be used within a HabeetatProvider');\n }\n \n return context;\n}\n","import { useHabeetat } from './useHabeetat';\n\n/**\n * Hook for permission checks\n * \n * @example\n * ```tsx\n * function ContactsPage() {\n * const { hasPermission, hasAnyPermission } = usePermissions();\n * \n * const canRead = hasPermission('contacts:read');\n * const canWrite = hasPermission('contacts:write');\n * const canManage = hasAnyPermission(['contacts:delete', 'contacts:admin']);\n * \n * return (\n * <div>\n * {canRead && <ContactsList />}\n * {canWrite && <AddContactButton />}\n * {canManage && <ManageContactsButton />}\n * </div>\n * );\n * }\n * ```\n */\nexport function usePermissions() {\n const { context, hasPermission, hasAnyPermission, hasAllPermissions } = useHabeetat();\n \n return {\n /** All user permissions */\n permissions: context?.permissions ?? [],\n /** All user roles */\n roles: context?.roles ?? [],\n /** Check if user has a specific permission */\n hasPermission,\n /** Check if user has any of the specified permissions */\n hasAnyPermission,\n /** Check if user has all of the specified permissions */\n hasAllPermissions,\n };\n}\n","import { useHabeetat } from './useHabeetat';\n\n/**\n * Hook for feature flag checks\n * \n * @example\n * ```tsx\n * function DealsPage() {\n * const { isEnabled, features } = useFeatures();\n * \n * if (!isEnabled('crm.deals.enabled')) {\n * return <UpgradePrompt feature=\"Deals\" />;\n * }\n * \n * return <DealsList />;\n * }\n * ```\n */\nexport function useFeatures() {\n const { features, isFeatureEnabled, refreshFeatures } = useHabeetat();\n \n return {\n /** All feature flags */\n features: features?.features ?? {},\n /** Feature source (plan, tenant, etc.) */\n source: features?.source,\n /** Plan code if source is plan */\n planCode: features?.planCode,\n /** Check if a feature is enabled */\n isEnabled: isFeatureEnabled,\n /** Refresh features from server */\n refresh: refreshFeatures,\n };\n}\n","import { useHabeetat } from './useHabeetat';\n\n/**\n * Hook for subscription and plan info\n */\nexport function useSubscription() {\n const { subscription, refreshSubscription } = useHabeetat();\n \n return {\n /** Current subscription */\n subscription,\n /** Current plan */\n plan: subscription?.plan,\n /** Plan limits */\n limits: subscription?.limits ?? {},\n /** Current usage */\n usage: subscription?.usage ?? {},\n /** Subscription status */\n status: subscription?.status,\n /** Check if subscription is active */\n isActive: subscription?.status === 'active' || subscription?.status === 'trialing',\n /** Check if in trial */\n isTrialing: subscription?.status === 'trialing',\n /** Check limit */\n checkLimit: (key: string, increment = 0): boolean => {\n const limit = subscription?.limits?.[key];\n const current = subscription?.usage?.[key] ?? 0;\n if (limit === undefined) return true;\n return current + increment <= limit;\n },\n /** Refresh subscription */\n refresh: refreshSubscription,\n };\n}\n","import { useLogto } from '@logto/react';\n\nexport interface AuthState {\n isAuthenticated: boolean;\n isLoading: boolean;\n}\n\n/**\n * Returns basic Logto auth state: `{ isAuthenticated, isLoading }`.\n */\nexport function useAuth(): AuthState {\n const { isAuthenticated, isLoading } = useLogto();\n return { isAuthenticated, isLoading };\n}\n","import { useLogto } from '@logto/react';\n\n/**\n * Returns a `signIn(redirectUri)` function that initiates the Logto sign-in flow.\n * The `redirectUri` must match one of the redirect URIs registered in Logto.\n */\nexport function useSignIn(): (redirectUri: string) => Promise<void> {\n const { signIn } = useLogto();\n return signIn;\n}\n","import { useLogto } from '@logto/react';\n\n/**\n * Returns a `signOut(postLogoutRedirectUri?)` function.\n */\nexport function useSignOut(): (postLogoutRedirectUri?: string) => Promise<void> {\n const { signOut } = useLogto();\n return signOut as (postLogoutRedirectUri?: string) => Promise<void>;\n}\n","import type { LogLevel } from '@habeetat/sdk-core';\nimport { SDK_ENDPOINTS } from '@habeetat/sdk-core';\n\nconst LOG_LEVEL_PRIORITY: Record<LogLevel, number> = {\n debug: 0,\n info: 1,\n warn: 2,\n error: 3,\n};\n\nexport interface FrontendLoggerConfig {\n /** Enable/disable logging (default: true) */\n enabled?: boolean;\n /** Minimum log level to emit (default: 'debug') */\n level?: LogLevel;\n /** Number of log records to buffer before flushing (default: 10) */\n batchSize?: number;\n /** Flush interval in milliseconds (default: 5000) */\n flushInterval?: number;\n}\n\ninterface LogEntry {\n level: LogLevel;\n message: string;\n tenantId?: string;\n context?: Record<string, unknown>;\n timestamp: string;\n source: 'frontend';\n serviceName?: string;\n}\n\n/**\n * Frontend logging client that batches log entries and sends them\n * to the platform backend via POST /sdk/v1/logs/batch.\n *\n * This class is framework-agnostic (no React dependency).\n */\nexport class HabeetatLoggerClient {\n private buffer: LogEntry[] = [];\n private flushTimer: ReturnType<typeof setInterval> | null = null;\n private readonly enabled: boolean;\n private readonly minLevel: number;\n private readonly batchSize: number;\n\n constructor(\n private readonly apiUrl: string,\n private readonly getAccessToken: () => Promise<string | null>,\n private readonly defaultAttributes: {\n tenantId?: string;\n appId?: string;\n userId?: string;\n serviceName?: string;\n },\n config?: FrontendLoggerConfig,\n ) {\n this.enabled = config?.enabled ?? true;\n this.minLevel = LOG_LEVEL_PRIORITY[config?.level ?? 'debug'];\n this.batchSize = config?.batchSize ?? 10;\n\n const interval = config?.flushInterval ?? 5000;\n if (this.enabled && interval > 0) {\n this.flushTimer = setInterval(() => this.flush(), interval);\n }\n }\n\n log(level: LogLevel, message: string, context?: Record<string, unknown>): void {\n if (!this.enabled) return;\n if (LOG_LEVEL_PRIORITY[level] < this.minLevel) return;\n\n this.buffer.push({\n level,\n message,\n tenantId: this.defaultAttributes.tenantId,\n context: {\n ...context,\n ...(this.defaultAttributes.appId && { appId: this.defaultAttributes.appId }),\n ...(this.defaultAttributes.userId && { userId: this.defaultAttributes.userId }),\n },\n timestamp: new Date().toISOString(),\n source: 'frontend',\n serviceName: this.defaultAttributes.serviceName,\n });\n\n if (this.buffer.length >= this.batchSize) {\n this.flush();\n }\n }\n\n debug(message: string, context?: Record<string, unknown>): void {\n this.log('debug', message, context);\n }\n\n info(message: string, context?: Record<string, unknown>): void {\n this.log('info', message, context);\n }\n\n warn(message: string, context?: Record<string, unknown>): void {\n this.log('warn', message, context);\n }\n\n error(message: string, context?: Record<string, unknown>): void {\n this.log('error', message, context);\n }\n\n /**\n * Flush buffered log entries to the backend.\n * Best-effort: failures are silently ignored.\n */\n async flush(): Promise<void> {\n if (this.buffer.length === 0) return;\n\n const entries = this.buffer.splice(0);\n\n try {\n const token = await this.getAccessToken();\n if (!token) return;\n\n const url = `${this.apiUrl}${SDK_ENDPOINTS.LOGS_BATCH}`;\n await fetch(url, {\n method: 'POST',\n headers: {\n Authorization: `Bearer ${token}`,\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify({ logs: entries }),\n });\n } catch {\n // Frontend logging is best-effort — silently drop on failure\n }\n }\n\n /**\n * Flush remaining logs and stop the timer.\n * Call this on component unmount.\n */\n destroy(): void {\n if (this.flushTimer) {\n clearInterval(this.flushTimer);\n this.flushTimer = null;\n }\n this.flush();\n }\n}\n","import { useRef, useEffect, useCallback, useMemo, useContext } from 'react';\nimport { HabeetatContext } from '../context/HabeetatContext';\nimport {\n HabeetatLoggerClient,\n type FrontendLoggerConfig,\n} from '../logger/HabeetatLoggerClient';\nimport type { LogLevel } from '@habeetat/sdk-core';\n\nexport interface UseLoggerReturn {\n log: (level: LogLevel, message: string, context?: Record<string, unknown>) => void;\n debug: (message: string, context?: Record<string, unknown>) => void;\n info: (message: string, context?: Record<string, unknown>) => void;\n warn: (message: string, context?: Record<string, unknown>) => void;\n error: (message: string, context?: Record<string, unknown>) => void;\n flush: () => Promise<void>;\n}\n\n/**\n * React hook that provides a logger connected to the Habeetat\n * centralized logging system (SigNoz via the backend).\n *\n * Logs are automatically enriched with user, tenant, and app context\n * from the HabeetatProvider.\n *\n * @example\n * ```tsx\n * function MyComponent() {\n * const logger = useLogger();\n *\n * const handleClick = () => {\n * logger.info('Button clicked', { buttonId: 'submit' });\n * };\n * }\n * ```\n */\nexport function useLogger(config?: FrontendLoggerConfig): UseLoggerReturn {\n const {\n platformUrl,\n getAccessToken,\n context: sdkContext,\n loggerConfig,\n } = useContext(HabeetatContext);\n\n const clientRef = useRef<HabeetatLoggerClient | null>(null);\n\n // Merge provider-level config with hook-level overrides\n const mergedConfig = useMemo<FrontendLoggerConfig>(\n () => ({\n enabled: config?.enabled ?? loggerConfig?.enabled ?? true,\n level: config?.level ?? loggerConfig?.level ?? 'debug',\n batchSize: config?.batchSize,\n flushInterval: config?.flushInterval,\n }),\n [config, loggerConfig],\n );\n\n // Recreate client when dependencies change\n useEffect(() => {\n if (!platformUrl) return;\n\n clientRef.current?.destroy();\n clientRef.current = new HabeetatLoggerClient(\n platformUrl,\n getAccessToken,\n {\n tenantId: sdkContext?.tenant?.id,\n appId: sdkContext?.app?.id,\n userId: sdkContext?.user?.id,\n },\n mergedConfig,\n );\n\n return () => {\n clientRef.current?.destroy();\n clientRef.current = null;\n };\n }, [platformUrl, getAccessToken, sdkContext?.tenant?.id, sdkContext?.app?.id, sdkContext?.user?.id, mergedConfig]);\n\n const log = useCallback(\n (level: LogLevel, message: string, context?: Record<string, unknown>) => {\n clientRef.current?.log(level, message, context);\n },\n [],\n );\n\n const debug = useCallback(\n (message: string, context?: Record<string, unknown>) => {\n clientRef.current?.debug(message, context);\n },\n [],\n );\n\n const info = useCallback(\n (message: string, context?: Record<string, unknown>) => {\n clientRef.current?.info(message, context);\n },\n [],\n );\n\n const warn = useCallback(\n (message: string, context?: Record<string, unknown>) => {\n clientRef.current?.warn(message, context);\n },\n [],\n );\n\n const error = useCallback(\n (message: string, context?: Record<string, unknown>) => {\n clientRef.current?.error(message, context);\n },\n [],\n );\n\n const flush = useCallback(async () => {\n await clientRef.current?.flush();\n }, []);\n\n return useMemo(\n () => ({ log, debug, info, warn, error, flush }),\n [log, debug, info, warn, error, flush],\n );\n}\n","import { useCallback } from 'react';\nimport { useHabeetat } from './useHabeetat';\n\ninterface TrackEventInput {\n eventName: string;\n properties?: Record<string, unknown>;\n sessionId?: string;\n timestamp?: string;\n}\n\nexport interface UseAnalyticsReturn {\n track: (events: TrackEventInput | TrackEventInput[]) => Promise<void>;\n}\n\n/**\n * Hook for tracking analytics events.\n * The `appName` is injected automatically from the HabeetatProvider config.\n *\n * @example\n * ```tsx\n * const { track } = useAnalytics();\n * await track({ eventName: 'button_click', properties: { button: 'save' } });\n * ```\n */\nexport function useAnalytics(): UseAnalyticsReturn {\n const { getAccessToken, platformUrl, appName, tenantSlug } = useHabeetat();\n\n const track = useCallback(async (events: TrackEventInput | TrackEventInput[]) => {\n if (!platformUrl || !tenantSlug) return;\n\n const token = await getAccessToken();\n if (!token) return;\n\n const eventList = Array.isArray(events) ? events : [events];\n\n await fetch(`${platformUrl}/analytics/track`, {\n method: 'POST',\n headers: {\n Authorization: `Bearer ${token}`,\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify({\n tenantId: tenantSlug,\n ...(appName && { appId: appName }),\n events: eventList,\n }),\n });\n }, [getAccessToken, platformUrl, appName, tenantSlug]);\n\n return { track };\n}\n","import { type ReactNode } from 'react';\nimport { usePermissions } from '../hooks/usePermissions';\n\ninterface RequirePermissionProps {\n permission: string;\n children: ReactNode;\n fallback?: ReactNode;\n}\n\n/**\n * Component that renders children only if user has the required permission\n */\nexport function RequirePermission({ permission, children, fallback = null }: RequirePermissionProps) {\n const { hasPermission } = usePermissions();\n \n if (!hasPermission(permission)) {\n return <>{fallback}</>;\n }\n \n return <>{children}</>;\n}\n","import { type ReactNode } from 'react';\nimport { useFeatures } from '../hooks/useFeatures';\n\ninterface RequireFeatureProps {\n flag: string;\n children: ReactNode;\n fallback?: ReactNode;\n}\n\n/**\n * Component that renders children only if the feature flag is enabled\n */\nexport function RequireFeature({ flag, children, fallback = null }: RequireFeatureProps) {\n const { isEnabled } = useFeatures();\n \n if (!isEnabled(flag)) {\n return <>{fallback}</>;\n }\n \n return <>{children}</>;\n}\n"]}
package/dist/index.mjs CHANGED
@@ -94,7 +94,7 @@ function HabeetatData({
94
94
  subscription: null
95
95
  });
96
96
  const apiUrl = useMemo(() => platformUrl.replace(/\/$/, ""), [platformUrl]);
97
- const fetchApi = useCallback(
97
+ const fetchApiImpl = useCallback(
98
98
  async (endpoint) => {
99
99
  let token;
100
100
  try {
@@ -117,30 +117,34 @@ function HabeetatData({
117
117
  },
118
118
  [apiUrl, tokenResource, tenantSlug, appId, getAccessToken]
119
119
  );
120
+ const fetchApiRef = useRef(fetchApiImpl);
121
+ useEffect(() => {
122
+ fetchApiRef.current = fetchApiImpl;
123
+ }, [fetchApiImpl]);
120
124
  const refreshContext = useCallback(async () => {
121
125
  try {
122
- const context = await fetchApi(SDK_ENDPOINTS.CONTEXT);
126
+ const context = await fetchApiRef.current(SDK_ENDPOINTS.CONTEXT);
123
127
  setState((prev) => ({ ...prev, context, error: null }));
124
128
  } catch (error) {
125
129
  setState((prev) => ({ ...prev, error }));
126
130
  }
127
- }, [fetchApi]);
131
+ }, []);
128
132
  const refreshFeatures = useCallback(async () => {
129
133
  try {
130
- const features = await fetchApi(SDK_ENDPOINTS.FEATURES);
134
+ const features = await fetchApiRef.current(SDK_ENDPOINTS.FEATURES);
131
135
  setState((prev) => ({ ...prev, features, error: null }));
132
136
  } catch (error) {
133
137
  setState((prev) => ({ ...prev, error }));
134
138
  }
135
- }, [fetchApi]);
139
+ }, []);
136
140
  const refreshSubscription = useCallback(async () => {
137
141
  try {
138
- const subscription = await fetchApi(SDK_ENDPOINTS.SUBSCRIPTION);
142
+ const subscription = await fetchApiRef.current(SDK_ENDPOINTS.SUBSCRIPTION);
139
143
  setState((prev) => ({ ...prev, subscription, error: null }));
140
144
  } catch (error) {
141
145
  setState((prev) => ({ ...prev, error }));
142
146
  }
143
- }, [fetchApi]);
147
+ }, []);
144
148
  const hasPermission = useCallback(
145
149
  (permission) => state.context?.permissions?.includes(permission) ?? false,
146
150
  [state.context?.permissions]
@@ -169,9 +173,9 @@ function HabeetatData({
169
173
  setState((prev) => ({ ...prev, isLoading: true }));
170
174
  try {
171
175
  const [context, features, subscription] = await Promise.all([
172
- fetchApi(SDK_ENDPOINTS.CONTEXT).catch(() => null),
173
- fetchApi(SDK_ENDPOINTS.FEATURES).catch(() => null),
174
- fetchApi(SDK_ENDPOINTS.SUBSCRIPTION).catch(() => null)
176
+ fetchApiRef.current(SDK_ENDPOINTS.CONTEXT).catch(() => null),
177
+ fetchApiRef.current(SDK_ENDPOINTS.FEATURES).catch(() => null),
178
+ fetchApiRef.current(SDK_ENDPOINTS.SUBSCRIPTION).catch(() => null)
175
179
  ]);
176
180
  setState({ isLoading: false, error: null, context, features, subscription });
177
181
  } catch (error) {
@@ -179,7 +183,7 @@ function HabeetatData({
179
183
  }
180
184
  };
181
185
  fetchAll();
182
- }, [fetchApi]);
186
+ }, []);
183
187
  const contextValue = useMemo(
184
188
  () => ({
185
189
  ...state,
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/context/HabeetatContext.ts","../src/provider/HabeetatProvider.tsx","../src/hooks/useHabeetat.ts","../src/hooks/usePermissions.ts","../src/hooks/useFeatures.ts","../src/hooks/useSubscription.ts","../src/hooks/useAuth.ts","../src/hooks/useSignIn.ts","../src/hooks/useSignOut.ts","../src/logger/HabeetatLoggerClient.ts","../src/hooks/useLogger.ts","../src/hooks/useAnalytics.ts","../src/components/RequirePermission.tsx","../src/components/RequireFeature.tsx"],"names":["useLogto","SDK_ENDPOINTS","useContext","useRef","useMemo","useEffect","useCallback","jsx","Fragment"],"mappings":"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","file":"index.mjs","sourcesContent":["import { createContext } from 'react';\nimport type { SdkContext, SdkFeaturesState, SdkSubscription } from '@habeetat/sdk-core';\n\n/**\n * Habeetat SDK state\n */\nexport interface HabeetatState {\n /** Whether the SDK is loading initial data */\n isLoading: boolean;\n /** Error if any occurred */\n error: Error | null;\n /** SDK context (user, tenant, permissions) */\n context: SdkContext | null;\n /** Feature flags */\n features: SdkFeaturesState | null;\n /** Subscription info */\n subscription: SdkSubscription | null;\n}\n\n/**\n * Habeetat SDK context value\n */\nexport interface HabeetatContextValue extends HabeetatState {\n /** Refresh context from server */\n refreshContext: () => Promise<void>;\n /** Refresh features from server */\n refreshFeatures: () => Promise<void>;\n /** Refresh subscription from server */\n refreshSubscription: () => Promise<void>;\n /** Check if user has permission */\n hasPermission: (permission: string) => boolean;\n /** Check if user has any of the permissions */\n hasAnyPermission: (permissions: string[]) => boolean;\n /** Check if user has all permissions */\n hasAllPermissions: (permissions: string[]) => boolean;\n /** Check if feature is enabled */\n isFeatureEnabled: (key: string) => boolean;\n /** Get access token for API calls */\n getAccessToken: () => Promise<string | null>;\n /** Platform SDK API base URL (for internal use by useLogger) */\n platformUrl: string | null;\n /** App name for analytics tracking */\n appName?: string;\n /** Current tenant slug */\n tenantSlug?: string;\n /** Logger configuration */\n loggerConfig?: { enabled?: boolean; level?: import('@habeetat/sdk-core').LogLevel };\n}\n\n/**\n * Default context value\n */\nconst defaultContextValue: HabeetatContextValue = {\n isLoading: true,\n error: null,\n context: null,\n features: null,\n subscription: null,\n refreshContext: async () => {},\n refreshFeatures: async () => {},\n refreshSubscription: async () => {},\n hasPermission: () => false,\n hasAnyPermission: () => false,\n hasAllPermissions: () => false,\n isFeatureEnabled: () => false,\n getAccessToken: async () => null,\n platformUrl: null,\n};\n\n/**\n * Habeetat React Context\n */\nexport const HabeetatContext = createContext<HabeetatContextValue>(defaultContextValue);\n","import {\n useState,\n useEffect,\n useCallback,\n useMemo,\n useRef,\n type ReactNode,\n} from 'react';\nimport { LogtoProvider, useLogto, useHandleSignInCallback } from '@logto/react';\nimport { SDK_ENDPOINTS } from '@habeetat/sdk-core';\nimport type { SdkContext, SdkFeaturesState, SdkSubscription } from '@habeetat/sdk-core';\nimport { HabeetatContext, type HabeetatContextValue, type HabeetatState } from '../context/HabeetatContext';\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\nexport interface LogtoConfig {\n /** Logto endpoint (e.g. https://iam.yourdomain.com) */\n endpoint: string;\n /** OIDC application ID registered in Logto */\n appId: string;\n /** API resources to request access tokens for */\n resources?: string[];\n /** Additional OIDC scopes */\n scopes?: string[];\n}\n\nexport interface HabeetatProviderProps {\n /** Logto OIDC configuration — replaces the need for a separate LogtoProvider */\n logto: LogtoConfig;\n /** Platform SDK base URL (e.g. https://api.yourdomain.com/sdk/v1) */\n platformUrl: string;\n /** API resource identifier for access-token requests; defaults to platformUrl */\n logtoResource?: string;\n /** App slug registered in Habeetat */\n appId?: string;\n /** App name used as app_id when tracking analytics events */\n appName?: string;\n /** Tenant slug */\n tenantSlug?: string;\n /**\n * Redirect to Logto automatically when the user is not authenticated.\n * A ref guard prevents redirect loops.\n */\n autoSignIn?: boolean;\n /** Path that handles the OIDC callback (default: '/callback') */\n callbackPath?: string;\n /** Rendered while auth state is loading */\n loadingFallback?: ReactNode;\n /** Centralized logging configuration */\n logging?: { enabled?: boolean; level?: import('@habeetat/sdk-core').LogLevel };\n children: ReactNode;\n}\n\n// ---------------------------------------------------------------------------\n// Callback handler — isolated so useHandleSignInCallback can be called\n// without breaking hooks rules in the main inner component\n// ---------------------------------------------------------------------------\n\ninterface CallbackHandlerProps {\n loadingFallback?: ReactNode;\n}\n\nfunction CallbackHandler({ loadingFallback }: CallbackHandlerProps) {\n const { isLoading } = useHandleSignInCallback(() => {\n window.location.href = '/';\n });\n\n if (isLoading) return loadingFallback ? <>{loadingFallback}</> : null;\n return null;\n}\n\n// ---------------------------------------------------------------------------\n// Inner provider — runs inside LogtoProvider so it can call useLogto()\n// ---------------------------------------------------------------------------\n\ninterface InnerProps {\n platformUrl: string;\n logtoResource?: string;\n appId?: string;\n appName?: string;\n tenantSlug?: string;\n autoSignIn?: boolean;\n callbackPath: string;\n loadingFallback?: ReactNode;\n logging?: { enabled?: boolean; level?: import('@habeetat/sdk-core').LogLevel };\n children: ReactNode;\n}\n\nfunction HabeetatInner({\n platformUrl,\n logtoResource,\n appId,\n appName,\n tenantSlug,\n autoSignIn,\n callbackPath,\n loadingFallback,\n logging,\n children,\n}: InnerProps) {\n const { isAuthenticated, isLoading: logtoLoading, getAccessToken, signIn } = useLogto();\n\n const tokenResource = logtoResource ?? platformUrl;\n const signInCalled = useRef(false);\n\n const isCallback =\n typeof window !== 'undefined' &&\n window.location.pathname === callbackPath;\n\n // Auto sign-in redirect\n useEffect(() => {\n if (isCallback || logtoLoading || isAuthenticated || !autoSignIn || signInCalled.current)\n return;\n signInCalled.current = true;\n const redirectUri =\n typeof window !== 'undefined'\n ? `${window.location.origin}${callbackPath}`\n : callbackPath;\n signIn(redirectUri);\n }, [isCallback, logtoLoading, isAuthenticated, autoSignIn, signIn, callbackPath]);\n\n // Delegate to callback handler when on the callback path\n if (isCallback) {\n return <CallbackHandler loadingFallback={loadingFallback} />;\n }\n\n if (logtoLoading) {\n return loadingFallback ? <>{loadingFallback}</> : null;\n }\n\n return (\n <HabeetatData\n platformUrl={platformUrl}\n logtoResource={logtoResource}\n appId={appId}\n appName={appName}\n tenantSlug={tenantSlug}\n getAccessToken={getAccessToken}\n tokenResource={tokenResource}\n loadingFallback={loadingFallback}\n logging={logging}\n >\n {children}\n </HabeetatData>\n );\n}\n\n// ---------------------------------------------------------------------------\n// Data layer — fetches SDK context/features/subscription\n// ---------------------------------------------------------------------------\n\ninterface DataProps {\n platformUrl: string;\n logtoResource?: string;\n appId?: string;\n appName?: string;\n tenantSlug?: string;\n tokenResource: string;\n getAccessToken: (resource?: string) => Promise<string | undefined>;\n loadingFallback?: ReactNode;\n logging?: { enabled?: boolean; level?: import('@habeetat/sdk-core').LogLevel };\n children: ReactNode;\n}\n\nfunction HabeetatData({\n platformUrl,\n appId,\n appName,\n tenantSlug,\n tokenResource,\n getAccessToken,\n logging,\n children,\n}: DataProps) {\n const [state, setState] = useState<HabeetatState>({\n isLoading: true,\n error: null,\n context: null,\n features: null,\n subscription: null,\n });\n\n const apiUrl = useMemo(() => platformUrl.replace(/\\/$/, ''), [platformUrl]);\n\n const fetchApi = useCallback(\n async <T,>(endpoint: string): Promise<T> => {\n let token: string | undefined;\n try {\n token = await getAccessToken(tokenResource);\n } catch (err) {\n throw new Error(`Failed to get access token: ${err}`);\n }\n if (!token) throw new Error('No access token available');\n\n const url = new URL(endpoint, apiUrl);\n if (tenantSlug) url.searchParams.set('tenantSlug', tenantSlug);\n if (appId) url.searchParams.set('appId', appId);\n\n const response = await fetch(url.toString(), {\n headers: {\n Authorization: `Bearer ${token}`,\n 'Content-Type': 'application/json',\n },\n });\n if (!response.ok) throw new Error(`API error: ${response.status}`);\n return response.json() as Promise<T>;\n },\n [apiUrl, tokenResource, tenantSlug, appId, getAccessToken],\n );\n\n const refreshContext = useCallback(async () => {\n try {\n const context = await fetchApi<SdkContext>(SDK_ENDPOINTS.CONTEXT);\n setState((prev) => ({ ...prev, context, error: null }));\n } catch (error) {\n setState((prev) => ({ ...prev, error: error as Error }));\n }\n }, [fetchApi]);\n\n const refreshFeatures = useCallback(async () => {\n try {\n const features = await fetchApi<SdkFeaturesState>(SDK_ENDPOINTS.FEATURES);\n setState((prev) => ({ ...prev, features, error: null }));\n } catch (error) {\n setState((prev) => ({ ...prev, error: error as Error }));\n }\n }, [fetchApi]);\n\n const refreshSubscription = useCallback(async () => {\n try {\n const subscription = await fetchApi<SdkSubscription>(SDK_ENDPOINTS.SUBSCRIPTION);\n setState((prev) => ({ ...prev, subscription, error: null }));\n } catch (error) {\n setState((prev) => ({ ...prev, error: error as Error }));\n }\n }, [fetchApi]);\n\n const hasPermission = useCallback(\n (permission: string) => state.context?.permissions?.includes(permission) ?? false,\n [state.context?.permissions],\n );\n\n const hasAnyPermission = useCallback(\n (permissions: string[]) => permissions.some((p) => state.context?.permissions?.includes(p)),\n [state.context?.permissions],\n );\n\n const hasAllPermissions = useCallback(\n (permissions: string[]) => permissions.every((p) => state.context?.permissions?.includes(p)),\n [state.context?.permissions],\n );\n\n const isFeatureEnabled = useCallback(\n (key: string) => state.features?.features?.[key] ?? false,\n [state.features?.features],\n );\n\n const getToken = useCallback(async (): Promise<string | null> => {\n try {\n return (await getAccessToken(tokenResource)) ?? null;\n } catch {\n return null;\n }\n }, [getAccessToken, tokenResource]);\n\n // Fetch SDK data on mount\n useEffect(() => {\n const fetchAll = async () => {\n setState((prev) => ({ ...prev, isLoading: true }));\n try {\n const [context, features, subscription] = await Promise.all([\n fetchApi<SdkContext>(SDK_ENDPOINTS.CONTEXT).catch(() => null),\n fetchApi<SdkFeaturesState>(SDK_ENDPOINTS.FEATURES).catch(() => null),\n fetchApi<SdkSubscription>(SDK_ENDPOINTS.SUBSCRIPTION).catch(() => null),\n ]);\n setState({ isLoading: false, error: null, context, features, subscription });\n } catch (error) {\n setState((prev) => ({ ...prev, isLoading: false, error: error as Error }));\n }\n };\n\n fetchAll();\n }, [fetchApi]);\n\n const contextValue: HabeetatContextValue = useMemo(\n () => ({\n ...state,\n refreshContext,\n refreshFeatures,\n refreshSubscription,\n hasPermission,\n hasAnyPermission,\n hasAllPermissions,\n isFeatureEnabled,\n getAccessToken: getToken,\n platformUrl: apiUrl,\n appName,\n tenantSlug,\n loggerConfig: logging,\n }),\n [\n state,\n refreshContext,\n refreshFeatures,\n refreshSubscription,\n hasPermission,\n hasAnyPermission,\n hasAllPermissions,\n isFeatureEnabled,\n getToken,\n apiUrl,\n appName,\n tenantSlug,\n logging,\n ],\n );\n\n return (\n <HabeetatContext.Provider value={contextValue}>\n {children}\n </HabeetatContext.Provider>\n );\n}\n\n// ---------------------------------------------------------------------------\n// Public provider — wraps LogtoProvider so callers don't need to\n// ---------------------------------------------------------------------------\n\n/**\n * HabeetatProvider — single provider for Habeetat auth + SDK context.\n *\n * Internally wraps `LogtoProvider` from `@logto/react`, so you no longer\n * need to install or import that package in your application.\n *\n * @example\n * ```tsx\n * import { HabeetatProvider } from '@habeetat/sdk-react';\n *\n * <HabeetatProvider\n * logto={{\n * endpoint: 'https://iam.example.com',\n * appId: 'abc123',\n * resources: ['https://api.example.com/api'],\n * }}\n * platformUrl=\"https://api.example.com/sdk/v1\"\n * tenantSlug=\"acme\"\n * autoSignIn\n * callbackPath=\"/callback\"\n * >\n * <App />\n * </HabeetatProvider>\n * ```\n */\nexport function HabeetatProvider({\n logto,\n platformUrl,\n logtoResource,\n appId,\n appName,\n tenantSlug,\n autoSignIn = false,\n callbackPath = '/callback',\n loadingFallback,\n logging,\n children,\n}: HabeetatProviderProps) {\n const logtoConfig = useMemo(\n () => ({\n endpoint: logto.endpoint,\n appId: logto.appId,\n ...(logto.resources && { resources: logto.resources }),\n ...(logto.scopes && { scopes: logto.scopes }),\n }),\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [logto.endpoint, logto.appId, logto.resources, logto.scopes],\n );\n\n return (\n <LogtoProvider config={logtoConfig}>\n <HabeetatInner\n platformUrl={platformUrl}\n logtoResource={logtoResource}\n appId={appId}\n appName={appName}\n tenantSlug={tenantSlug}\n autoSignIn={autoSignIn}\n callbackPath={callbackPath}\n loadingFallback={loadingFallback}\n logging={logging}\n >\n {children}\n </HabeetatInner>\n </LogtoProvider>\n );\n}\n","import { useContext } from 'react';\nimport { HabeetatContext, type HabeetatContextValue } from '../context/HabeetatContext';\n\n/**\n * Hook to access Habeetat SDK context\n * \n * @example\n * ```tsx\n * function MyComponent() {\n * const { context, isLoading, error } = useHabeetat();\n * \n * if (isLoading) return <Spinner />;\n * if (error) return <Error message={error.message} />;\n * \n * return <div>Hello, {context?.user.name}</div>;\n * }\n * ```\n */\nexport function useHabeetat(): HabeetatContextValue {\n const context = useContext(HabeetatContext);\n \n if (!context) {\n throw new Error('useHabeetat must be used within a HabeetatProvider');\n }\n \n return context;\n}\n","import { useHabeetat } from './useHabeetat';\n\n/**\n * Hook for permission checks\n * \n * @example\n * ```tsx\n * function ContactsPage() {\n * const { hasPermission, hasAnyPermission } = usePermissions();\n * \n * const canRead = hasPermission('contacts:read');\n * const canWrite = hasPermission('contacts:write');\n * const canManage = hasAnyPermission(['contacts:delete', 'contacts:admin']);\n * \n * return (\n * <div>\n * {canRead && <ContactsList />}\n * {canWrite && <AddContactButton />}\n * {canManage && <ManageContactsButton />}\n * </div>\n * );\n * }\n * ```\n */\nexport function usePermissions() {\n const { context, hasPermission, hasAnyPermission, hasAllPermissions } = useHabeetat();\n \n return {\n /** All user permissions */\n permissions: context?.permissions ?? [],\n /** All user roles */\n roles: context?.roles ?? [],\n /** Check if user has a specific permission */\n hasPermission,\n /** Check if user has any of the specified permissions */\n hasAnyPermission,\n /** Check if user has all of the specified permissions */\n hasAllPermissions,\n };\n}\n","import { useHabeetat } from './useHabeetat';\n\n/**\n * Hook for feature flag checks\n * \n * @example\n * ```tsx\n * function DealsPage() {\n * const { isEnabled, features } = useFeatures();\n * \n * if (!isEnabled('crm.deals.enabled')) {\n * return <UpgradePrompt feature=\"Deals\" />;\n * }\n * \n * return <DealsList />;\n * }\n * ```\n */\nexport function useFeatures() {\n const { features, isFeatureEnabled, refreshFeatures } = useHabeetat();\n \n return {\n /** All feature flags */\n features: features?.features ?? {},\n /** Feature source (plan, tenant, etc.) */\n source: features?.source,\n /** Plan code if source is plan */\n planCode: features?.planCode,\n /** Check if a feature is enabled */\n isEnabled: isFeatureEnabled,\n /** Refresh features from server */\n refresh: refreshFeatures,\n };\n}\n","import { useHabeetat } from './useHabeetat';\n\n/**\n * Hook for subscription and plan info\n */\nexport function useSubscription() {\n const { subscription, refreshSubscription } = useHabeetat();\n \n return {\n /** Current subscription */\n subscription,\n /** Current plan */\n plan: subscription?.plan,\n /** Plan limits */\n limits: subscription?.limits ?? {},\n /** Current usage */\n usage: subscription?.usage ?? {},\n /** Subscription status */\n status: subscription?.status,\n /** Check if subscription is active */\n isActive: subscription?.status === 'active' || subscription?.status === 'trialing',\n /** Check if in trial */\n isTrialing: subscription?.status === 'trialing',\n /** Check limit */\n checkLimit: (key: string, increment = 0): boolean => {\n const limit = subscription?.limits?.[key];\n const current = subscription?.usage?.[key] ?? 0;\n if (limit === undefined) return true;\n return current + increment <= limit;\n },\n /** Refresh subscription */\n refresh: refreshSubscription,\n };\n}\n","import { useLogto } from '@logto/react';\n\nexport interface AuthState {\n isAuthenticated: boolean;\n isLoading: boolean;\n}\n\n/**\n * Returns basic Logto auth state: `{ isAuthenticated, isLoading }`.\n */\nexport function useAuth(): AuthState {\n const { isAuthenticated, isLoading } = useLogto();\n return { isAuthenticated, isLoading };\n}\n","import { useLogto } from '@logto/react';\n\n/**\n * Returns a `signIn(redirectUri)` function that initiates the Logto sign-in flow.\n * The `redirectUri` must match one of the redirect URIs registered in Logto.\n */\nexport function useSignIn(): (redirectUri: string) => Promise<void> {\n const { signIn } = useLogto();\n return signIn;\n}\n","import { useLogto } from '@logto/react';\n\n/**\n * Returns a `signOut(postLogoutRedirectUri?)` function.\n */\nexport function useSignOut(): (postLogoutRedirectUri?: string) => Promise<void> {\n const { signOut } = useLogto();\n return signOut as (postLogoutRedirectUri?: string) => Promise<void>;\n}\n","import type { LogLevel } from '@habeetat/sdk-core';\nimport { SDK_ENDPOINTS } from '@habeetat/sdk-core';\n\nconst LOG_LEVEL_PRIORITY: Record<LogLevel, number> = {\n debug: 0,\n info: 1,\n warn: 2,\n error: 3,\n};\n\nexport interface FrontendLoggerConfig {\n /** Enable/disable logging (default: true) */\n enabled?: boolean;\n /** Minimum log level to emit (default: 'debug') */\n level?: LogLevel;\n /** Number of log records to buffer before flushing (default: 10) */\n batchSize?: number;\n /** Flush interval in milliseconds (default: 5000) */\n flushInterval?: number;\n}\n\ninterface LogEntry {\n level: LogLevel;\n message: string;\n tenantId?: string;\n context?: Record<string, unknown>;\n timestamp: string;\n source: 'frontend';\n serviceName?: string;\n}\n\n/**\n * Frontend logging client that batches log entries and sends them\n * to the platform backend via POST /sdk/v1/logs/batch.\n *\n * This class is framework-agnostic (no React dependency).\n */\nexport class HabeetatLoggerClient {\n private buffer: LogEntry[] = [];\n private flushTimer: ReturnType<typeof setInterval> | null = null;\n private readonly enabled: boolean;\n private readonly minLevel: number;\n private readonly batchSize: number;\n\n constructor(\n private readonly apiUrl: string,\n private readonly getAccessToken: () => Promise<string | null>,\n private readonly defaultAttributes: {\n tenantId?: string;\n appId?: string;\n userId?: string;\n serviceName?: string;\n },\n config?: FrontendLoggerConfig,\n ) {\n this.enabled = config?.enabled ?? true;\n this.minLevel = LOG_LEVEL_PRIORITY[config?.level ?? 'debug'];\n this.batchSize = config?.batchSize ?? 10;\n\n const interval = config?.flushInterval ?? 5000;\n if (this.enabled && interval > 0) {\n this.flushTimer = setInterval(() => this.flush(), interval);\n }\n }\n\n log(level: LogLevel, message: string, context?: Record<string, unknown>): void {\n if (!this.enabled) return;\n if (LOG_LEVEL_PRIORITY[level] < this.minLevel) return;\n\n this.buffer.push({\n level,\n message,\n tenantId: this.defaultAttributes.tenantId,\n context: {\n ...context,\n ...(this.defaultAttributes.appId && { appId: this.defaultAttributes.appId }),\n ...(this.defaultAttributes.userId && { userId: this.defaultAttributes.userId }),\n },\n timestamp: new Date().toISOString(),\n source: 'frontend',\n serviceName: this.defaultAttributes.serviceName,\n });\n\n if (this.buffer.length >= this.batchSize) {\n this.flush();\n }\n }\n\n debug(message: string, context?: Record<string, unknown>): void {\n this.log('debug', message, context);\n }\n\n info(message: string, context?: Record<string, unknown>): void {\n this.log('info', message, context);\n }\n\n warn(message: string, context?: Record<string, unknown>): void {\n this.log('warn', message, context);\n }\n\n error(message: string, context?: Record<string, unknown>): void {\n this.log('error', message, context);\n }\n\n /**\n * Flush buffered log entries to the backend.\n * Best-effort: failures are silently ignored.\n */\n async flush(): Promise<void> {\n if (this.buffer.length === 0) return;\n\n const entries = this.buffer.splice(0);\n\n try {\n const token = await this.getAccessToken();\n if (!token) return;\n\n const url = `${this.apiUrl}${SDK_ENDPOINTS.LOGS_BATCH}`;\n await fetch(url, {\n method: 'POST',\n headers: {\n Authorization: `Bearer ${token}`,\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify({ logs: entries }),\n });\n } catch {\n // Frontend logging is best-effort — silently drop on failure\n }\n }\n\n /**\n * Flush remaining logs and stop the timer.\n * Call this on component unmount.\n */\n destroy(): void {\n if (this.flushTimer) {\n clearInterval(this.flushTimer);\n this.flushTimer = null;\n }\n this.flush();\n }\n}\n","import { useRef, useEffect, useCallback, useMemo, useContext } from 'react';\nimport { HabeetatContext } from '../context/HabeetatContext';\nimport {\n HabeetatLoggerClient,\n type FrontendLoggerConfig,\n} from '../logger/HabeetatLoggerClient';\nimport type { LogLevel } from '@habeetat/sdk-core';\n\nexport interface UseLoggerReturn {\n log: (level: LogLevel, message: string, context?: Record<string, unknown>) => void;\n debug: (message: string, context?: Record<string, unknown>) => void;\n info: (message: string, context?: Record<string, unknown>) => void;\n warn: (message: string, context?: Record<string, unknown>) => void;\n error: (message: string, context?: Record<string, unknown>) => void;\n flush: () => Promise<void>;\n}\n\n/**\n * React hook that provides a logger connected to the Habeetat\n * centralized logging system (SigNoz via the backend).\n *\n * Logs are automatically enriched with user, tenant, and app context\n * from the HabeetatProvider.\n *\n * @example\n * ```tsx\n * function MyComponent() {\n * const logger = useLogger();\n *\n * const handleClick = () => {\n * logger.info('Button clicked', { buttonId: 'submit' });\n * };\n * }\n * ```\n */\nexport function useLogger(config?: FrontendLoggerConfig): UseLoggerReturn {\n const {\n platformUrl,\n getAccessToken,\n context: sdkContext,\n loggerConfig,\n } = useContext(HabeetatContext);\n\n const clientRef = useRef<HabeetatLoggerClient | null>(null);\n\n // Merge provider-level config with hook-level overrides\n const mergedConfig = useMemo<FrontendLoggerConfig>(\n () => ({\n enabled: config?.enabled ?? loggerConfig?.enabled ?? true,\n level: config?.level ?? loggerConfig?.level ?? 'debug',\n batchSize: config?.batchSize,\n flushInterval: config?.flushInterval,\n }),\n [config, loggerConfig],\n );\n\n // Recreate client when dependencies change\n useEffect(() => {\n if (!platformUrl) return;\n\n clientRef.current?.destroy();\n clientRef.current = new HabeetatLoggerClient(\n platformUrl,\n getAccessToken,\n {\n tenantId: sdkContext?.tenant?.id,\n appId: sdkContext?.app?.id,\n userId: sdkContext?.user?.id,\n },\n mergedConfig,\n );\n\n return () => {\n clientRef.current?.destroy();\n clientRef.current = null;\n };\n }, [platformUrl, getAccessToken, sdkContext?.tenant?.id, sdkContext?.app?.id, sdkContext?.user?.id, mergedConfig]);\n\n const log = useCallback(\n (level: LogLevel, message: string, context?: Record<string, unknown>) => {\n clientRef.current?.log(level, message, context);\n },\n [],\n );\n\n const debug = useCallback(\n (message: string, context?: Record<string, unknown>) => {\n clientRef.current?.debug(message, context);\n },\n [],\n );\n\n const info = useCallback(\n (message: string, context?: Record<string, unknown>) => {\n clientRef.current?.info(message, context);\n },\n [],\n );\n\n const warn = useCallback(\n (message: string, context?: Record<string, unknown>) => {\n clientRef.current?.warn(message, context);\n },\n [],\n );\n\n const error = useCallback(\n (message: string, context?: Record<string, unknown>) => {\n clientRef.current?.error(message, context);\n },\n [],\n );\n\n const flush = useCallback(async () => {\n await clientRef.current?.flush();\n }, []);\n\n return useMemo(\n () => ({ log, debug, info, warn, error, flush }),\n [log, debug, info, warn, error, flush],\n );\n}\n","import { useCallback } from 'react';\nimport { useHabeetat } from './useHabeetat';\n\ninterface TrackEventInput {\n eventName: string;\n properties?: Record<string, unknown>;\n sessionId?: string;\n timestamp?: string;\n}\n\nexport interface UseAnalyticsReturn {\n track: (events: TrackEventInput | TrackEventInput[]) => Promise<void>;\n}\n\n/**\n * Hook for tracking analytics events.\n * The `appName` is injected automatically from the HabeetatProvider config.\n *\n * @example\n * ```tsx\n * const { track } = useAnalytics();\n * await track({ eventName: 'button_click', properties: { button: 'save' } });\n * ```\n */\nexport function useAnalytics(): UseAnalyticsReturn {\n const { getAccessToken, platformUrl, appName, tenantSlug } = useHabeetat();\n\n const track = useCallback(async (events: TrackEventInput | TrackEventInput[]) => {\n if (!platformUrl || !tenantSlug) return;\n\n const token = await getAccessToken();\n if (!token) return;\n\n const eventList = Array.isArray(events) ? events : [events];\n\n await fetch(`${platformUrl}/analytics/track`, {\n method: 'POST',\n headers: {\n Authorization: `Bearer ${token}`,\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify({\n tenantId: tenantSlug,\n ...(appName && { appId: appName }),\n events: eventList,\n }),\n });\n }, [getAccessToken, platformUrl, appName, tenantSlug]);\n\n return { track };\n}\n","import { type ReactNode } from 'react';\nimport { usePermissions } from '../hooks/usePermissions';\n\ninterface RequirePermissionProps {\n permission: string;\n children: ReactNode;\n fallback?: ReactNode;\n}\n\n/**\n * Component that renders children only if user has the required permission\n */\nexport function RequirePermission({ permission, children, fallback = null }: RequirePermissionProps) {\n const { hasPermission } = usePermissions();\n \n if (!hasPermission(permission)) {\n return <>{fallback}</>;\n }\n \n return <>{children}</>;\n}\n","import { type ReactNode } from 'react';\nimport { useFeatures } from '../hooks/useFeatures';\n\ninterface RequireFeatureProps {\n flag: string;\n children: ReactNode;\n fallback?: ReactNode;\n}\n\n/**\n * Component that renders children only if the feature flag is enabled\n */\nexport function RequireFeature({ flag, children, fallback = null }: RequireFeatureProps) {\n const { isEnabled } = useFeatures();\n \n if (!isEnabled(flag)) {\n return <>{fallback}</>;\n }\n \n return <>{children}</>;\n}\n"]}
1
+ {"version":3,"sources":["../src/context/HabeetatContext.ts","../src/provider/HabeetatProvider.tsx","../src/hooks/useHabeetat.ts","../src/hooks/usePermissions.ts","../src/hooks/useFeatures.ts","../src/hooks/useSubscription.ts","../src/hooks/useAuth.ts","../src/hooks/useSignIn.ts","../src/hooks/useSignOut.ts","../src/logger/HabeetatLoggerClient.ts","../src/hooks/useLogger.ts","../src/hooks/useAnalytics.ts","../src/components/RequirePermission.tsx","../src/components/RequireFeature.tsx"],"names":["useLogto","SDK_ENDPOINTS","useContext","useRef","useMemo","useEffect","useCallback","jsx","Fragment"],"mappings":"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","file":"index.mjs","sourcesContent":["import { createContext } from 'react';\nimport type { SdkContext, SdkFeaturesState, SdkSubscription } from '@habeetat/sdk-core';\n\n/**\n * Habeetat SDK state\n */\nexport interface HabeetatState {\n /** Whether the SDK is loading initial data */\n isLoading: boolean;\n /** Error if any occurred */\n error: Error | null;\n /** SDK context (user, tenant, permissions) */\n context: SdkContext | null;\n /** Feature flags */\n features: SdkFeaturesState | null;\n /** Subscription info */\n subscription: SdkSubscription | null;\n}\n\n/**\n * Habeetat SDK context value\n */\nexport interface HabeetatContextValue extends HabeetatState {\n /** Refresh context from server */\n refreshContext: () => Promise<void>;\n /** Refresh features from server */\n refreshFeatures: () => Promise<void>;\n /** Refresh subscription from server */\n refreshSubscription: () => Promise<void>;\n /** Check if user has permission */\n hasPermission: (permission: string) => boolean;\n /** Check if user has any of the permissions */\n hasAnyPermission: (permissions: string[]) => boolean;\n /** Check if user has all permissions */\n hasAllPermissions: (permissions: string[]) => boolean;\n /** Check if feature is enabled */\n isFeatureEnabled: (key: string) => boolean;\n /** Get access token for API calls */\n getAccessToken: () => Promise<string | null>;\n /** Platform SDK API base URL (for internal use by useLogger) */\n platformUrl: string | null;\n /** App name for analytics tracking */\n appName?: string;\n /** Current tenant slug */\n tenantSlug?: string;\n /** Logger configuration */\n loggerConfig?: { enabled?: boolean; level?: import('@habeetat/sdk-core').LogLevel };\n}\n\n/**\n * Default context value\n */\nconst defaultContextValue: HabeetatContextValue = {\n isLoading: true,\n error: null,\n context: null,\n features: null,\n subscription: null,\n refreshContext: async () => {},\n refreshFeatures: async () => {},\n refreshSubscription: async () => {},\n hasPermission: () => false,\n hasAnyPermission: () => false,\n hasAllPermissions: () => false,\n isFeatureEnabled: () => false,\n getAccessToken: async () => null,\n platformUrl: null,\n};\n\n/**\n * Habeetat React Context\n */\nexport const HabeetatContext = createContext<HabeetatContextValue>(defaultContextValue);\n","import {\n useState,\n useEffect,\n useCallback,\n useMemo,\n useRef,\n type ReactNode,\n} from 'react';\nimport { LogtoProvider, useLogto, useHandleSignInCallback } from '@logto/react';\nimport { SDK_ENDPOINTS } from '@habeetat/sdk-core';\nimport type { SdkContext, SdkFeaturesState, SdkSubscription } from '@habeetat/sdk-core';\nimport { HabeetatContext, type HabeetatContextValue, type HabeetatState } from '../context/HabeetatContext';\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\nexport interface LogtoConfig {\n /** Logto endpoint (e.g. https://iam.yourdomain.com) */\n endpoint: string;\n /** OIDC application ID registered in Logto */\n appId: string;\n /** API resources to request access tokens for */\n resources?: string[];\n /** Additional OIDC scopes */\n scopes?: string[];\n}\n\nexport interface HabeetatProviderProps {\n /** Logto OIDC configuration — replaces the need for a separate LogtoProvider */\n logto: LogtoConfig;\n /** Platform SDK base URL (e.g. https://api.yourdomain.com/sdk/v1) */\n platformUrl: string;\n /** API resource identifier for access-token requests; defaults to platformUrl */\n logtoResource?: string;\n /** App slug registered in Habeetat */\n appId?: string;\n /** App name used as app_id when tracking analytics events */\n appName?: string;\n /** Tenant slug */\n tenantSlug?: string;\n /**\n * Redirect to Logto automatically when the user is not authenticated.\n * A ref guard prevents redirect loops.\n */\n autoSignIn?: boolean;\n /** Path that handles the OIDC callback (default: '/callback') */\n callbackPath?: string;\n /** Rendered while auth state is loading */\n loadingFallback?: ReactNode;\n /** Centralized logging configuration */\n logging?: { enabled?: boolean; level?: import('@habeetat/sdk-core').LogLevel };\n children: ReactNode;\n}\n\n// ---------------------------------------------------------------------------\n// Callback handler — isolated so useHandleSignInCallback can be called\n// without breaking hooks rules in the main inner component\n// ---------------------------------------------------------------------------\n\ninterface CallbackHandlerProps {\n loadingFallback?: ReactNode;\n}\n\nfunction CallbackHandler({ loadingFallback }: CallbackHandlerProps) {\n const { isLoading } = useHandleSignInCallback(() => {\n window.location.href = '/';\n });\n\n if (isLoading) return loadingFallback ? <>{loadingFallback}</> : null;\n return null;\n}\n\n// ---------------------------------------------------------------------------\n// Inner provider — runs inside LogtoProvider so it can call useLogto()\n// ---------------------------------------------------------------------------\n\ninterface InnerProps {\n platformUrl: string;\n logtoResource?: string;\n appId?: string;\n appName?: string;\n tenantSlug?: string;\n autoSignIn?: boolean;\n callbackPath: string;\n loadingFallback?: ReactNode;\n logging?: { enabled?: boolean; level?: import('@habeetat/sdk-core').LogLevel };\n children: ReactNode;\n}\n\nfunction HabeetatInner({\n platformUrl,\n logtoResource,\n appId,\n appName,\n tenantSlug,\n autoSignIn,\n callbackPath,\n loadingFallback,\n logging,\n children,\n}: InnerProps) {\n const { isAuthenticated, isLoading: logtoLoading, getAccessToken, signIn } = useLogto();\n\n const tokenResource = logtoResource ?? platformUrl;\n const signInCalled = useRef(false);\n\n const isCallback =\n typeof window !== 'undefined' &&\n window.location.pathname === callbackPath;\n\n // Auto sign-in redirect\n useEffect(() => {\n if (isCallback || logtoLoading || isAuthenticated || !autoSignIn || signInCalled.current)\n return;\n signInCalled.current = true;\n const redirectUri =\n typeof window !== 'undefined'\n ? `${window.location.origin}${callbackPath}`\n : callbackPath;\n signIn(redirectUri);\n }, [isCallback, logtoLoading, isAuthenticated, autoSignIn, signIn, callbackPath]);\n\n // Delegate to callback handler when on the callback path\n if (isCallback) {\n return <CallbackHandler loadingFallback={loadingFallback} />;\n }\n\n if (logtoLoading) {\n return loadingFallback ? <>{loadingFallback}</> : null;\n }\n\n return (\n <HabeetatData\n platformUrl={platformUrl}\n logtoResource={logtoResource}\n appId={appId}\n appName={appName}\n tenantSlug={tenantSlug}\n getAccessToken={getAccessToken}\n tokenResource={tokenResource}\n loadingFallback={loadingFallback}\n logging={logging}\n >\n {children}\n </HabeetatData>\n );\n}\n\n// ---------------------------------------------------------------------------\n// Data layer — fetches SDK context/features/subscription\n// ---------------------------------------------------------------------------\n\ninterface DataProps {\n platformUrl: string;\n logtoResource?: string;\n appId?: string;\n appName?: string;\n tenantSlug?: string;\n tokenResource: string;\n getAccessToken: (resource?: string) => Promise<string | undefined>;\n loadingFallback?: ReactNode;\n logging?: { enabled?: boolean; level?: import('@habeetat/sdk-core').LogLevel };\n children: ReactNode;\n}\n\nfunction HabeetatData({\n platformUrl,\n appId,\n appName,\n tenantSlug,\n tokenResource,\n getAccessToken,\n logging,\n children,\n}: DataProps) {\n const [state, setState] = useState<HabeetatState>({\n isLoading: true,\n error: null,\n context: null,\n features: null,\n subscription: null,\n });\n\n const apiUrl = useMemo(() => platformUrl.replace(/\\/$/, ''), [platformUrl]);\n\n const fetchApiImpl = useCallback(\n async <T,>(endpoint: string): Promise<T> => {\n let token: string | undefined;\n try {\n token = await getAccessToken(tokenResource);\n } catch (err) {\n throw new Error(`Failed to get access token: ${err}`);\n }\n if (!token) throw new Error('No access token available');\n\n const url = new URL(endpoint, apiUrl);\n if (tenantSlug) url.searchParams.set('tenantSlug', tenantSlug);\n if (appId) url.searchParams.set('appId', appId);\n\n const response = await fetch(url.toString(), {\n headers: {\n Authorization: `Bearer ${token}`,\n 'Content-Type': 'application/json',\n },\n });\n if (!response.ok) throw new Error(`API error: ${response.status}`);\n return response.json() as Promise<T>;\n },\n [apiUrl, tokenResource, tenantSlug, appId, getAccessToken],\n );\n\n const fetchApiRef = useRef(fetchApiImpl);\n useEffect(() => { fetchApiRef.current = fetchApiImpl; }, [fetchApiImpl]);\n\n const refreshContext = useCallback(async () => {\n try {\n const context = await fetchApiRef.current<SdkContext>(SDK_ENDPOINTS.CONTEXT);\n setState((prev) => ({ ...prev, context, error: null }));\n } catch (error) {\n setState((prev) => ({ ...prev, error: error as Error }));\n }\n }, []);\n\n const refreshFeatures = useCallback(async () => {\n try {\n const features = await fetchApiRef.current<SdkFeaturesState>(SDK_ENDPOINTS.FEATURES);\n setState((prev) => ({ ...prev, features, error: null }));\n } catch (error) {\n setState((prev) => ({ ...prev, error: error as Error }));\n }\n }, []);\n\n const refreshSubscription = useCallback(async () => {\n try {\n const subscription = await fetchApiRef.current<SdkSubscription>(SDK_ENDPOINTS.SUBSCRIPTION);\n setState((prev) => ({ ...prev, subscription, error: null }));\n } catch (error) {\n setState((prev) => ({ ...prev, error: error as Error }));\n }\n }, []);\n\n const hasPermission = useCallback(\n (permission: string) => state.context?.permissions?.includes(permission) ?? false,\n [state.context?.permissions],\n );\n\n const hasAnyPermission = useCallback(\n (permissions: string[]) => permissions.some((p) => state.context?.permissions?.includes(p)),\n [state.context?.permissions],\n );\n\n const hasAllPermissions = useCallback(\n (permissions: string[]) => permissions.every((p) => state.context?.permissions?.includes(p)),\n [state.context?.permissions],\n );\n\n const isFeatureEnabled = useCallback(\n (key: string) => state.features?.features?.[key] ?? false,\n [state.features?.features],\n );\n\n const getToken = useCallback(async (): Promise<string | null> => {\n try {\n return (await getAccessToken(tokenResource)) ?? null;\n } catch {\n return null;\n }\n }, [getAccessToken, tokenResource]);\n\n // Fetch SDK data on mount — runs once; fetchApiRef always points to the latest fetchApiImpl\n useEffect(() => {\n const fetchAll = async () => {\n setState((prev) => ({ ...prev, isLoading: true }));\n try {\n const [context, features, subscription] = await Promise.all([\n fetchApiRef.current<SdkContext>(SDK_ENDPOINTS.CONTEXT).catch(() => null),\n fetchApiRef.current<SdkFeaturesState>(SDK_ENDPOINTS.FEATURES).catch(() => null),\n fetchApiRef.current<SdkSubscription>(SDK_ENDPOINTS.SUBSCRIPTION).catch(() => null),\n ]);\n setState({ isLoading: false, error: null, context, features, subscription });\n } catch (error) {\n setState((prev) => ({ ...prev, isLoading: false, error: error as Error }));\n }\n };\n\n fetchAll();\n }, []);\n\n const contextValue: HabeetatContextValue = useMemo(\n () => ({\n ...state,\n refreshContext,\n refreshFeatures,\n refreshSubscription,\n hasPermission,\n hasAnyPermission,\n hasAllPermissions,\n isFeatureEnabled,\n getAccessToken: getToken,\n platformUrl: apiUrl,\n appName,\n tenantSlug,\n loggerConfig: logging,\n }),\n [\n state,\n refreshContext,\n refreshFeatures,\n refreshSubscription,\n hasPermission,\n hasAnyPermission,\n hasAllPermissions,\n isFeatureEnabled,\n getToken,\n apiUrl,\n appName,\n tenantSlug,\n logging,\n ],\n );\n\n return (\n <HabeetatContext.Provider value={contextValue}>\n {children}\n </HabeetatContext.Provider>\n );\n}\n\n// ---------------------------------------------------------------------------\n// Public provider — wraps LogtoProvider so callers don't need to\n// ---------------------------------------------------------------------------\n\n/**\n * HabeetatProvider — single provider for Habeetat auth + SDK context.\n *\n * Internally wraps `LogtoProvider` from `@logto/react`, so you no longer\n * need to install or import that package in your application.\n *\n * @example\n * ```tsx\n * import { HabeetatProvider } from '@habeetat/sdk-react';\n *\n * <HabeetatProvider\n * logto={{\n * endpoint: 'https://iam.example.com',\n * appId: 'abc123',\n * resources: ['https://api.example.com/api'],\n * }}\n * platformUrl=\"https://api.example.com/sdk/v1\"\n * tenantSlug=\"acme\"\n * autoSignIn\n * callbackPath=\"/callback\"\n * >\n * <App />\n * </HabeetatProvider>\n * ```\n */\nexport function HabeetatProvider({\n logto,\n platformUrl,\n logtoResource,\n appId,\n appName,\n tenantSlug,\n autoSignIn = false,\n callbackPath = '/callback',\n loadingFallback,\n logging,\n children,\n}: HabeetatProviderProps) {\n const logtoConfig = useMemo(\n () => ({\n endpoint: logto.endpoint,\n appId: logto.appId,\n ...(logto.resources && { resources: logto.resources }),\n ...(logto.scopes && { scopes: logto.scopes }),\n }),\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [logto.endpoint, logto.appId, logto.resources, logto.scopes],\n );\n\n return (\n <LogtoProvider config={logtoConfig}>\n <HabeetatInner\n platformUrl={platformUrl}\n logtoResource={logtoResource}\n appId={appId}\n appName={appName}\n tenantSlug={tenantSlug}\n autoSignIn={autoSignIn}\n callbackPath={callbackPath}\n loadingFallback={loadingFallback}\n logging={logging}\n >\n {children}\n </HabeetatInner>\n </LogtoProvider>\n );\n}\n","import { useContext } from 'react';\nimport { HabeetatContext, type HabeetatContextValue } from '../context/HabeetatContext';\n\n/**\n * Hook to access Habeetat SDK context\n * \n * @example\n * ```tsx\n * function MyComponent() {\n * const { context, isLoading, error } = useHabeetat();\n * \n * if (isLoading) return <Spinner />;\n * if (error) return <Error message={error.message} />;\n * \n * return <div>Hello, {context?.user.name}</div>;\n * }\n * ```\n */\nexport function useHabeetat(): HabeetatContextValue {\n const context = useContext(HabeetatContext);\n \n if (!context) {\n throw new Error('useHabeetat must be used within a HabeetatProvider');\n }\n \n return context;\n}\n","import { useHabeetat } from './useHabeetat';\n\n/**\n * Hook for permission checks\n * \n * @example\n * ```tsx\n * function ContactsPage() {\n * const { hasPermission, hasAnyPermission } = usePermissions();\n * \n * const canRead = hasPermission('contacts:read');\n * const canWrite = hasPermission('contacts:write');\n * const canManage = hasAnyPermission(['contacts:delete', 'contacts:admin']);\n * \n * return (\n * <div>\n * {canRead && <ContactsList />}\n * {canWrite && <AddContactButton />}\n * {canManage && <ManageContactsButton />}\n * </div>\n * );\n * }\n * ```\n */\nexport function usePermissions() {\n const { context, hasPermission, hasAnyPermission, hasAllPermissions } = useHabeetat();\n \n return {\n /** All user permissions */\n permissions: context?.permissions ?? [],\n /** All user roles */\n roles: context?.roles ?? [],\n /** Check if user has a specific permission */\n hasPermission,\n /** Check if user has any of the specified permissions */\n hasAnyPermission,\n /** Check if user has all of the specified permissions */\n hasAllPermissions,\n };\n}\n","import { useHabeetat } from './useHabeetat';\n\n/**\n * Hook for feature flag checks\n * \n * @example\n * ```tsx\n * function DealsPage() {\n * const { isEnabled, features } = useFeatures();\n * \n * if (!isEnabled('crm.deals.enabled')) {\n * return <UpgradePrompt feature=\"Deals\" />;\n * }\n * \n * return <DealsList />;\n * }\n * ```\n */\nexport function useFeatures() {\n const { features, isFeatureEnabled, refreshFeatures } = useHabeetat();\n \n return {\n /** All feature flags */\n features: features?.features ?? {},\n /** Feature source (plan, tenant, etc.) */\n source: features?.source,\n /** Plan code if source is plan */\n planCode: features?.planCode,\n /** Check if a feature is enabled */\n isEnabled: isFeatureEnabled,\n /** Refresh features from server */\n refresh: refreshFeatures,\n };\n}\n","import { useHabeetat } from './useHabeetat';\n\n/**\n * Hook for subscription and plan info\n */\nexport function useSubscription() {\n const { subscription, refreshSubscription } = useHabeetat();\n \n return {\n /** Current subscription */\n subscription,\n /** Current plan */\n plan: subscription?.plan,\n /** Plan limits */\n limits: subscription?.limits ?? {},\n /** Current usage */\n usage: subscription?.usage ?? {},\n /** Subscription status */\n status: subscription?.status,\n /** Check if subscription is active */\n isActive: subscription?.status === 'active' || subscription?.status === 'trialing',\n /** Check if in trial */\n isTrialing: subscription?.status === 'trialing',\n /** Check limit */\n checkLimit: (key: string, increment = 0): boolean => {\n const limit = subscription?.limits?.[key];\n const current = subscription?.usage?.[key] ?? 0;\n if (limit === undefined) return true;\n return current + increment <= limit;\n },\n /** Refresh subscription */\n refresh: refreshSubscription,\n };\n}\n","import { useLogto } from '@logto/react';\n\nexport interface AuthState {\n isAuthenticated: boolean;\n isLoading: boolean;\n}\n\n/**\n * Returns basic Logto auth state: `{ isAuthenticated, isLoading }`.\n */\nexport function useAuth(): AuthState {\n const { isAuthenticated, isLoading } = useLogto();\n return { isAuthenticated, isLoading };\n}\n","import { useLogto } from '@logto/react';\n\n/**\n * Returns a `signIn(redirectUri)` function that initiates the Logto sign-in flow.\n * The `redirectUri` must match one of the redirect URIs registered in Logto.\n */\nexport function useSignIn(): (redirectUri: string) => Promise<void> {\n const { signIn } = useLogto();\n return signIn;\n}\n","import { useLogto } from '@logto/react';\n\n/**\n * Returns a `signOut(postLogoutRedirectUri?)` function.\n */\nexport function useSignOut(): (postLogoutRedirectUri?: string) => Promise<void> {\n const { signOut } = useLogto();\n return signOut as (postLogoutRedirectUri?: string) => Promise<void>;\n}\n","import type { LogLevel } from '@habeetat/sdk-core';\nimport { SDK_ENDPOINTS } from '@habeetat/sdk-core';\n\nconst LOG_LEVEL_PRIORITY: Record<LogLevel, number> = {\n debug: 0,\n info: 1,\n warn: 2,\n error: 3,\n};\n\nexport interface FrontendLoggerConfig {\n /** Enable/disable logging (default: true) */\n enabled?: boolean;\n /** Minimum log level to emit (default: 'debug') */\n level?: LogLevel;\n /** Number of log records to buffer before flushing (default: 10) */\n batchSize?: number;\n /** Flush interval in milliseconds (default: 5000) */\n flushInterval?: number;\n}\n\ninterface LogEntry {\n level: LogLevel;\n message: string;\n tenantId?: string;\n context?: Record<string, unknown>;\n timestamp: string;\n source: 'frontend';\n serviceName?: string;\n}\n\n/**\n * Frontend logging client that batches log entries and sends them\n * to the platform backend via POST /sdk/v1/logs/batch.\n *\n * This class is framework-agnostic (no React dependency).\n */\nexport class HabeetatLoggerClient {\n private buffer: LogEntry[] = [];\n private flushTimer: ReturnType<typeof setInterval> | null = null;\n private readonly enabled: boolean;\n private readonly minLevel: number;\n private readonly batchSize: number;\n\n constructor(\n private readonly apiUrl: string,\n private readonly getAccessToken: () => Promise<string | null>,\n private readonly defaultAttributes: {\n tenantId?: string;\n appId?: string;\n userId?: string;\n serviceName?: string;\n },\n config?: FrontendLoggerConfig,\n ) {\n this.enabled = config?.enabled ?? true;\n this.minLevel = LOG_LEVEL_PRIORITY[config?.level ?? 'debug'];\n this.batchSize = config?.batchSize ?? 10;\n\n const interval = config?.flushInterval ?? 5000;\n if (this.enabled && interval > 0) {\n this.flushTimer = setInterval(() => this.flush(), interval);\n }\n }\n\n log(level: LogLevel, message: string, context?: Record<string, unknown>): void {\n if (!this.enabled) return;\n if (LOG_LEVEL_PRIORITY[level] < this.minLevel) return;\n\n this.buffer.push({\n level,\n message,\n tenantId: this.defaultAttributes.tenantId,\n context: {\n ...context,\n ...(this.defaultAttributes.appId && { appId: this.defaultAttributes.appId }),\n ...(this.defaultAttributes.userId && { userId: this.defaultAttributes.userId }),\n },\n timestamp: new Date().toISOString(),\n source: 'frontend',\n serviceName: this.defaultAttributes.serviceName,\n });\n\n if (this.buffer.length >= this.batchSize) {\n this.flush();\n }\n }\n\n debug(message: string, context?: Record<string, unknown>): void {\n this.log('debug', message, context);\n }\n\n info(message: string, context?: Record<string, unknown>): void {\n this.log('info', message, context);\n }\n\n warn(message: string, context?: Record<string, unknown>): void {\n this.log('warn', message, context);\n }\n\n error(message: string, context?: Record<string, unknown>): void {\n this.log('error', message, context);\n }\n\n /**\n * Flush buffered log entries to the backend.\n * Best-effort: failures are silently ignored.\n */\n async flush(): Promise<void> {\n if (this.buffer.length === 0) return;\n\n const entries = this.buffer.splice(0);\n\n try {\n const token = await this.getAccessToken();\n if (!token) return;\n\n const url = `${this.apiUrl}${SDK_ENDPOINTS.LOGS_BATCH}`;\n await fetch(url, {\n method: 'POST',\n headers: {\n Authorization: `Bearer ${token}`,\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify({ logs: entries }),\n });\n } catch {\n // Frontend logging is best-effort — silently drop on failure\n }\n }\n\n /**\n * Flush remaining logs and stop the timer.\n * Call this on component unmount.\n */\n destroy(): void {\n if (this.flushTimer) {\n clearInterval(this.flushTimer);\n this.flushTimer = null;\n }\n this.flush();\n }\n}\n","import { useRef, useEffect, useCallback, useMemo, useContext } from 'react';\nimport { HabeetatContext } from '../context/HabeetatContext';\nimport {\n HabeetatLoggerClient,\n type FrontendLoggerConfig,\n} from '../logger/HabeetatLoggerClient';\nimport type { LogLevel } from '@habeetat/sdk-core';\n\nexport interface UseLoggerReturn {\n log: (level: LogLevel, message: string, context?: Record<string, unknown>) => void;\n debug: (message: string, context?: Record<string, unknown>) => void;\n info: (message: string, context?: Record<string, unknown>) => void;\n warn: (message: string, context?: Record<string, unknown>) => void;\n error: (message: string, context?: Record<string, unknown>) => void;\n flush: () => Promise<void>;\n}\n\n/**\n * React hook that provides a logger connected to the Habeetat\n * centralized logging system (SigNoz via the backend).\n *\n * Logs are automatically enriched with user, tenant, and app context\n * from the HabeetatProvider.\n *\n * @example\n * ```tsx\n * function MyComponent() {\n * const logger = useLogger();\n *\n * const handleClick = () => {\n * logger.info('Button clicked', { buttonId: 'submit' });\n * };\n * }\n * ```\n */\nexport function useLogger(config?: FrontendLoggerConfig): UseLoggerReturn {\n const {\n platformUrl,\n getAccessToken,\n context: sdkContext,\n loggerConfig,\n } = useContext(HabeetatContext);\n\n const clientRef = useRef<HabeetatLoggerClient | null>(null);\n\n // Merge provider-level config with hook-level overrides\n const mergedConfig = useMemo<FrontendLoggerConfig>(\n () => ({\n enabled: config?.enabled ?? loggerConfig?.enabled ?? true,\n level: config?.level ?? loggerConfig?.level ?? 'debug',\n batchSize: config?.batchSize,\n flushInterval: config?.flushInterval,\n }),\n [config, loggerConfig],\n );\n\n // Recreate client when dependencies change\n useEffect(() => {\n if (!platformUrl) return;\n\n clientRef.current?.destroy();\n clientRef.current = new HabeetatLoggerClient(\n platformUrl,\n getAccessToken,\n {\n tenantId: sdkContext?.tenant?.id,\n appId: sdkContext?.app?.id,\n userId: sdkContext?.user?.id,\n },\n mergedConfig,\n );\n\n return () => {\n clientRef.current?.destroy();\n clientRef.current = null;\n };\n }, [platformUrl, getAccessToken, sdkContext?.tenant?.id, sdkContext?.app?.id, sdkContext?.user?.id, mergedConfig]);\n\n const log = useCallback(\n (level: LogLevel, message: string, context?: Record<string, unknown>) => {\n clientRef.current?.log(level, message, context);\n },\n [],\n );\n\n const debug = useCallback(\n (message: string, context?: Record<string, unknown>) => {\n clientRef.current?.debug(message, context);\n },\n [],\n );\n\n const info = useCallback(\n (message: string, context?: Record<string, unknown>) => {\n clientRef.current?.info(message, context);\n },\n [],\n );\n\n const warn = useCallback(\n (message: string, context?: Record<string, unknown>) => {\n clientRef.current?.warn(message, context);\n },\n [],\n );\n\n const error = useCallback(\n (message: string, context?: Record<string, unknown>) => {\n clientRef.current?.error(message, context);\n },\n [],\n );\n\n const flush = useCallback(async () => {\n await clientRef.current?.flush();\n }, []);\n\n return useMemo(\n () => ({ log, debug, info, warn, error, flush }),\n [log, debug, info, warn, error, flush],\n );\n}\n","import { useCallback } from 'react';\nimport { useHabeetat } from './useHabeetat';\n\ninterface TrackEventInput {\n eventName: string;\n properties?: Record<string, unknown>;\n sessionId?: string;\n timestamp?: string;\n}\n\nexport interface UseAnalyticsReturn {\n track: (events: TrackEventInput | TrackEventInput[]) => Promise<void>;\n}\n\n/**\n * Hook for tracking analytics events.\n * The `appName` is injected automatically from the HabeetatProvider config.\n *\n * @example\n * ```tsx\n * const { track } = useAnalytics();\n * await track({ eventName: 'button_click', properties: { button: 'save' } });\n * ```\n */\nexport function useAnalytics(): UseAnalyticsReturn {\n const { getAccessToken, platformUrl, appName, tenantSlug } = useHabeetat();\n\n const track = useCallback(async (events: TrackEventInput | TrackEventInput[]) => {\n if (!platformUrl || !tenantSlug) return;\n\n const token = await getAccessToken();\n if (!token) return;\n\n const eventList = Array.isArray(events) ? events : [events];\n\n await fetch(`${platformUrl}/analytics/track`, {\n method: 'POST',\n headers: {\n Authorization: `Bearer ${token}`,\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify({\n tenantId: tenantSlug,\n ...(appName && { appId: appName }),\n events: eventList,\n }),\n });\n }, [getAccessToken, platformUrl, appName, tenantSlug]);\n\n return { track };\n}\n","import { type ReactNode } from 'react';\nimport { usePermissions } from '../hooks/usePermissions';\n\ninterface RequirePermissionProps {\n permission: string;\n children: ReactNode;\n fallback?: ReactNode;\n}\n\n/**\n * Component that renders children only if user has the required permission\n */\nexport function RequirePermission({ permission, children, fallback = null }: RequirePermissionProps) {\n const { hasPermission } = usePermissions();\n \n if (!hasPermission(permission)) {\n return <>{fallback}</>;\n }\n \n return <>{children}</>;\n}\n","import { type ReactNode } from 'react';\nimport { useFeatures } from '../hooks/useFeatures';\n\ninterface RequireFeatureProps {\n flag: string;\n children: ReactNode;\n fallback?: ReactNode;\n}\n\n/**\n * Component that renders children only if the feature flag is enabled\n */\nexport function RequireFeature({ flag, children, fallback = null }: RequireFeatureProps) {\n const { isEnabled } = useFeatures();\n \n if (!isEnabled(flag)) {\n return <>{fallback}</>;\n }\n \n return <>{children}</>;\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@habeetat/sdk-react",
3
- "version": "0.1.0-dev.20260330160419.ec63152",
3
+ "version": "0.1.0-dev.20260403141840.b34ffd7",
4
4
  "description": "Habeetat Platform SDK for React applications",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.mjs",