@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 +29 -2
- package/dist/index.d.ts +29 -2
- package/dist/index.js +32 -0
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +32 -1
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
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
|
package/dist/index.mjs.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":["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