@habeetat/sdk-react 0.1.0-dev.20260325103304.48d3552 → 0.1.0-dev.20260330160419.ec63152

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.d.mts CHANGED
@@ -24,6 +24,8 @@ interface HabeetatProviderProps {
24
24
  logtoResource?: string;
25
25
  /** App slug registered in Habeetat */
26
26
  appId?: string;
27
+ /** App name used as app_id when tracking analytics events */
28
+ appName?: string;
27
29
  /** Tenant slug */
28
30
  tenantSlug?: string;
29
31
  /**
@@ -67,7 +69,7 @@ interface HabeetatProviderProps {
67
69
  * </HabeetatProvider>
68
70
  * ```
69
71
  */
70
- declare function HabeetatProvider({ logto, platformUrl, logtoResource, appId, tenantSlug, autoSignIn, callbackPath, loadingFallback, logging, children, }: HabeetatProviderProps): react_jsx_runtime.JSX.Element;
72
+ declare function HabeetatProvider({ logto, platformUrl, logtoResource, appId, appName, tenantSlug, autoSignIn, callbackPath, loadingFallback, logging, children, }: HabeetatProviderProps): react_jsx_runtime.JSX.Element;
71
73
 
72
74
  /**
73
75
  * Habeetat SDK state
@@ -106,6 +108,10 @@ interface HabeetatContextValue extends HabeetatState {
106
108
  getAccessToken: () => Promise<string | null>;
107
109
  /** Platform SDK API base URL (for internal use by useLogger) */
108
110
  platformUrl: string | null;
111
+ /** App name for analytics tracking */
112
+ appName?: string;
113
+ /** Current tenant slug */
114
+ tenantSlug?: string;
109
115
  /** Logger configuration */
110
116
  loggerConfig?: {
111
117
  enabled?: boolean;
@@ -281,6 +287,27 @@ interface UseLoggerReturn {
281
287
  */
282
288
  declare function useLogger(config?: FrontendLoggerConfig): UseLoggerReturn;
283
289
 
290
+ interface TrackEventInput {
291
+ eventName: string;
292
+ properties?: Record<string, unknown>;
293
+ sessionId?: string;
294
+ timestamp?: string;
295
+ }
296
+ interface UseAnalyticsReturn {
297
+ track: (events: TrackEventInput | TrackEventInput[]) => Promise<void>;
298
+ }
299
+ /**
300
+ * Hook for tracking analytics events.
301
+ * The `appName` is injected automatically from the HabeetatProvider config.
302
+ *
303
+ * @example
304
+ * ```tsx
305
+ * const { track } = useAnalytics();
306
+ * await track({ eventName: 'button_click', properties: { button: 'save' } });
307
+ * ```
308
+ */
309
+ declare function useAnalytics(): UseAnalyticsReturn;
310
+
284
311
  interface RequirePermissionProps {
285
312
  permission: string;
286
313
  children: ReactNode;
@@ -301,4 +328,4 @@ interface RequireFeatureProps {
301
328
  */
302
329
  declare function RequireFeature({ flag, children, fallback }: RequireFeatureProps): react_jsx_runtime.JSX.Element;
303
330
 
304
- export { type AuthState, type FrontendLoggerConfig, HabeetatContext, type HabeetatContextValue, HabeetatProvider, type HabeetatProviderProps, type HabeetatState, type LogtoConfig, RequireFeature, RequirePermission, type UseLoggerReturn, useAuth, useFeatures, useHabeetat, useLogger, usePermissions, useSignIn, useSignOut, useSubscription };
331
+ export { type AuthState, type FrontendLoggerConfig, HabeetatContext, type HabeetatContextValue, HabeetatProvider, type HabeetatProviderProps, type HabeetatState, type LogtoConfig, RequireFeature, RequirePermission, type UseAnalyticsReturn, type UseLoggerReturn, useAnalytics, useAuth, useFeatures, useHabeetat, useLogger, usePermissions, useSignIn, useSignOut, useSubscription };
package/dist/index.d.ts CHANGED
@@ -24,6 +24,8 @@ interface HabeetatProviderProps {
24
24
  logtoResource?: string;
25
25
  /** App slug registered in Habeetat */
26
26
  appId?: string;
27
+ /** App name used as app_id when tracking analytics events */
28
+ appName?: string;
27
29
  /** Tenant slug */
28
30
  tenantSlug?: string;
29
31
  /**
@@ -67,7 +69,7 @@ interface HabeetatProviderProps {
67
69
  * </HabeetatProvider>
68
70
  * ```
69
71
  */
70
- declare function HabeetatProvider({ logto, platformUrl, logtoResource, appId, tenantSlug, autoSignIn, callbackPath, loadingFallback, logging, children, }: HabeetatProviderProps): react_jsx_runtime.JSX.Element;
72
+ declare function HabeetatProvider({ logto, platformUrl, logtoResource, appId, appName, tenantSlug, autoSignIn, callbackPath, loadingFallback, logging, children, }: HabeetatProviderProps): react_jsx_runtime.JSX.Element;
71
73
 
72
74
  /**
73
75
  * Habeetat SDK state
@@ -106,6 +108,10 @@ interface HabeetatContextValue extends HabeetatState {
106
108
  getAccessToken: () => Promise<string | null>;
107
109
  /** Platform SDK API base URL (for internal use by useLogger) */
108
110
  platformUrl: string | null;
111
+ /** App name for analytics tracking */
112
+ appName?: string;
113
+ /** Current tenant slug */
114
+ tenantSlug?: string;
109
115
  /** Logger configuration */
110
116
  loggerConfig?: {
111
117
  enabled?: boolean;
@@ -281,6 +287,27 @@ interface UseLoggerReturn {
281
287
  */
282
288
  declare function useLogger(config?: FrontendLoggerConfig): UseLoggerReturn;
283
289
 
290
+ interface TrackEventInput {
291
+ eventName: string;
292
+ properties?: Record<string, unknown>;
293
+ sessionId?: string;
294
+ timestamp?: string;
295
+ }
296
+ interface UseAnalyticsReturn {
297
+ track: (events: TrackEventInput | TrackEventInput[]) => Promise<void>;
298
+ }
299
+ /**
300
+ * Hook for tracking analytics events.
301
+ * The `appName` is injected automatically from the HabeetatProvider config.
302
+ *
303
+ * @example
304
+ * ```tsx
305
+ * const { track } = useAnalytics();
306
+ * await track({ eventName: 'button_click', properties: { button: 'save' } });
307
+ * ```
308
+ */
309
+ declare function useAnalytics(): UseAnalyticsReturn;
310
+
284
311
  interface RequirePermissionProps {
285
312
  permission: string;
286
313
  children: ReactNode;
@@ -301,4 +328,4 @@ interface RequireFeatureProps {
301
328
  */
302
329
  declare function RequireFeature({ flag, children, fallback }: RequireFeatureProps): react_jsx_runtime.JSX.Element;
303
330
 
304
- export { type AuthState, type FrontendLoggerConfig, HabeetatContext, type HabeetatContextValue, HabeetatProvider, type HabeetatProviderProps, type HabeetatState, type LogtoConfig, RequireFeature, RequirePermission, type UseLoggerReturn, useAuth, useFeatures, useHabeetat, useLogger, usePermissions, useSignIn, useSignOut, useSubscription };
331
+ export { type AuthState, type FrontendLoggerConfig, HabeetatContext, type HabeetatContextValue, HabeetatProvider, type HabeetatProviderProps, type HabeetatState, type LogtoConfig, RequireFeature, RequirePermission, type UseAnalyticsReturn, type UseLoggerReturn, useAnalytics, useAuth, useFeatures, useHabeetat, useLogger, usePermissions, useSignIn, useSignOut, useSubscription };
package/dist/index.js CHANGED
@@ -37,6 +37,7 @@ function HabeetatInner({
37
37
  platformUrl,
38
38
  logtoResource,
39
39
  appId,
40
+ appName,
40
41
  tenantSlug,
41
42
  autoSignIn,
42
43
  callbackPath,
@@ -67,6 +68,7 @@ function HabeetatInner({
67
68
  platformUrl,
68
69
  logtoResource,
69
70
  appId,
71
+ appName,
70
72
  tenantSlug,
71
73
  getAccessToken,
72
74
  tokenResource,
@@ -79,6 +81,7 @@ function HabeetatInner({
79
81
  function HabeetatData({
80
82
  platformUrl,
81
83
  appId,
84
+ appName,
82
85
  tenantSlug,
83
86
  tokenResource,
84
87
  getAccessToken,
@@ -191,6 +194,8 @@ function HabeetatData({
191
194
  isFeatureEnabled,
192
195
  getAccessToken: getToken,
193
196
  platformUrl: apiUrl,
197
+ appName,
198
+ tenantSlug,
194
199
  loggerConfig: logging
195
200
  }),
196
201
  [
@@ -204,6 +209,8 @@ function HabeetatData({
204
209
  isFeatureEnabled,
205
210
  getToken,
206
211
  apiUrl,
212
+ appName,
213
+ tenantSlug,
207
214
  logging
208
215
  ]
209
216
  );
@@ -214,6 +221,7 @@ function HabeetatProvider({
214
221
  platformUrl,
215
222
  logtoResource,
216
223
  appId,
224
+ appName,
217
225
  tenantSlug,
218
226
  autoSignIn = false,
219
227
  callbackPath = "/callback",
@@ -237,6 +245,7 @@ function HabeetatProvider({
237
245
  platformUrl,
238
246
  logtoResource,
239
247
  appId,
248
+ appName,
240
249
  tenantSlug,
241
250
  autoSignIn,
242
251
  callbackPath,
@@ -491,6 +500,28 @@ function useLogger(config) {
491
500
  [log, debug, info, warn, error, flush]
492
501
  );
493
502
  }
503
+ function useAnalytics() {
504
+ const { getAccessToken, platformUrl, appName, tenantSlug } = useHabeetat();
505
+ const track = react.useCallback(async (events) => {
506
+ if (!platformUrl || !tenantSlug) return;
507
+ const token = await getAccessToken();
508
+ if (!token) return;
509
+ const eventList = Array.isArray(events) ? events : [events];
510
+ await fetch(`${platformUrl}/analytics/track`, {
511
+ method: "POST",
512
+ headers: {
513
+ Authorization: `Bearer ${token}`,
514
+ "Content-Type": "application/json"
515
+ },
516
+ body: JSON.stringify({
517
+ tenantId: tenantSlug,
518
+ ...appName && { appId: appName },
519
+ events: eventList
520
+ })
521
+ });
522
+ }, [getAccessToken, platformUrl, appName, tenantSlug]);
523
+ return { track };
524
+ }
494
525
  function RequirePermission({ permission, children, fallback = null }) {
495
526
  const { hasPermission } = usePermissions();
496
527
  if (!hasPermission(permission)) {
@@ -510,6 +541,7 @@ exports.HabeetatContext = HabeetatContext;
510
541
  exports.HabeetatProvider = HabeetatProvider;
511
542
  exports.RequireFeature = RequireFeature;
512
543
  exports.RequirePermission = RequirePermission;
544
+ exports.useAnalytics = useAnalytics;
513
545
  exports.useAuth = useAuth;
514
546
  exports.useFeatures = useFeatures;
515
547
  exports.useHabeetat = useHabeetat;
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/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 /** 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 /** 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 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 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 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 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 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 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 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 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 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 { 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 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"]}
package/dist/index.mjs CHANGED
@@ -35,6 +35,7 @@ function HabeetatInner({
35
35
  platformUrl,
36
36
  logtoResource,
37
37
  appId,
38
+ appName,
38
39
  tenantSlug,
39
40
  autoSignIn,
40
41
  callbackPath,
@@ -65,6 +66,7 @@ function HabeetatInner({
65
66
  platformUrl,
66
67
  logtoResource,
67
68
  appId,
69
+ appName,
68
70
  tenantSlug,
69
71
  getAccessToken,
70
72
  tokenResource,
@@ -77,6 +79,7 @@ function HabeetatInner({
77
79
  function HabeetatData({
78
80
  platformUrl,
79
81
  appId,
82
+ appName,
80
83
  tenantSlug,
81
84
  tokenResource,
82
85
  getAccessToken,
@@ -189,6 +192,8 @@ function HabeetatData({
189
192
  isFeatureEnabled,
190
193
  getAccessToken: getToken,
191
194
  platformUrl: apiUrl,
195
+ appName,
196
+ tenantSlug,
192
197
  loggerConfig: logging
193
198
  }),
194
199
  [
@@ -202,6 +207,8 @@ function HabeetatData({
202
207
  isFeatureEnabled,
203
208
  getToken,
204
209
  apiUrl,
210
+ appName,
211
+ tenantSlug,
205
212
  logging
206
213
  ]
207
214
  );
@@ -212,6 +219,7 @@ function HabeetatProvider({
212
219
  platformUrl,
213
220
  logtoResource,
214
221
  appId,
222
+ appName,
215
223
  tenantSlug,
216
224
  autoSignIn = false,
217
225
  callbackPath = "/callback",
@@ -235,6 +243,7 @@ function HabeetatProvider({
235
243
  platformUrl,
236
244
  logtoResource,
237
245
  appId,
246
+ appName,
238
247
  tenantSlug,
239
248
  autoSignIn,
240
249
  callbackPath,
@@ -489,6 +498,28 @@ function useLogger(config) {
489
498
  [log, debug, info, warn, error, flush]
490
499
  );
491
500
  }
501
+ function useAnalytics() {
502
+ const { getAccessToken, platformUrl, appName, tenantSlug } = useHabeetat();
503
+ const track = useCallback(async (events) => {
504
+ if (!platformUrl || !tenantSlug) return;
505
+ const token = await getAccessToken();
506
+ if (!token) return;
507
+ const eventList = Array.isArray(events) ? events : [events];
508
+ await fetch(`${platformUrl}/analytics/track`, {
509
+ method: "POST",
510
+ headers: {
511
+ Authorization: `Bearer ${token}`,
512
+ "Content-Type": "application/json"
513
+ },
514
+ body: JSON.stringify({
515
+ tenantId: tenantSlug,
516
+ ...appName && { appId: appName },
517
+ events: eventList
518
+ })
519
+ });
520
+ }, [getAccessToken, platformUrl, appName, tenantSlug]);
521
+ return { track };
522
+ }
492
523
  function RequirePermission({ permission, children, fallback = null }) {
493
524
  const { hasPermission } = usePermissions();
494
525
  if (!hasPermission(permission)) {
@@ -504,6 +535,6 @@ function RequireFeature({ flag, children, fallback = null }) {
504
535
  return /* @__PURE__ */ jsx(Fragment, { children });
505
536
  }
506
537
 
507
- export { HabeetatContext, HabeetatProvider, RequireFeature, RequirePermission, useAuth, useFeatures, useHabeetat, useLogger, usePermissions, useSignIn, useSignOut, useSubscription };
538
+ export { HabeetatContext, HabeetatProvider, RequireFeature, RequirePermission, useAnalytics, useAuth, useFeatures, useHabeetat, useLogger, usePermissions, useSignIn, useSignOut, useSubscription };
508
539
  //# sourceMappingURL=index.mjs.map
509
540
  //# sourceMappingURL=index.mjs.map
@@ -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/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 /** 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 /** 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 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 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 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 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 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 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 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 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 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 { 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 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"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@habeetat/sdk-react",
3
- "version": "0.1.0-dev.20260325103304.48d3552",
3
+ "version": "0.1.0-dev.20260330160419.ec63152",
4
4
  "description": "Habeetat Platform SDK for React applications",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.mjs",