@fluid-app/rep-sdk 0.1.0
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/README.md +413 -0
- package/dist/ContactsScreen-BYXF74BO.js +4 -0
- package/dist/ContactsScreen-BYXF74BO.js.map +1 -0
- package/dist/ContactsScreen-XZOQJVFE.cjs +17 -0
- package/dist/ContactsScreen-XZOQJVFE.cjs.map +1 -0
- package/dist/CustomersScreen-53SXRDDK.cjs +17 -0
- package/dist/CustomersScreen-53SXRDDK.cjs.map +1 -0
- package/dist/CustomersScreen-VS6LGULO.js +4 -0
- package/dist/CustomersScreen-VS6LGULO.js.map +1 -0
- package/dist/MessagingScreen-O42JEJMW.js +4 -0
- package/dist/MessagingScreen-O42JEJMW.js.map +1 -0
- package/dist/MessagingScreen-UCVLYWZB.cjs +17 -0
- package/dist/MessagingScreen-UCVLYWZB.cjs.map +1 -0
- package/dist/OrdersScreen-QQJFTTSS.js +4 -0
- package/dist/OrdersScreen-QQJFTTSS.js.map +1 -0
- package/dist/OrdersScreen-WNT2WDLI.cjs +17 -0
- package/dist/OrdersScreen-WNT2WDLI.cjs.map +1 -0
- package/dist/ProductsScreen-CTIAKS3Z.cjs +17 -0
- package/dist/ProductsScreen-CTIAKS3Z.cjs.map +1 -0
- package/dist/ProductsScreen-TRIT2FE3.js +4 -0
- package/dist/ProductsScreen-TRIT2FE3.js.map +1 -0
- package/dist/chunk-2AWTZV3T.js +16 -0
- package/dist/chunk-2AWTZV3T.js.map +1 -0
- package/dist/chunk-CXRJSGO6.js +16 -0
- package/dist/chunk-CXRJSGO6.js.map +1 -0
- package/dist/chunk-DEQ3PBVX.cjs +29 -0
- package/dist/chunk-DEQ3PBVX.cjs.map +1 -0
- package/dist/chunk-JZRNKSKT.cjs +19 -0
- package/dist/chunk-JZRNKSKT.cjs.map +1 -0
- package/dist/chunk-LO2HDG6C.js +26 -0
- package/dist/chunk-LO2HDG6C.js.map +1 -0
- package/dist/chunk-MBUCXIUN.cjs +19 -0
- package/dist/chunk-MBUCXIUN.cjs.map +1 -0
- package/dist/chunk-MEOOAMH2.cjs +19 -0
- package/dist/chunk-MEOOAMH2.cjs.map +1 -0
- package/dist/chunk-PJWPO4BJ.js +16 -0
- package/dist/chunk-PJWPO4BJ.js.map +1 -0
- package/dist/chunk-PZIHCYDD.js +16 -0
- package/dist/chunk-PZIHCYDD.js.map +1 -0
- package/dist/chunk-QUVJ3R4T.cjs +19 -0
- package/dist/chunk-QUVJ3R4T.cjs.map +1 -0
- package/dist/chunk-WH7WZXT6.js +16 -0
- package/dist/chunk-WH7WZXT6.js.map +1 -0
- package/dist/chunk-YII3IXF4.cjs +19 -0
- package/dist/chunk-YII3IXF4.cjs.map +1 -0
- package/dist/index.cjs +2446 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +2164 -0
- package/dist/index.d.ts +2164 -0
- package/dist/index.js +2079 -0
- package/dist/index.js.map +1 -0
- package/package.json +58 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/client/types.ts","../src/client/fluid-client.ts","../src/providers/FluidThemeProvider.tsx","../src/providers/FluidProvider.tsx","../src/auth/constants.ts","../src/auth/url-token.ts","../src/auth/token-storage.ts","../src/auth/token-utils.ts","../src/auth/types.ts","../src/auth/dev-utils.ts","../src/providers/FluidAuthProvider.tsx","../src/types/page-template.ts","../src/registries/page-template-registry.ts","../src/core/resolve-pages.ts","../src/providers/PageTemplateProvider.tsx","../src/hooks/use-fluid-api.ts","../src/hooks/use-fluid-profile.ts","../src/hooks/use-fluid-permissions.ts","../src/hooks/use-fluid-theme.ts","../src/hooks/use-current-rep.ts","../src/hooks/use-fluid-auth.ts","../src/hooks/demo-data/calendar-events.ts","../src/hooks/use-calendar-events.ts","../src/hooks/demo-data/todos.ts","../src/hooks/use-todos.ts","../src/hooks/hook-types.ts","../src/hooks/demo-data/activities.ts","../src/hooks/use-activities.ts","../src/hooks/demo-data/catchups.ts","../src/hooks/use-catchups.ts","../src/hooks/demo-data/mysite.ts","../src/hooks/use-mysite.ts","../src/hooks/demo-data/conversations.ts","../src/hooks/use-conversations.ts","../src/types/screen-types.ts","../src/hooks/demo-data/contacts.ts","../src/hooks/use-contacts.ts","../src/components/AuthError.tsx","../src/components/RequireAuth.tsx","../src/themes/index.ts","../src/screens/index.ts"],"names":["createContext","useMemo","jsx","useContext","isBrowser","useRef","isLoading","useState","useEffect","error","useCallback","useQuery","now","daysFromNow","hoursAgo","daysAgo"],"mappings":"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","file":"index.js","sourcesContent":["// ============================================================================\n// HTTP Method Constants\n// ============================================================================\n\n/**\n * HTTP methods supported by the API client.\n * Use `as const` for literal type inference and type safety.\n */\nexport const HTTP_METHODS = {\n GET: \"GET\",\n POST: \"POST\",\n PUT: \"PUT\",\n PATCH: \"PATCH\",\n DELETE: \"DELETE\",\n} as const;\n\n/**\n * Union type of all supported HTTP methods.\n * Derived from HTTP_METHODS constant to avoid duplication.\n */\nexport type HttpMethod = (typeof HTTP_METHODS)[keyof typeof HTTP_METHODS];\n\n// ============================================================================\n// Configuration Types\n// ============================================================================\n\n/**\n * Configuration for the Fluid SDK client.\n * Use Readonly<FluidSDKConfig> when the config should not be modified after creation.\n */\nexport interface FluidSDKConfig {\n /**\n * Base URL for all API requests (e.g., \"https://api.fluid.app/api\")\n */\n readonly baseUrl: string;\n\n /**\n * Function to retrieve the authentication token\n * Return null/undefined if no token is available\n */\n readonly getAuthToken?: () => string | null | Promise<string | null>;\n\n /**\n * Callback invoked when a 401 authentication error occurs\n * Use this to trigger re-authentication flows\n */\n readonly onAuthError?: () => void;\n\n /**\n * Default headers to include in all requests\n * Example: { \"x-fluid-client\": \"rep-portal\" }\n */\n readonly defaultHeaders?: Readonly<Record<string, string>>;\n}\n\n/**\n * Options for individual API requests.\n * Uses HttpMethod type for method to ensure type safety.\n */\nexport interface RequestOptions {\n readonly method?: HttpMethod;\n readonly body?: unknown;\n readonly params?: Readonly<Record<string, unknown>>;\n readonly headers?: Readonly<Record<string, string>>;\n readonly signal?: AbortSignal;\n}\n\n// ============================================================================\n// Pagination Types\n// ============================================================================\n\n/**\n * Pagination parameters for list endpoints\n */\nexport interface PaginationParams {\n readonly page?: number;\n readonly per_page?: number;\n}\n\n// ============================================================================\n// Sort Order - Derive from constant for single source of truth\n// ============================================================================\n\n/**\n * Sort order constant - single source of truth for sort direction values.\n * Use SORT_ORDERS.asc instead of \"asc\" for type-safe comparisons.\n */\nexport const SORT_ORDERS = {\n asc: \"asc\",\n desc: \"desc\",\n} as const;\n\n/**\n * Union type of sort order values, derived from SORT_ORDERS constant.\n * @see deriving-typeof-for-object-keys pattern\n */\nexport type SortOrder = (typeof SORT_ORDERS)[keyof typeof SORT_ORDERS];\n\n/**\n * Common filter parameters for list endpoints\n */\nexport interface BaseListParams extends PaginationParams {\n readonly sort_by?: string;\n readonly sort_order?: SortOrder;\n readonly search?: string;\n}\n","/**\n * Fluid API Client\n * Adapted from: packages/fluidos-api-client/src/lib/fetch-client.ts\n * Provides authenticated API access with domain-specific methods\n */\n\nimport type { Rep, UpdateRepData } from \"../types/rep\";\nimport type { Profile } from \"../types/profile\";\nimport type { UserPermissions } from \"../types/permissions\";\nimport {\n HTTP_METHODS,\n type FluidSDKConfig,\n type RequestOptions,\n type BaseListParams,\n} from \"./types\";\n\n/**\n * API Error class for structured error handling\n */\nexport class ApiError extends Error {\n readonly status: number;\n readonly data: unknown;\n\n constructor(message: string, status: number, data?: unknown) {\n super(message);\n this.name = \"ApiError\";\n this.status = status;\n this.data = data;\n\n // V8-specific stack trace capture (Node.js, Chrome)\n const errorWithCapture = Error as typeof Error & {\n captureStackTrace?: (\n target: object,\n constructor: typeof ApiError,\n ) => void;\n };\n if (errorWithCapture.captureStackTrace) {\n errorWithCapture.captureStackTrace(this, ApiError);\n }\n }\n\n toJSON() {\n return {\n name: this.name,\n message: this.message,\n status: this.status,\n data: this.data,\n };\n }\n}\n\n/**\n * Type guard for ApiError\n */\nexport function isApiError(error: unknown): error is ApiError {\n return error instanceof ApiError;\n}\n\n// ============================================================================\n// Discriminated Union for API Responses\n// ============================================================================\n\n/**\n * Discriminated union representing the result of an API call.\n * Use `isApiSuccess` and `isApiFailure` type guards to narrow.\n */\nexport type ApiResult<T> =\n | { readonly success: true; readonly data: T }\n | { readonly success: false; readonly error: ApiError };\n\n/**\n * Type guard for successful API result\n */\nexport function isApiSuccess<T>(\n result: ApiResult<T>,\n): result is { readonly success: true; readonly data: T } {\n return result.success === true;\n}\n\n/**\n * Type guard for failed API result\n */\nexport function isApiFailure<T>(\n result: ApiResult<T>,\n): result is { readonly success: false; readonly error: ApiError } {\n return result.success === false;\n}\n\n/**\n * Type guard to check if a value is a non-null string\n */\nfunction isString(value: unknown): value is string {\n return typeof value === \"string\";\n}\n\n/**\n * Extract error message from API response data using `in` operator narrowing.\n * Checks common error message field names in order of precedence.\n */\nfunction extractErrorMessage(\n data: Readonly<Record<string, unknown>>,\n fallback: string,\n): string {\n // Use `in` operator to narrow and then type guard to validate string type\n if (\"message\" in data && isString(data.message)) {\n return data.message;\n }\n if (\"error_message\" in data && isString(data.error_message)) {\n return data.error_message;\n }\n if (\"error\" in data && isString(data.error)) {\n return data.error;\n }\n return fallback;\n}\n\n// ============================================================================\n// Domain Types\n// ============================================================================\n\n// ============================================================================\n// Product Types\n// ============================================================================\n\nexport interface Product {\n readonly id: number;\n readonly title: string;\n readonly sku?: string | null;\n readonly price: string | number;\n readonly description?: string | null;\n readonly image_url?: string;\n readonly status?: string;\n readonly active?: boolean;\n readonly slug?: string;\n readonly in_stock?: boolean;\n readonly display_price?: string;\n readonly currency_code?: string;\n readonly updated_at?: string;\n}\n\nexport interface ProductListParams extends BaseListParams {\n readonly search_query?: string;\n readonly status?: readonly (\"active\" | \"draft\" | \"archived\" | \"all\")[];\n readonly category_id?: string;\n readonly category_ids?: readonly number[];\n readonly collection_id?: string;\n readonly collection_ids?: readonly number[];\n readonly order_by?: readonly string[];\n readonly country_code?: readonly string[];\n readonly published_stores?: readonly (\"retail\" | \"rep\")[];\n}\n\nexport interface ProductsResponse {\n readonly products: readonly Product[];\n readonly meta: {\n readonly request_id: string;\n readonly timestamp: string;\n readonly pagination?: {\n readonly current_page: number;\n readonly per_page: number;\n readonly total_pages: number;\n readonly total_count: number;\n };\n };\n}\n\n// ============================================================================\n// Order Types\n// ============================================================================\n\nexport interface Order {\n readonly id: string;\n readonly order_number: string;\n readonly status: string;\n readonly total: number;\n readonly customer_id: string;\n readonly rep_id?: string;\n readonly created_at: string;\n readonly updated_at: string;\n}\n\nexport interface OrderListParams extends BaseListParams {\n readonly status?: string;\n readonly customer_id?: string;\n readonly date_from?: string;\n readonly date_to?: string;\n}\n\nexport interface CreateOrderData {\n readonly customer_id: string;\n readonly line_items: readonly OrderLineItem[];\n readonly notes?: string;\n}\n\nexport interface OrderLineItem {\n readonly product_id: string;\n readonly quantity: number;\n readonly price?: number;\n}\n\n// ============================================================================\n// Analytics Types\n// ============================================================================\n\nexport interface DashboardData {\n readonly total_sales: number;\n readonly total_orders: number;\n readonly total_customers: number;\n readonly recent_orders: readonly Order[];\n}\n\nexport interface SalesParams {\n readonly date_from?: string;\n readonly date_to?: string;\n readonly group_by?: \"day\" | \"week\" | \"month\";\n}\n\nexport interface SalesData {\n readonly total: number;\n readonly data: readonly SalesDataPoint[];\n}\n\nexport interface SalesDataPoint {\n readonly date: string;\n readonly amount: number;\n readonly orders: number;\n}\n\n// ============================================================================\n// Client Implementation\n// ============================================================================\n\n/**\n * Creates a configured Fluid API client instance\n */\nexport function createFluidClient(config: FluidSDKConfig) {\n const { baseUrl, getAuthToken, onAuthError, defaultHeaders = {} } = config;\n\n /**\n * Build headers for a request\n */\n async function buildHeaders(\n customHeaders?: Record<string, string>,\n ): Promise<Record<string, string>> {\n const headers: Record<string, string> = {\n \"Content-Type\": \"application/json\",\n ...defaultHeaders,\n ...customHeaders,\n };\n\n if (getAuthToken) {\n const token = await getAuthToken();\n if (token) {\n headers.Authorization = `Bearer ${token}`;\n }\n }\n\n return headers;\n }\n\n /**\n * Build URL with query parameters (Rails-compatible)\n */\n function buildUrl(\n endpoint: string,\n params?: Record<string, unknown>,\n ): string {\n // Construct URL by concatenating baseUrl + endpoint\n // Using URL constructor with relative paths would strip the baseUrl path (e.g., /api)\n const normalizedBase = baseUrl.endsWith(\"/\")\n ? baseUrl.slice(0, -1)\n : baseUrl;\n const normalizedEndpoint = endpoint.startsWith(\"/\")\n ? endpoint\n : `/${endpoint}`;\n const url = new URL(normalizedBase + normalizedEndpoint);\n\n if (params) {\n for (const [key, value] of Object.entries(params)) {\n if (value === undefined || value === null) {\n continue;\n }\n\n if (Array.isArray(value)) {\n // Handle arrays like Rails expects: key[]\n for (const item of value) {\n url.searchParams.append(`${key}[]`, String(item));\n }\n } else if (typeof value === \"object\") {\n // Handle nested objects: key[subkey]\n for (const [subKey, subValue] of Object.entries(\n value as Record<string, unknown>,\n )) {\n if (subValue === undefined || subValue === null) {\n continue;\n }\n\n if (Array.isArray(subValue)) {\n for (const item of subValue) {\n url.searchParams.append(`${key}[${subKey}][]`, String(item));\n }\n } else {\n url.searchParams.append(`${key}[${subKey}]`, String(subValue));\n }\n }\n } else {\n url.searchParams.append(key, String(value));\n }\n }\n }\n\n return url.toString();\n }\n\n /**\n * Default request options for type-safe defaults.\n * Uses `satisfies` to validate against RequestOptions while preserving literal types.\n */\n const defaultRequestOptions = {\n method: HTTP_METHODS.GET,\n } as const satisfies Partial<RequestOptions>;\n\n /**\n * Main request function\n */\n async function request<TResponse = unknown>(\n endpoint: string,\n options: RequestOptions = {},\n ): Promise<TResponse> {\n const {\n method = defaultRequestOptions.method,\n headers: customHeaders,\n params,\n body,\n signal,\n } = options;\n\n // Use buildUrl for all requests to ensure baseUrl path is preserved\n const url = buildUrl(\n endpoint,\n method === HTTP_METHODS.GET ? params : undefined,\n );\n\n const headers = await buildHeaders(customHeaders);\n\n let response: Response;\n\n try {\n const fetchOptions: RequestInit = {\n method,\n headers,\n };\n // Only add signal and body when defined to satisfy exactOptionalPropertyTypes\n // RequestInit expects signal: AbortSignal | null, not undefined\n if (signal !== undefined) {\n fetchOptions.signal = signal;\n }\n if (body && method !== HTTP_METHODS.GET) {\n fetchOptions.body = JSON.stringify(body);\n }\n response = await fetch(url, fetchOptions);\n } catch (networkError) {\n throw new ApiError(\n `Network error: ${networkError instanceof Error ? networkError.message : \"Unknown network error\"}`,\n 0,\n null,\n );\n }\n\n // Handle authentication errors\n if (response.status === 401 && onAuthError) {\n onAuthError();\n }\n\n if (!response.ok) {\n try {\n const contentType = response.headers.get(\"content-type\");\n if (contentType?.includes(\"application/json\")) {\n const data = (await response.json()) as Record<string, unknown>;\n // Use `in` operator narrowing to safely extract error message\n const errorMessage = extractErrorMessage(\n data,\n `${method} request failed`,\n );\n throw new ApiError(\n errorMessage,\n response.status,\n \"errors\" in data ? data.errors : data,\n );\n } else {\n throw new ApiError(\n `${method} request failed with status ${response.status}`,\n response.status,\n null,\n );\n }\n } catch (error) {\n if (isApiError(error)) {\n throw error;\n }\n\n throw new ApiError(\n `${method} request failed with status ${response.status}`,\n response.status,\n null,\n );\n }\n }\n\n // Handle empty responses (204 No Content)\n // Note: Callers expecting nullable responses should use requestNullable<T>\n // which properly types the return as T | null\n if (\n response.status === 204 ||\n response.headers.get(\"content-length\") === \"0\"\n ) {\n // Type assertion required: 204 No Content has no body to parse.\n // This is safe when TResponse is a union including null (e.g., T | null).\n // For fully type-safe nullable handling, prefer requestNullable() or safeRequest().\n return null as TResponse;\n }\n\n try {\n const data: unknown = await response.json();\n // Runtime check: verify we got an object/array, not a primitive that would be mistyped\n if (data === null || data === undefined) {\n throw new ApiError(\n \"Unexpected null/undefined in JSON response\",\n response.status,\n null,\n );\n }\n // Type assertion required: JSON.parse returns `unknown`, but we've validated\n // the response is not null/undefined. The caller specifies TResponse based on\n // their knowledge of the API endpoint's response schema.\n return data as TResponse;\n } catch (parseError) {\n if (isApiError(parseError)) {\n throw parseError;\n }\n throw new ApiError(\n \"Failed to parse response as JSON\",\n response.status,\n null,\n );\n }\n }\n\n /**\n * Request function for endpoints that may return null (204 No Content).\n * Properly types the return as T | null.\n */\n async function requestNullable<TResponse>(\n endpoint: string,\n options: RequestOptions = {},\n ): Promise<TResponse | null> {\n return request<TResponse | null>(endpoint, options);\n }\n\n /**\n * Safe request wrapper that returns a discriminated union instead of throwing.\n * Use `isApiSuccess` or `isApiFailure` to narrow the result.\n */\n async function safeRequest<TResponse>(\n endpoint: string,\n options: RequestOptions = {},\n ): Promise<ApiResult<TResponse>> {\n try {\n const data = await request<TResponse>(endpoint, options);\n return { success: true, data };\n } catch (error) {\n if (isApiError(error)) {\n return { success: false, error };\n }\n // Wrap unknown errors in ApiError\n return {\n success: false,\n error: new ApiError(\n error instanceof Error ? error.message : \"Unknown error\",\n 0,\n null,\n ),\n };\n }\n }\n\n /**\n * Helper to safely convert typed params to Record<string, unknown>.\n * Type assertion required: TypeScript's structural typing allows any object\n * to be treated as Record<string, unknown> when we only need to iterate\n * over its entries. This is safe because buildUrl only reads properties.\n */\n function toParams<T extends object>(\n params: T | undefined,\n ): Record<string, unknown> | undefined {\n return params as Record<string, unknown> | undefined;\n }\n\n // Convenience HTTP methods using HTTP_METHODS constant for type safety\n const get = <\n TResponse = unknown,\n TParams extends object = Record<string, unknown>,\n >(\n endpoint: string,\n params?: TParams,\n options?: Omit<RequestOptions, \"method\" | \"params\">,\n ) => {\n // Build request options object, only adding params if defined\n const baseOptions = {\n ...options,\n method: HTTP_METHODS.GET,\n } satisfies RequestOptions;\n\n const convertedParams = toParams(params);\n const requestOptions: RequestOptions =\n convertedParams !== undefined\n ? { ...baseOptions, params: convertedParams }\n : baseOptions;\n\n return request<TResponse>(endpoint, requestOptions);\n };\n\n const post = <TResponse = unknown>(\n endpoint: string,\n body?: unknown,\n options?: Omit<RequestOptions, \"method\" | \"body\">,\n ) =>\n request<TResponse>(endpoint, {\n ...options,\n method: HTTP_METHODS.POST,\n body,\n } satisfies RequestOptions);\n\n const put = <TResponse = unknown>(\n endpoint: string,\n body?: unknown,\n options?: Omit<RequestOptions, \"method\" | \"body\">,\n ) =>\n request<TResponse>(endpoint, {\n ...options,\n method: HTTP_METHODS.PUT,\n body,\n } satisfies RequestOptions);\n\n const patch = <TResponse = unknown>(\n endpoint: string,\n body?: unknown,\n options?: Omit<RequestOptions, \"method\" | \"body\">,\n ) =>\n request<TResponse>(endpoint, {\n ...options,\n method: HTTP_METHODS.PATCH,\n body,\n } satisfies RequestOptions);\n\n const del = <TResponse = unknown>(\n endpoint: string,\n options?: Omit<RequestOptions, \"method\">,\n ) =>\n request<TResponse>(endpoint, {\n ...options,\n method: HTTP_METHODS.DELETE,\n } satisfies RequestOptions);\n\n // ============================================================================\n // Domain-Specific API Methods\n // ============================================================================\n\n return {\n // Low-level methods for custom endpoints\n request,\n requestNullable,\n safeRequest,\n get,\n post,\n put,\n patch,\n delete: del,\n\n // Products API - matches fluid-admin's /company/v1/products\n products: {\n list: (params?: ProductListParams) =>\n get<ProductsResponse, ProductListParams>(\n \"/company/v1/products\",\n params,\n ),\n get: (id: string | number) =>\n get<{ product: Product }>(`/company/v1/products/${id}`),\n search: (query: string, params?: ProductListParams) =>\n get<ProductsResponse>(\"/company/v1/products\", {\n search_query: query,\n ...params,\n } as Record<string, unknown>),\n },\n\n // Orders API\n orders: {\n list: (params?: OrderListParams) =>\n get<Order[], OrderListParams>(\"/orders\", params),\n get: (id: string) => get<Order>(`/orders/${id}`),\n create: (data: CreateOrderData) => post<Order>(\"/orders\", data),\n },\n\n // Reps API\n reps: {\n current: () => get<Rep>(\"/reps/me\"),\n updateProfile: (data: UpdateRepData) => patch<Rep>(\"/reps/me\", data),\n },\n\n // Profile API (themes, navigation, screens)\n profile: {\n get: () => get<Profile>(\"/rep_app/manifest\"),\n },\n\n // Permissions API\n permissions: {\n get: () => get<UserPermissions>(\"/company/roles/my_permissions\"),\n },\n\n // Analytics API\n analytics: {\n dashboard: () => get<DashboardData>(\"/analytics/dashboard\"),\n sales: (params?: SalesParams) =>\n get<SalesData, SalesParams>(\"/analytics/sales\", params),\n },\n };\n}\n\nexport type FluidClient = ReturnType<typeof createFluidClient>;\n","/**\n * Theme Provider for Fluid SDK\n * Simplified from: packages/rep-app/src/hooks/use-theme.ts\n * Handles CSS variable injection without localStorage persistence\n */\n\nimport {\n createContext,\n useContext,\n useState,\n useEffect,\n useMemo,\n useCallback,\n type ReactNode,\n} from \"react\";\nimport type { Theme } from \"../types/theme\";\n\n/**\n * Context value for theme management.\n * All properties are readonly since context values should not be mutated by consumers.\n */\ninterface ThemeContextValue {\n /** Currently active theme */\n readonly currentTheme: Theme | null;\n /** Switch to a different theme */\n readonly setTheme: (theme: Theme) => void;\n /** Switch between light and dark mode for the current theme */\n readonly setThemeMode: (mode: \"light\" | \"dark\") => void;\n}\n\nconst ThemeContext = createContext<ThemeContextValue | null>(null);\n\nexport interface FluidThemeProviderProps {\n children: ReactNode;\n /** Initial theme to apply */\n initialTheme?: Theme;\n /** Container element for scoped theme application (defaults to document.documentElement) */\n container?: HTMLElement | null;\n}\n\n/**\n * Apply theme CSS variables to a container element\n */\nfunction applyThemeVariables(\n theme: Theme,\n container: HTMLElement | null,\n): void {\n const target = container ?? document.documentElement;\n\n // Apply each theme config value as a CSS variable\n for (const [key, value] of Object.entries(theme.config)) {\n target.style.setProperty(`--fluid-${key}`, value);\n }\n\n // Set data attribute for mode-based styling\n if (theme.mode) {\n target.dataset.fluidThemeMode = theme.mode;\n }\n}\n\nexport function FluidThemeProvider({\n children,\n initialTheme,\n container,\n}: FluidThemeProviderProps) {\n const [currentTheme, setCurrentTheme] = useState<Theme | null>(\n initialTheme ?? null,\n );\n\n // Apply theme variables when theme changes\n useEffect(() => {\n if (currentTheme) {\n applyThemeVariables(currentTheme, container ?? null);\n }\n }, [currentTheme, container]);\n\n const setTheme = useCallback((theme: Theme) => {\n setCurrentTheme(theme);\n }, []);\n\n const setThemeMode = useCallback((mode: \"light\" | \"dark\") => {\n setCurrentTheme((prev) => (prev ? { ...prev, mode } : null));\n }, []);\n\n // Use `satisfies` to validate shape at compile time while preserving inference\n const value = useMemo(\n () =>\n ({\n currentTheme,\n setTheme,\n setThemeMode,\n }) satisfies ThemeContextValue,\n [currentTheme, setTheme, setThemeMode],\n );\n\n return (\n <ThemeContext.Provider value={value}>{children}</ThemeContext.Provider>\n );\n}\n\n/**\n * Hook to access theme context\n * Must be used within a FluidThemeProvider\n */\nexport function useThemeContext(): ThemeContextValue {\n const context = useContext(ThemeContext);\n if (!context) {\n throw new Error(\"useThemeContext must be used within a FluidThemeProvider\");\n }\n return context;\n}\n","/**\n * Main Fluid SDK Provider\n * Wraps QueryClientProvider and FluidThemeProvider\n */\n\nimport {\n createContext,\n useContext,\n useMemo,\n useRef,\n type ReactNode,\n} from \"react\";\nimport { QueryClient, QueryClientProvider } from \"@tanstack/react-query\";\nimport { createFluidClient, type FluidClient } from \"../client/fluid-client\";\nimport { FluidThemeProvider } from \"./FluidThemeProvider\";\nimport type { FluidSDKConfig } from \"../client/types\";\nimport type { Theme } from \"../types/theme\";\n\n/**\n * Context value for FluidProvider.\n * All properties are readonly since context values should not be mutated by consumers.\n */\ninterface FluidContextValue {\n /** Configured API client instance */\n readonly client: FluidClient;\n /** SDK configuration */\n readonly config: FluidSDKConfig;\n}\n\nconst FluidContext = createContext<FluidContextValue | null>(null);\n\nexport interface FluidProviderProps {\n /** SDK configuration (baseUrl, auth, etc.) */\n config: FluidSDKConfig;\n /** React children */\n children: ReactNode;\n /** Optional custom QueryClient instance */\n queryClient?: QueryClient;\n /** Optional initial theme */\n initialTheme?: Theme;\n /** Optional container for scoped theme application */\n themeContainer?: HTMLElement | null;\n}\n\n/**\n * Main provider for the Fluid Rep SDK\n *\n * @example\n * ```tsx\n * import { FluidProvider } from \"@fluid-app/rep-sdk\";\n *\n * function App() {\n * return (\n * <FluidProvider\n * config={{\n * baseUrl: \"https://api.fluid.app/api\",\n * getAuthToken: () => localStorage.getItem(\"token\"),\n * }}\n * >\n * <YourApp />\n * </FluidProvider>\n * );\n * }\n * ```\n */\nexport function FluidProvider({\n config,\n children,\n queryClient,\n initialTheme,\n themeContainer,\n}: FluidProviderProps) {\n // Create default QueryClient if none provided\n // Using lazy initialization to ensure it's only created once\n const defaultQueryClient = useMemo(\n () =>\n new QueryClient({\n defaultOptions: {\n queries: {\n staleTime: 1000 * 60, // 1 minute\n retry: 1,\n },\n },\n }),\n [],\n );\n\n // Keep latest config in a ref so client creation reads current values\n const configRef = useRef(config);\n configRef.current = config;\n\n // Recreate client only when baseUrl changes (primitive dependency)\n // createFluidClient destructures config eagerly, capturing callbacks at creation time\n const client = useMemo(\n () => createFluidClient(configRef.current),\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [config.baseUrl],\n );\n\n // Context value only changes when client changes\n const contextValue = useMemo(\n () => ({ client, config: configRef.current }) satisfies FluidContextValue,\n [client],\n );\n\n // Build theme provider props conditionally to satisfy exactOptionalPropertyTypes\n // We only pass props that are defined to avoid passing `undefined` explicitly\n const themeProviderProps = {\n ...(initialTheme !== undefined && { initialTheme }),\n ...(themeContainer !== undefined && { container: themeContainer }),\n };\n\n return (\n <QueryClientProvider client={queryClient ?? defaultQueryClient}>\n <FluidContext.Provider value={contextValue}>\n <FluidThemeProvider {...themeProviderProps}>\n {children}\n </FluidThemeProvider>\n </FluidContext.Provider>\n </QueryClientProvider>\n );\n}\n\n/**\n * Hook to access the Fluid context\n * Must be used within a FluidProvider\n */\nexport function useFluidContext(): FluidContextValue {\n const context = useContext(FluidContext);\n if (!context) {\n throw new Error(\"useFluidContext must be used within a FluidProvider\");\n }\n return context;\n}\n","/**\n * Auth Constants for Fluid Rep SDK\n *\n * These constants define the default values for authentication\n * configuration and storage keys.\n */\n\n/**\n * Authentication-related constants with sensible defaults.\n */\nexport const AUTH_CONSTANTS = {\n /**\n * Grace period in milliseconds to account for clock skew\n * when checking token expiration. Tokens are considered valid\n * if they expire within this period.\n */\n TOKEN_GRACE_PERIOD_MS: 30 * 1000, // 30 seconds\n\n /**\n * Default cookie max age in seconds (9 days).\n * This matches the typical JWT token lifetime from the Fluid API.\n */\n COOKIE_MAX_AGE: 9 * 24 * 60 * 60, // 9 days = 777600 seconds\n} as const;\n\n/**\n * Storage keys for auth tokens.\n */\nexport const STORAGE_KEYS = {\n /** localStorage key for user token */\n USER_TOKEN: \"fluidUserToken\",\n /** localStorage key for company token (legacy) */\n COMPANY_TOKEN: \"fluidCompanyToken\",\n /** Cookie name for auth token */\n AUTH_COOKIE: \"auth_token\",\n} as const;\n\n/**\n * Default URL parameter names for token extraction.\n */\nexport const URL_PARAMS = {\n /** URL parameter name for user token */\n USER_TOKEN: \"fluidUserToken\",\n /** URL parameter name for company token (legacy) */\n COMPANY_TOKEN: \"fluidCompanyToken\",\n} as const;\n","/**\n * URL Token Utilities for Fluid Rep SDK\n *\n * Functions for extracting and cleaning auth tokens from URL parameters.\n * This is the primary way tokens are passed from the parent Fluid Commerce\n * app to embedded rep portals.\n *\n * **Security model**: Tokens in URL parameters are a known tradeoff.\n * The token is extracted and immediately cleaned from the URL via\n * `history.replaceState()`. A `Referrer-Policy` meta tag in the\n * starter template prevents the token from leaking in referrer headers.\n * See docs/authentication.md for full security analysis.\n */\n\nimport { URL_PARAMS } from \"./constants\";\n\n/**\n * Check if we're running in a browser environment.\n */\nfunction isBrowser(): boolean {\n return typeof window !== \"undefined\";\n}\n\n/**\n * Extract the auth token from the URL query parameters.\n *\n * @param tokenKey - The URL parameter name (default: \"fluidUserToken\")\n * @returns The token value or null if not present\n *\n * @example\n * ```ts\n * // URL: https://myportal.com?fluidUserToken=eyJhbG...\n * const token = extractTokenFromUrl();\n * // token = \"eyJhbG...\"\n * ```\n */\nexport function extractTokenFromUrl(\n tokenKey: string = URL_PARAMS.USER_TOKEN,\n): string | null {\n if (!isBrowser()) {\n return null;\n }\n\n try {\n const searchParams = new URLSearchParams(window.location.search);\n return searchParams.get(tokenKey);\n } catch {\n return null;\n }\n}\n\n/**\n * Extract the company token from the URL query parameters.\n * This is a legacy parameter that may still be used in some flows.\n *\n * @param tokenKey - The URL parameter name (default: \"fluidCompanyToken\")\n * @returns The token value or null if not present\n */\nexport function extractCompanyTokenFromUrl(\n tokenKey: string = URL_PARAMS.COMPANY_TOKEN,\n): string | null {\n if (!isBrowser()) {\n return null;\n }\n\n try {\n const searchParams = new URLSearchParams(window.location.search);\n return searchParams.get(tokenKey);\n } catch {\n return null;\n }\n}\n\n/**\n * Remove the auth token from the URL without reloading the page.\n * This prevents the token from being accidentally shared via URL copy/paste\n * or appearing in browser history.\n *\n * Uses history.replaceState to update the URL cleanly.\n *\n * @param tokenKey - The URL parameter name to remove (default: \"fluidUserToken\")\n *\n * @example\n * ```ts\n * // Before: https://myportal.com?fluidUserToken=eyJhbG...&page=1\n * cleanTokenFromUrl();\n * // After: https://myportal.com?page=1\n * ```\n */\nexport function cleanTokenFromUrl(\n tokenKey: string = URL_PARAMS.USER_TOKEN,\n): void {\n if (!isBrowser()) {\n return;\n }\n\n try {\n const url = new URL(window.location.href);\n const hadToken = url.searchParams.has(tokenKey);\n const hadCompanyToken = url.searchParams.has(URL_PARAMS.COMPANY_TOKEN);\n\n // Remove both user and company tokens\n url.searchParams.delete(tokenKey);\n url.searchParams.delete(URL_PARAMS.COMPANY_TOKEN);\n\n // Only update URL if we actually removed something\n if (hadToken || hadCompanyToken) {\n // Use replaceState to avoid adding to browser history\n window.history.replaceState(\n window.history.state,\n document.title,\n url.toString(),\n );\n }\n } catch (error) {\n console.warn(\"[FluidAuth] Failed to clean token from URL:\", error);\n }\n}\n\n/**\n * Check if the URL contains an auth token parameter.\n *\n * @param tokenKey - The URL parameter name (default: \"fluidUserToken\")\n * @returns true if the URL contains the token parameter\n */\nexport function hasTokenInUrl(\n tokenKey: string = URL_PARAMS.USER_TOKEN,\n): boolean {\n if (!isBrowser()) {\n return false;\n }\n\n try {\n const searchParams = new URLSearchParams(window.location.search);\n return searchParams.has(tokenKey);\n } catch {\n return false;\n }\n}\n\n/**\n * Extract all auth-related tokens from the URL at once.\n *\n * @param userTokenKey - The URL parameter name for user token\n * @param companyTokenKey - The URL parameter name for company token\n * @returns Object with both token values (or null if not present)\n */\nexport function extractAllTokensFromUrl(\n userTokenKey: string = URL_PARAMS.USER_TOKEN,\n companyTokenKey: string = URL_PARAMS.COMPANY_TOKEN,\n): { userToken: string | null; companyToken: string | null } {\n if (!isBrowser()) {\n return { userToken: null, companyToken: null };\n }\n\n try {\n const searchParams = new URLSearchParams(window.location.search);\n return {\n userToken: searchParams.get(userTokenKey),\n companyToken: searchParams.get(companyTokenKey),\n };\n } catch {\n return { userToken: null, companyToken: null };\n }\n}\n","/**\n * Token Storage Utilities for Fluid Rep SDK\n *\n * Functions for storing and retrieving auth tokens from\n * cookies and localStorage.\n */\n\nimport { AUTH_CONSTANTS, STORAGE_KEYS } from \"./constants\";\nimport type { FluidAuthConfig } from \"./types\";\n\n/**\n * Check if we're running in a browser environment.\n */\nfunction isBrowser(): boolean {\n return typeof window !== \"undefined\" && typeof document !== \"undefined\";\n}\n\n/**\n * Parse cookies from document.cookie string into an object.\n */\nfunction parseCookies(): Record<string, string> {\n if (!isBrowser()) {\n return {};\n }\n\n const cookies: Record<string, string> = {};\n const cookieString = document.cookie;\n\n if (!cookieString) {\n return cookies;\n }\n\n cookieString.split(\";\").forEach((cookie) => {\n const [name, ...valueParts] = cookie.trim().split(\"=\");\n if (name) {\n cookies[name] = decodeURIComponent(valueParts.join(\"=\"));\n }\n });\n\n return cookies;\n}\n\n/**\n * Set a cookie with the given options.\n */\nfunction setCookie(\n name: string,\n value: string,\n options: Readonly<{\n maxAge?: number;\n path?: string;\n sameSite?: \"strict\" | \"lax\" | \"none\";\n secure?: boolean;\n }> = {},\n): void {\n if (!isBrowser()) {\n return;\n }\n\n const {\n maxAge = AUTH_CONSTANTS.COOKIE_MAX_AGE,\n path = \"/\",\n sameSite = \"lax\",\n secure = window.location.protocol === \"https:\",\n } = options;\n\n let cookieString = `${name}=${encodeURIComponent(value)}`;\n cookieString += `; path=${path}`;\n cookieString += `; max-age=${maxAge}`;\n cookieString += `; samesite=${sameSite}`;\n\n if (secure) {\n cookieString += \"; secure\";\n }\n\n document.cookie = cookieString;\n}\n\n/**\n * Delete a cookie by setting its max-age to 0.\n */\nfunction deleteCookie(name: string, path: string = \"/\"): void {\n if (!isBrowser()) {\n return;\n }\n\n document.cookie = `${name}=; path=${path}; max-age=0`;\n}\n\n/**\n * Get the stored auth token.\n * Checks cookie first, then falls back to localStorage.\n *\n * @param config - Optional auth config for custom cookie key\n * @returns The stored token or null if not found\n *\n * @example\n * ```ts\n * const token = getStoredToken();\n * if (token) {\n * console.log(\"User is logged in\");\n * }\n * ```\n */\nexport function getStoredToken(config?: FluidAuthConfig): string | null {\n if (!isBrowser()) {\n return null;\n }\n\n const cookieKey = config?.cookieKey ?? STORAGE_KEYS.AUTH_COOKIE;\n const localStorageKey = STORAGE_KEYS.USER_TOKEN;\n\n // Priority: cookie > localStorage\n const cookies = parseCookies();\n const cookieToken = cookies[cookieKey];\n\n if (cookieToken) {\n return cookieToken;\n }\n\n try {\n return localStorage.getItem(localStorageKey);\n } catch {\n // localStorage might be unavailable (private browsing, etc.)\n return null;\n }\n}\n\n/**\n * Store an auth token in both cookie and localStorage.\n * Using both provides redundancy and compatibility with different auth flows.\n *\n * @param token - The JWT token to store\n * @param config - Optional auth config for custom storage options\n *\n * @example\n * ```ts\n * storeToken(newToken);\n * // Token is now accessible via getStoredToken()\n * ```\n */\nexport function storeToken(token: string, config?: FluidAuthConfig): void {\n if (!isBrowser()) {\n return;\n }\n\n const cookieKey = config?.cookieKey ?? STORAGE_KEYS.AUTH_COOKIE;\n const maxAge = config?.cookieMaxAge ?? AUTH_CONSTANTS.COOKIE_MAX_AGE;\n\n // Store in cookie\n try {\n setCookie(cookieKey, token, {\n maxAge,\n path: \"/\",\n // Use 'none' with secure for cross-origin iframe scenarios\n sameSite: window.self !== window.top ? \"none\" : \"lax\",\n secure: window.location.protocol === \"https:\",\n });\n } catch (error) {\n console.warn(\"[FluidAuth] Failed to store token in cookie:\", error);\n }\n\n // Also store in localStorage as backup\n try {\n localStorage.setItem(STORAGE_KEYS.USER_TOKEN, token);\n } catch (error) {\n console.warn(\"[FluidAuth] Failed to store token in localStorage:\", error);\n }\n}\n\n/**\n * Clear all stored auth tokens from cookies and localStorage.\n *\n * @param config - Optional auth config for custom cookie key\n *\n * @example\n * ```ts\n * // User logs out\n * clearTokens();\n * ```\n */\nexport function clearTokens(config?: FluidAuthConfig): void {\n if (!isBrowser()) {\n return;\n }\n\n const cookieKey = config?.cookieKey ?? STORAGE_KEYS.AUTH_COOKIE;\n\n // Clear cookie\n try {\n deleteCookie(cookieKey);\n } catch {\n // Ignore cleanup errors\n }\n\n // Clear localStorage\n try {\n localStorage.removeItem(STORAGE_KEYS.USER_TOKEN);\n localStorage.removeItem(STORAGE_KEYS.COMPANY_TOKEN);\n } catch {\n // Ignore cleanup errors\n }\n}\n\n/**\n * Check if any auth token is stored.\n *\n * @param config - Optional auth config\n * @returns true if a token is stored, false otherwise\n */\nexport function hasStoredToken(config?: FluidAuthConfig): boolean {\n return getStoredToken(config) !== null;\n}\n","/**\n * Token Utilities for Fluid Rep SDK\n *\n * Functions for decoding, validating, and checking JWT tokens.\n */\n\nimport {\n decodeJwt,\n jwtVerify,\n createRemoteJWKSet,\n type JWTPayload as JoseJWTPayload,\n} from \"jose\";\nimport { AUTH_CONSTANTS } from \"./constants\";\nimport type { JWTPayload, TokenValidationResult } from \"./types\";\n\n/**\n * Extract a JWTPayload from a jose-decoded JWT payload.\n *\n * Type assertions are required because jose's payload type uses `unknown`\n * for custom claims. This helper centralises the mapping so that\n * both {@link decodeToken} and {@link verifyToken} share the same logic.\n */\nfunction extractPayloadFromJose(\n decoded: JoseJWTPayload & Partial<JWTPayload>,\n): JWTPayload {\n return {\n id: decoded.id as number | undefined,\n email: decoded.email as string | undefined,\n full_name: decoded.full_name as string | undefined,\n user_type: (decoded.user_type as JWTPayload[\"user_type\"]) ?? \"rep\",\n og_user_type: decoded.og_user_type as JWTPayload[\"og_user_type\"],\n company_id: decoded.company_id as number | undefined,\n exp: decoded.exp,\n auth_type: decoded.auth_type as string | undefined,\n };\n}\n\n/**\n * Decode a JWT token and extract its payload.\n *\n * **Security note:** This function does NOT verify the JWT signature.\n * It only decodes the payload. Any valid JWT structure will be accepted,\n * regardless of who signed it.\n *\n * Client-side token decoding is used for UX purposes only (displaying\n * user info, role-based UI). The real security boundary is the server-side\n * API, which verifies the signature on every request.\n *\n * For signature verification, use {@link verifyToken} with a JWKS URL.\n *\n * @param token - The JWT token string\n * @returns The decoded JWT payload, or null if decoding fails\n *\n * @example\n * ```ts\n * const payload = decodeToken(token);\n * if (payload) {\n * console.log(`User: ${payload.email}`);\n * }\n * ```\n */\nexport function decodeToken(token: string): JWTPayload | null {\n try {\n // Type assertion required: jose's decodeJwt returns JoseJWTPayload with unknown custom claims.\n // We extend it with Partial<JWTPayload> to access our app-specific fields safely.\n const decoded = decodeJwt(token) as JoseJWTPayload & Partial<JWTPayload>;\n\n return extractPayloadFromJose(decoded);\n } catch (error) {\n console.error(\"[FluidAuth] Failed to decode JWT token:\", error);\n return null;\n }\n}\n\n/**\n * Check if a token has expired.\n * Includes a configurable grace period to account for clock skew.\n *\n * @param token - The JWT token string\n * @param gracePeriodMs - Grace period in milliseconds (default: 30 seconds)\n * @returns true if the token is expired, false otherwise\n *\n * @example\n * ```ts\n * if (isTokenExpired(token)) {\n * // Token is expired, need to re-authenticate\n * clearAuth();\n * }\n * ```\n */\nexport function isTokenExpired(\n token: string,\n gracePeriodMs: number = AUTH_CONSTANTS.TOKEN_GRACE_PERIOD_MS,\n): boolean {\n try {\n const decoded = decodeJwt(token);\n\n // If no expiration, token never expires\n if (!decoded.exp) {\n return false;\n }\n\n // exp is in seconds, convert to milliseconds\n const expirationTime = decoded.exp * 1000;\n const currentTime = Date.now();\n\n // Token is expired if current time is past expiration + grace period\n return currentTime > expirationTime + gracePeriodMs;\n } catch {\n // If we can't decode the token, treat it as expired\n return true;\n }\n}\n\n/**\n * Validate a JWT token for format and expiration.\n *\n * **Security note:** This function checks JWT structure and expiration\n * but does NOT verify the signature. It is a UX-level check only.\n * For signature verification, use {@link verifyToken} with a JWKS URL.\n *\n * @param token - The JWT token string\n * @param gracePeriodMs - Grace period for expiration check (default: 30 seconds)\n * @returns Validation result with status and decoded payload if valid\n *\n * @example\n * ```ts\n * const result = validateToken(token);\n * if (result.isValid) {\n * console.log(`Welcome, ${result.payload?.full_name}`);\n * } else {\n * console.error(`Auth failed: ${result.error}`);\n * }\n * ```\n */\nexport function validateToken(\n token: string,\n gracePeriodMs: number = AUTH_CONSTANTS.TOKEN_GRACE_PERIOD_MS,\n): TokenValidationResult {\n // Check if token is provided\n if (!token || token.trim() === \"\") {\n return {\n isValid: false,\n error: \"Token is empty or not provided\",\n };\n }\n\n // Try to decode the token\n const payload = decodeToken(token);\n if (!payload) {\n return {\n isValid: false,\n error: \"Token has invalid format\",\n };\n }\n\n // Check expiration\n if (isTokenExpired(token, gracePeriodMs)) {\n return {\n isValid: false,\n payload,\n error: \"Token has expired\",\n };\n }\n\n return {\n isValid: true,\n payload,\n };\n}\n\n/**\n * Type guard to check if a validation result is valid.\n * Enables TypeScript narrowing of the result type.\n *\n * @param result - The validation result to check\n * @returns true if the token is valid (narrows payload to non-optional)\n *\n * @example\n * ```ts\n * const result = validateToken(token);\n * if (isValidToken(result)) {\n * // result.payload is guaranteed to be JWTPayload (not undefined)\n * console.log(result.payload.email);\n * }\n * ```\n */\nexport function isValidToken(\n result: TokenValidationResult,\n): result is TokenValidationResult & { isValid: true; payload: JWTPayload } {\n return result.isValid === true;\n}\n\n/**\n * Get the expiration time of a token as a Date.\n *\n * @param token - The JWT token string\n * @returns The expiration Date, or null if token has no expiration or is invalid\n */\nexport function getTokenExpiration(token: string): Date | null {\n try {\n const decoded = decodeJwt(token);\n if (!decoded.exp) {\n return null;\n }\n return new Date(decoded.exp * 1000);\n } catch {\n return null;\n }\n}\n\n/**\n * Get the time remaining until token expiration in milliseconds.\n *\n * @param token - The JWT token string\n * @returns Milliseconds until expiration, or 0 if expired/invalid, or Infinity if no expiration\n */\nexport function getTokenTimeRemaining(token: string): number {\n try {\n const decoded = decodeJwt(token);\n if (!decoded.exp) {\n return Infinity;\n }\n const expirationTime = decoded.exp * 1000;\n const remaining = expirationTime - Date.now();\n return Math.max(0, remaining);\n } catch {\n return 0;\n }\n}\n\n/**\n * Verify a JWT token's signature using a JWKS endpoint and extract its payload.\n *\n * Unlike {@link decodeToken}, this function cryptographically verifies\n * that the token was signed by a trusted key.\n *\n * @param token - The JWT token string\n * @param jwksUrl - URL of the JWKS endpoint\n * @returns The verified JWT payload, or null if verification fails\n */\nexport async function verifyToken(\n token: string,\n jwksUrl: string,\n): Promise<JWTPayload | null> {\n try {\n const JWKS = createRemoteJWKSet(new URL(jwksUrl));\n const { payload } = await jwtVerify(token, JWKS);\n\n // Type assertion required: jose's jwtVerify returns JoseJWTPayload with unknown custom claims.\n // We extend it with Partial<JWTPayload> to access our app-specific fields safely.\n const decoded = payload as JoseJWTPayload & Partial<JWTPayload>;\n return extractPayloadFromJose(decoded);\n } catch (error) {\n console.error(\"[FluidAuth] JWT signature verification failed:\", error);\n return null;\n }\n}\n","/**\n * Auth Types for Fluid Rep SDK\n *\n * These types define the JWT payload structure and authentication\n * configuration options for rep portal applications.\n */\n\n// ============================================================================\n// User Types - Derive from constant for single source of truth\n// ============================================================================\n\n/**\n * User type constant - single source of truth for user role values.\n * Use USER_TYPES.admin instead of \"admin\" for type-safe comparisons.\n */\nexport const USER_TYPES = {\n admin: \"admin\",\n rep: \"rep\",\n root_admin: \"root_admin\",\n customer: \"customer\",\n} as const;\n\n/**\n * Union type of all user types, derived from USER_TYPES constant.\n * @see deriving-typeof-for-object-keys pattern\n */\nexport type UserType = (typeof USER_TYPES)[keyof typeof USER_TYPES];\n\n/**\n * Runtime validation for user types.\n * @param value - The value to check\n * @returns true if value is a valid UserType\n */\nexport function isUserType(value: string): value is UserType {\n return Object.values(USER_TYPES).includes(value as UserType);\n}\n\n/**\n * JWT payload structure from Fluid Commerce authentication.\n * Contains user identity and role information.\n */\nexport interface JWTPayload {\n /** User ID */\n id?: number | undefined;\n /** User email address */\n email?: string | undefined;\n /** Full name of the user */\n full_name?: string | undefined;\n /** User role type */\n user_type: UserType;\n /** Original user type (for impersonation scenarios) */\n og_user_type?: UserType | undefined;\n /** Company ID the user belongs to */\n company_id?: number | undefined;\n /** Token expiration timestamp (Unix seconds) */\n exp?: number | undefined;\n /** Authentication type (e.g., \"standard\", \"impersonation\") */\n auth_type?: string | undefined;\n}\n\n/**\n * Configuration options for FluidAuthProvider.\n * All options have sensible defaults.\n */\nexport interface FluidAuthConfig {\n /**\n * URL parameter name for the auth token.\n * @default \"fluidUserToken\"\n */\n tokenKey?: string;\n\n /**\n * Cookie name for storing the auth token.\n * @default \"auth_token\"\n */\n cookieKey?: string;\n\n /**\n * Cookie max age in seconds.\n * @default 777600 (9 days)\n */\n cookieMaxAge?: number;\n\n /**\n * Grace period in milliseconds to account for clock skew\n * when checking token expiration.\n * @default 30000 (30 seconds)\n */\n gracePeriodMs?: number;\n\n /**\n * Callback invoked when authentication fails (no valid token).\n * Use this to redirect to a login page or show an error.\n */\n onAuthFailure?: () => void;\n\n /**\n * Enable dev-mode auth bypass.\n * When true AND running in Vite dev mode (import.meta.env.DEV),\n * auth will use a synthetic mock user instead of requiring a real JWT.\n * The mock user allows UI rendering but API calls will fail (token is null).\n * @default false\n */\n devBypass?: boolean;\n\n /**\n * JWKS (JSON Web Key Set) URL for signature verification.\n * When provided, JWT signatures will be verified against keys\n * from this endpoint before accepting the token.\n *\n * This provides defense-in-depth client-side verification.\n * Without this, tokens are only decoded (not verified) client-side,\n * and real verification happens server-side on API calls.\n *\n * @example \"https://api.fluid.app/.well-known/jwks.json\"\n */\n jwksUrl?: string;\n}\n\n/**\n * Value provided by the FluidAuthContext.\n * All properties are readonly since context values should not be mutated by consumers.\n */\nexport interface FluidAuthContextValue {\n /** Whether the user is authenticated with a valid token */\n readonly isAuthenticated: boolean;\n /** Whether authentication is still being initialized */\n readonly isLoading: boolean;\n /** Decoded JWT payload if authenticated, null otherwise */\n readonly user: JWTPayload | null;\n /** Raw JWT token string if authenticated, null otherwise */\n readonly token: string | null;\n /** Clear authentication state and stored tokens */\n readonly clearAuth: () => void;\n /** Authentication error if any occurred during initialization */\n readonly error: Error | null;\n}\n\n/**\n * Result of token validation.\n * Uses a discriminated union for type-safe handling of valid/invalid states.\n */\nexport type TokenValidationResult =\n | {\n /** Token is valid */\n isValid: true;\n /** Decoded JWT payload */\n payload: JWTPayload;\n /** No error when valid */\n error?: undefined;\n }\n | {\n /** Token is invalid */\n isValid: false;\n /** Decoded JWT payload if parseable but expired */\n payload?: JWTPayload;\n /** Error message explaining why validation failed */\n error: string;\n };\n","import type { JWTPayload } from \"./types\";\nimport { USER_TYPES } from \"./types\";\n\n/**\n * Check if dev bypass should be active.\n * Requires both the config flag AND Vite dev mode.\n */\nexport function isDevBypassActive(devBypass?: boolean): boolean {\n if (!devBypass) return false;\n\n try {\n // import.meta.env.DEV is a Vite compile-time constant\n // It's `true` in dev mode and completely tree-shaken in production\n return import.meta.env.DEV === true;\n } catch {\n return false;\n }\n}\n\n/**\n * Create a synthetic dev user for local development.\n * This user has realistic data for UI rendering but no real auth.\n */\nexport function createDevUser(): JWTPayload {\n return {\n id: 0,\n email: \"dev@localhost\",\n full_name: \"Dev User\",\n user_type: USER_TYPES.rep,\n og_user_type: undefined,\n company_id: 0,\n exp: undefined, // Never expires\n auth_type: \"dev_bypass\",\n };\n}\n","/**\n * FluidAuthProvider - Authentication Provider for Fluid Rep SDK\n *\n * Handles JWT token extraction from URL, validation, storage, and\n * provides authentication context to child components.\n */\n\nimport {\n createContext,\n useContext,\n useEffect,\n useState,\n useCallback,\n useMemo,\n useRef,\n type ReactNode,\n} from \"react\";\nimport type {\n FluidAuthConfig,\n FluidAuthContextValue,\n JWTPayload,\n} from \"../auth/types\";\nimport { extractTokenFromUrl, cleanTokenFromUrl } from \"../auth/url-token\";\nimport { getStoredToken, storeToken, clearTokens } from \"../auth/token-storage\";\nimport {\n validateToken,\n verifyToken,\n isTokenExpired,\n} from \"../auth/token-utils\";\nimport { isDevBypassActive, createDevUser } from \"../auth/dev-utils\";\n\n/**\n * Auth context - null when outside provider\n */\nconst FluidAuthContext = createContext<FluidAuthContextValue | null>(null);\n\nexport interface FluidAuthProviderProps {\n /** React children to wrap with auth context */\n children: ReactNode;\n /** Auth configuration options */\n config?: FluidAuthConfig;\n}\n\n/**\n * Authentication provider for Fluid rep portal applications.\n *\n * On mount, this provider:\n * 1. Checks for a token in the URL (passed from parent app)\n * 2. Cleans token from URL immediately (security)\n * 3. Falls back to stored token (cookie/localStorage)\n * 4. Validates the token (checks expiration)\n * 5. Stores valid tokens for future use\n * 6. Calls onAuthFailure if no valid token found\n *\n * @example\n * ```tsx\n * import { FluidAuthProvider } from \"@fluid-app/rep-sdk\";\n *\n * function App() {\n * return (\n * <FluidAuthProvider\n * config={{\n * onAuthFailure: () => {\n * window.location.href = \"/login\";\n * },\n * }}\n * >\n * <YourApp />\n * </FluidAuthProvider>\n * );\n * }\n * ```\n */\nexport function FluidAuthProvider({\n children,\n config,\n}: FluidAuthProviderProps) {\n const configRef = useRef(config);\n configRef.current = config;\n\n const [isLoading, setIsLoading] = useState(true);\n const [token, setToken] = useState<string | null>(null);\n const [user, setUser] = useState<JWTPayload | null>(null);\n const [error, setError] = useState<Error | null>(null);\n\n // Initialize auth on mount\n useEffect(() => {\n const initializeAuth = async () => {\n try {\n // DEV BYPASS: Check for env variable token first, then dev bypass\n if (isDevBypassActive(config?.devBypass)) {\n // Check for VITE_DEV_TOKEN env variable first (real token in dev)\n const envToken = import.meta.env.VITE_DEV_TOKEN;\n if (envToken) {\n const validation = validateToken(envToken, config?.gracePeriodMs);\n if (validation.isValid && validation.payload) {\n storeToken(envToken, config);\n setToken(envToken);\n setUser(validation.payload);\n setError(null);\n return;\n }\n console.warn(\n \"[FluidAuth] VITE_DEV_TOKEN is invalid or expired, falling back to mock user\",\n );\n }\n\n // No valid env token - use synthetic dev user\n console.warn(\n \"[FluidAuth] Dev bypass active - using mock user. API calls will fail without a real token.\",\n );\n const devUser = createDevUser();\n setToken(null);\n setUser(devUser);\n setError(null);\n return;\n }\n\n // 1. Try to get token from URL first (fresh authentication)\n const tokenKey = config?.tokenKey ?? \"fluidUserToken\";\n let candidateToken = extractTokenFromUrl(tokenKey);\n\n // Clean token from URL immediately after extraction (security)\n // Do this BEFORE validation so the URL is clean even if validation fails\n cleanTokenFromUrl(tokenKey);\n\n // 2. Fall back to stored token\n if (!candidateToken) {\n candidateToken = getStoredToken(config);\n }\n\n // 3. If we have a token, validate it\n if (candidateToken) {\n let payload: JWTPayload | null = null;\n\n if (config?.jwksUrl) {\n // Signature verification enabled - use verifyToken\n payload = await verifyToken(candidateToken, config.jwksUrl);\n if (!payload) {\n clearTokens(config);\n setToken(null);\n setUser(null);\n setError(new Error(\"JWT signature verification failed\"));\n config?.onAuthFailure?.();\n return;\n }\n // Also check expiration\n if (isTokenExpired(candidateToken, config?.gracePeriodMs)) {\n clearTokens(config);\n setToken(null);\n setUser(null);\n setError(new Error(\"Token has expired\"));\n config?.onAuthFailure?.();\n return;\n }\n } else {\n // No JWKS - existing behavior (decode only, check expiration)\n const validation = validateToken(\n candidateToken,\n config?.gracePeriodMs,\n );\n if (validation.isValid && validation.payload) {\n payload = validation.payload;\n } else {\n clearTokens(config);\n setToken(null);\n setUser(null);\n setError(new Error(validation.error ?? \"Invalid token\"));\n config?.onAuthFailure?.();\n return;\n }\n }\n\n // Valid token - store it and update state\n storeToken(candidateToken, config);\n setToken(candidateToken);\n setUser(payload);\n setError(null);\n } else {\n // No token available\n setToken(null);\n setUser(null);\n setError(new Error(\"No authentication token found\"));\n config?.onAuthFailure?.();\n }\n } catch (err) {\n const error =\n err instanceof Error ? err : new Error(\"Authentication error\");\n setError(error);\n setToken(null);\n setUser(null);\n config?.onAuthFailure?.();\n } finally {\n setIsLoading(false);\n }\n };\n\n void initializeAuth();\n // Only run on mount - config changes don't re-initialize\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n\n // Clear auth handler\n const clearAuth = useCallback(() => {\n clearTokens(configRef.current);\n setToken(null);\n setUser(null);\n setError(null);\n }, []);\n\n // Memoize context value\n // Use `satisfies` to validate shape at compile time while preserving inference\n const contextValue = useMemo(\n () =>\n ({\n isAuthenticated: user !== null,\n isLoading,\n user,\n token,\n clearAuth,\n error,\n }) satisfies FluidAuthContextValue,\n [token, isLoading, user, clearAuth, error],\n );\n\n return (\n <FluidAuthContext.Provider value={contextValue}>\n {children}\n </FluidAuthContext.Provider>\n );\n}\n\n/**\n * Hook to access the auth context directly.\n * Prefer using `useFluidAuth` for most use cases.\n *\n * @throws Error if used outside FluidAuthProvider\n */\nexport function useFluidAuthContext(): FluidAuthContextValue {\n const context = useContext(FluidAuthContext);\n\n if (!context) {\n throw new Error(\n \"useFluidAuthContext must be used within a FluidAuthProvider. \" +\n \"Wrap your app with <FluidAuthProvider> to use authentication features.\",\n );\n }\n\n return context;\n}\n","import type { WidgetSchema } from \"./widget-schema\";\n\n/**\n * Category for organizing page templates in the registry\n */\nexport interface PageCategory {\n /** Unique identifier for the category */\n readonly id: string;\n /** Display label */\n label: string;\n /** Icon identifier (e.g., lucide icon name) */\n icon?: string;\n}\n\n/**\n * A reusable page template that can be shared across multiple navigations\n */\nexport interface PageTemplate {\n /** Unique identifier for the template */\n readonly id: string;\n /** URL-friendly slug */\n slug: string;\n /** Display name */\n name: string;\n /** Description of the template's purpose */\n description?: string;\n /** Category ID for organization */\n category: string;\n /** Tags for filtering and search */\n tags?: readonly string[];\n /** The widget tree that defines the page content */\n component_tree: readonly WidgetSchema[];\n /** Semantic version of the template */\n version: string;\n /** Whether this is a core feature that cannot be removed */\n isCore?: boolean;\n /** Default prop values that can be customized */\n defaultProps?: Readonly<Record<string, unknown>>;\n /** Thumbnail image URL for UI display */\n thumbnail?: string;\n}\n\n/**\n * Reference to a shared page template within a navigation\n */\nexport interface PageReference {\n /** ID of the page template being referenced */\n page_template_id: string;\n /** Screen ID to assign to this page in the navigation */\n screen_id: number;\n /** Optional prop overrides (only prop values, not widget structure) */\n overrides?: readonly PageOverride[];\n}\n\n/**\n * Override for a specific widget's props within a page template\n */\nexport interface PageOverride {\n /** ID of the widget to override (must match WidgetSchema.id in the template) */\n readonly widget_id: string;\n /** Props to override (merged with original props) */\n props: Readonly<Record<string, unknown>>;\n}\n\n/**\n * Built-in page category IDs\n */\nexport const PAGE_CATEGORIES = {\n CORE: \"core\",\n COMMERCE: \"commerce\",\n COMMUNICATION: \"communication\",\n DATA: \"data\",\n CUSTOM: \"custom\",\n} as const;\n\nexport type PageCategoryId =\n (typeof PAGE_CATEGORIES)[keyof typeof PAGE_CATEGORIES];\n","import type {\n PageTemplate,\n PageCategory,\n PageCategoryId,\n} from \"../types/page-template\";\nimport { PAGE_CATEGORIES } from \"../types/page-template\";\n\n/**\n * Registry for managing reusable page templates.\n *\n * The registry provides a central store for page templates that can be\n * shared across multiple navigations. Core pages (like Messaging, Contacts)\n * are pre-registered and cannot be removed.\n *\n * @example\n * ```ts\n * // Register a custom page template\n * PageTemplateRegistry.register({\n * id: 'custom-dashboard',\n * slug: 'dashboard',\n * name: 'Custom Dashboard',\n * category: 'custom',\n * version: '1.0.0',\n * component_tree: [{ type: 'TextWidget', props: { text: 'Hello' } }],\n * });\n *\n * // Get a template by ID\n * const template = PageTemplateRegistry.get('custom-dashboard');\n *\n * // List all templates in a category\n * const corePages = PageTemplateRegistry.getByCategory('core');\n * ```\n */\nclass PageTemplateRegistryImpl {\n private templates = new Map<string, PageTemplate>();\n private categories: PageCategory[] = [];\n\n constructor() {\n // Initialize default categories\n this.categories = [\n { id: PAGE_CATEGORIES.CORE, label: \"Core Features\", icon: \"star\" },\n {\n id: PAGE_CATEGORIES.COMMERCE,\n label: \"Commerce\",\n icon: \"shopping-cart\",\n },\n {\n id: PAGE_CATEGORIES.COMMUNICATION,\n label: \"Communication\",\n icon: \"message-circle\",\n },\n {\n id: PAGE_CATEGORIES.DATA,\n label: \"Data & Analytics\",\n icon: \"bar-chart\",\n },\n { id: PAGE_CATEGORIES.CUSTOM, label: \"Custom\", icon: \"puzzle\" },\n ];\n }\n\n /**\n * Register a new page template.\n * @throws Error if a template with the same ID already exists\n */\n register(template: PageTemplate): void {\n if (this.templates.has(template.id)) {\n throw new Error(\n `Page template with ID \"${template.id}\" is already registered`,\n );\n }\n this.templates.set(template.id, template);\n }\n\n /**\n * Unregister a page template by ID.\n * Core templates cannot be unregistered.\n * @returns true if the template was removed, false if it didn't exist or is a core template\n */\n unregister(id: string): boolean {\n const template = this.templates.get(id);\n if (!template) {\n return false;\n }\n if (template.isCore) {\n console.warn(\n `Cannot unregister core page template \"${id}\". Core templates are required.`,\n );\n return false;\n }\n return this.templates.delete(id);\n }\n\n /**\n * Get a page template by ID.\n */\n get(id: string): PageTemplate | undefined {\n return this.templates.get(id);\n }\n\n /**\n * Get all page templates in a specific category.\n */\n getByCategory(category: PageCategoryId | string): PageTemplate[] {\n return Array.from(this.templates.values()).filter(\n (t) => t.category === category,\n );\n }\n\n /**\n * List all registered page templates.\n */\n listAll(): PageTemplate[] {\n return Array.from(this.templates.values());\n }\n\n /**\n * List all core page templates (isCore: true).\n */\n listCore(): PageTemplate[] {\n return Array.from(this.templates.values()).filter((t) => t.isCore);\n }\n\n /**\n * List all non-core page templates.\n */\n listOptional(): PageTemplate[] {\n return Array.from(this.templates.values()).filter((t) => !t.isCore);\n }\n\n /**\n * List all registered categories.\n */\n listCategories(): PageCategory[] {\n return [...this.categories];\n }\n\n /**\n * Add a custom category.\n */\n addCategory(category: PageCategory): void {\n if (this.categories.some((c) => c.id === category.id)) {\n console.warn(`Category with ID \"${category.id}\" already exists`);\n return;\n }\n this.categories.push(category);\n }\n\n /**\n * Check if a template exists by ID.\n */\n has(id: string): boolean {\n return this.templates.has(id);\n }\n\n /**\n * Get the count of registered templates.\n */\n get size(): number {\n return this.templates.size;\n }\n\n /**\n * Clear all non-core templates.\n * Useful for testing or resetting the registry.\n */\n clearNonCore(): void {\n for (const [id, template] of this.templates) {\n if (!template.isCore) {\n this.templates.delete(id);\n }\n }\n }\n}\n\n/**\n * Global page template registry singleton.\n *\n * This registry is automatically populated with core page templates\n * (Messaging, Contacts) when the SDK is imported.\n */\nexport const PageTemplateRegistry = new PageTemplateRegistryImpl();\n","import type { Navigation, ScreenDefinition, WidgetSchema } from \"../types\";\nimport type { PageReference, PageOverride } from \"../types/page-template\";\nimport { PageTemplateRegistry } from \"../registries/page-template-registry\";\n\n/**\n * Apply prop overrides to widgets in a component tree.\n * Recursively walks widget.props.children so overrides targeting\n * nested widgets (inside LayoutWidget, ContainerWidget, etc.) are applied.\n *\n * @param componentTree - The original component tree from the page template\n * @param overrides - Array of widget-specific prop overrides\n * @returns A new component tree with overrides applied\n */\nfunction applyOverrides(\n componentTree: readonly WidgetSchema[],\n overrides: readonly PageOverride[],\n): WidgetSchema[] {\n if (!overrides.length) {\n // Return a mutable copy to satisfy ScreenDefinition.component_tree type\n return [...componentTree];\n }\n\n // Build a map of widget_id -> override for O(1) lookup (built once, shared across recursion)\n const overrideMap = new Map(overrides.map((o) => [o.widget_id, o.props]));\n\n return componentTree.map((widget) =>\n applyWidgetOverrides(widget, overrideMap),\n );\n}\n\n/**\n * Recursively apply overrides to a widget and its children.\n * Only clones widgets that actually change (have an override or contain children that might).\n */\nfunction applyWidgetOverrides(\n widget: WidgetSchema,\n overrideMap: ReadonlyMap<string, Record<string, unknown>>,\n): WidgetSchema {\n const override = widget.id ? overrideMap.get(widget.id) : undefined;\n const children = widget.props.children;\n\n // Recurse into children if they exist (LayoutWidget, ContainerWidget)\n const hasChildren = Array.isArray(children) && children.length > 0;\n\n if (!override && !hasChildren) {\n return widget;\n }\n\n const newProps = override\n ? { ...widget.props, ...override }\n : { ...widget.props };\n\n if (hasChildren) {\n newProps.children = (children as readonly WidgetSchema[]).map((child) =>\n applyWidgetOverrides(child, overrideMap),\n );\n }\n\n return { ...widget, props: newProps };\n}\n\n/**\n * Resolve a page reference to a screen definition.\n *\n * @param ref - The page reference from navigation\n * @returns A ScreenDefinition or undefined if the template doesn't exist\n */\nfunction resolvePageReference(\n ref: Readonly<PageReference>,\n): ScreenDefinition | undefined {\n const template = PageTemplateRegistry.get(ref.page_template_id);\n if (!template) {\n console.warn(\n `Page template \"${ref.page_template_id}\" not found in registry`,\n );\n return undefined;\n }\n\n // Apply any overrides to the component tree\n // Spread to create mutable array for ScreenDefinition.component_tree\n const componentTree = ref.overrides\n ? applyOverrides(template.component_tree, ref.overrides)\n : [...template.component_tree];\n\n return {\n id: ref.screen_id,\n slug: template.slug,\n name: template.name,\n component_tree: componentTree,\n };\n}\n\n/**\n * Resolve all page references and local screens into a unified screen list.\n *\n * This function merges:\n * 1. Screen definitions from page_refs (shared templates)\n * 2. Local screen definitions (for backwards compatibility and custom screens)\n *\n * When a screen_id appears in both page_refs and screens, the local screen\n * takes precedence (allows local overrides of template pages).\n *\n * @param navigation - The navigation configuration\n * @returns A unified array of ScreenDefinition objects\n *\n * @example\n * ```ts\n * const navigation: Navigation = {\n * definition_id: 1,\n * id: 1,\n * name: \"Main Nav\",\n * navigation_items: [...],\n * screens: [\n * // Local custom screen\n * { id: 1, slug: \"home\", name: \"Home\", component_tree: [...] }\n * ],\n * page_refs: [\n * // Reference to shared messaging template\n * { page_template_id: \"core-messaging\", screen_id: 2 }\n * ],\n * };\n *\n * const allScreens = resolveNavigationPages(navigation);\n * // Returns: [home screen, messaging screen from template]\n * ```\n */\nexport function resolveNavigationPages(\n navigation: Readonly<Navigation>,\n): ScreenDefinition[] {\n // Start with local screens (these take precedence)\n const localScreenIds = new Set(navigation.screens.map((s) => s.id));\n const result: ScreenDefinition[] = [...navigation.screens];\n\n // Resolve page references (skip if local screen already exists with same ID)\n if (navigation.page_refs) {\n for (const ref of navigation.page_refs) {\n if (localScreenIds.has(ref.screen_id)) {\n // Local screen takes precedence\n continue;\n }\n\n const screen = resolvePageReference(ref);\n if (screen) {\n result.push(screen);\n }\n }\n }\n\n return result;\n}\n\n/**\n * Get all available page templates for use in navigation.\n *\n * @returns Array of page templates from the registry\n */\nexport function getAvailablePageTemplates() {\n return PageTemplateRegistry.listAll();\n}\n\n/**\n * Get core page templates that are required for basic functionality.\n *\n * @returns Array of core page templates\n */\nexport function getCorePageTemplates() {\n return PageTemplateRegistry.listCore();\n}\n\n/**\n * Get optional page templates that can be added to navigation.\n *\n * @returns Array of optional (non-core) page templates\n */\nexport function getOptionalPageTemplates() {\n return PageTemplateRegistry.listOptional();\n}\n\n/**\n * Check if a navigation has all required core pages.\n *\n * @param navigation - The navigation to check\n * @returns Object with validation result and missing page IDs\n */\nexport function validateNavigationPages(navigation: Readonly<Navigation>): {\n readonly valid: boolean;\n readonly missingCorePages: readonly string[];\n} {\n const corePages = PageTemplateRegistry.listCore();\n const referencedTemplateIds = new Set(\n navigation.page_refs?.map((ref) => ref.page_template_id) ?? [],\n );\n\n // Check which core pages are referenced\n const missingCorePages = corePages\n .filter((page) => !referencedTemplateIds.has(page.id))\n .map((page) => page.id);\n\n return {\n valid: missingCorePages.length === 0,\n missingCorePages,\n };\n}\n","import React, {\n createContext,\n useContext,\n useEffect,\n useMemo,\n useRef,\n} from \"react\";\nimport type { PageTemplate } from \"../types/page-template\";\nimport { PageTemplateRegistry } from \"../registries/page-template-registry\";\nimport { resolveNavigationPages } from \"../core/resolve-pages\";\nimport type { Navigation, ScreenDefinition } from \"../types\";\n\n/** Stable empty array for the default `templates` prop (avoids new reference each render) */\nconst EMPTY_TEMPLATES: readonly PageTemplate[] = [];\n\n/**\n * Context value for page template resolution.\n * All properties are readonly since context values should not be mutated by consumers.\n */\ninterface PageTemplateContextValue {\n /**\n * Resolve a navigation's page_refs and screens into a unified screen list\n */\n readonly resolvePages: (navigation: Navigation) => ScreenDefinition[];\n /**\n * Get all available page templates\n */\n readonly listTemplates: () => PageTemplate[];\n /**\n * Get a specific template by ID\n */\n readonly getTemplate: (id: string) => PageTemplate | undefined;\n /**\n * Check if a template exists\n */\n readonly hasTemplate: (id: string) => boolean;\n}\n\nconst PageTemplateContext = createContext<PageTemplateContextValue | null>(\n null,\n);\n\n/**\n * Props for PageTemplateProvider\n */\ninterface PageTemplateProviderProps {\n children: React.ReactNode;\n /**\n * Additional custom page templates to register.\n * These are registered when the provider mounts and unregistered when it unmounts.\n */\n templates?: readonly PageTemplate[];\n}\n\n/**\n * Provider for page template resolution.\n *\n * This provider:\n * 1. Registers any custom templates passed via props\n * 2. Provides methods for resolving navigation pages\n * 3. Cleans up custom templates on unmount\n *\n * @example\n * ```tsx\n * // With custom templates\n * const customTemplates: PageTemplate[] = [\n * {\n * id: 'custom-dashboard',\n * slug: 'dashboard',\n * name: 'Dashboard',\n * category: 'custom',\n * version: '1.0.0',\n * component_tree: [{ type: 'TextWidget', props: { text: 'Custom Dashboard' } }],\n * },\n * ];\n *\n * <PageTemplateProvider templates={customTemplates}>\n * <App />\n * </PageTemplateProvider>\n *\n * // Without custom templates (uses only core templates)\n * <PageTemplateProvider>\n * <App />\n * </PageTemplateProvider>\n * ```\n */\nexport function PageTemplateProvider({\n children,\n templates = EMPTY_TEMPLATES,\n}: PageTemplateProviderProps) {\n // Track which templates we registered so we can clean them up\n const registeredIds = useRef<string[]>([]);\n\n // Derive a stable primitive key from template IDs\n // (rerender-dependencies rule: use primitive dependencies in effects)\n const templateKey = templates.map((t) => t.id).join(\",\");\n\n // Register custom templates when template IDs change\n useEffect(() => {\n const registered: string[] = [];\n\n for (const template of templates) {\n if (!PageTemplateRegistry.has(template.id)) {\n try {\n PageTemplateRegistry.register(template);\n registered.push(template.id);\n } catch (error) {\n console.warn(\n `Failed to register page template \"${template.id}\":`,\n error,\n );\n }\n }\n }\n\n registeredIds.current = registered;\n\n // Cleanup when template IDs change or on unmount\n return () => {\n for (const id of registeredIds.current) {\n PageTemplateRegistry.unregister(id);\n }\n registeredIds.current = [];\n };\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [templateKey]);\n\n // Memoize context value to prevent unnecessary re-renders\n // Use `satisfies` to validate shape at compile time while preserving inference\n const contextValue = useMemo(\n () =>\n ({\n resolvePages: resolveNavigationPages,\n listTemplates: () => PageTemplateRegistry.listAll(),\n getTemplate: (id: string) => PageTemplateRegistry.get(id),\n hasTemplate: (id: string) => PageTemplateRegistry.has(id),\n }) satisfies PageTemplateContextValue,\n [],\n );\n\n return (\n <PageTemplateContext.Provider value={contextValue}>\n {children}\n </PageTemplateContext.Provider>\n );\n}\n\n/**\n * Hook to access page template functionality.\n *\n * @throws Error if used outside of PageTemplateProvider\n *\n * @example\n * ```tsx\n * function NavigationRenderer({ navigation }: { navigation: Navigation }) {\n * const { resolvePages } = usePageTemplates();\n * const screens = resolvePages(navigation);\n *\n * return (\n * <div>\n * {screens.map((screen) => (\n * <Screen key={screen.id} definition={screen} />\n * ))}\n * </div>\n * );\n * }\n * ```\n */\nexport function usePageTemplates(): PageTemplateContextValue {\n const context = useContext(PageTemplateContext);\n if (!context) {\n throw new Error(\n \"usePageTemplates must be used within a PageTemplateProvider\",\n );\n }\n return context;\n}\n\n/**\n * Hook to resolve navigation pages directly.\n * Convenience wrapper around usePageTemplates().resolvePages.\n *\n * @param navigation - The navigation to resolve\n * @returns Array of resolved screen definitions\n */\nexport function useResolvedPages(navigation: Navigation): ScreenDefinition[] {\n const { resolvePages } = usePageTemplates();\n return useMemo(() => resolvePages(navigation), [resolvePages, navigation]);\n}\n","import { useFluidContext } from \"../providers/FluidProvider\";\nimport type { FluidClient } from \"../client/fluid-client\";\n\n/**\n * Hook to access the Fluid API client\n *\n * @example\n * ```tsx\n * function ProductList() {\n * const api = useFluidApi();\n *\n * const { data: products } = useQuery({\n * queryKey: [\"products\"],\n * queryFn: () => api.products.list(),\n * });\n *\n * return <ul>{products?.map(p => <li key={p.id}>{p.name}</li>)}</ul>;\n * }\n * ```\n */\nexport function useFluidApi(): FluidClient {\n const { client } = useFluidContext();\n return client;\n}\n","import { useQuery, type UseQueryResult } from \"@tanstack/react-query\";\nimport { useFluidApi } from \"./use-fluid-api\";\nimport type { Profile } from \"../types/profile\";\n\n/**\n * Query key for profile data\n */\nexport const PROFILE_QUERY_KEY = [\"fluid\", \"profile\"] as const;\n\n/**\n * Hook to fetch the rep portal profile (themes, navigation, screens)\n *\n * @example\n * ```tsx\n * function Navigation() {\n * const { data: profile, isLoading } = useFluidProfile();\n *\n * if (isLoading) return <Spinner />;\n *\n * return (\n * <nav>\n * {profile?.navigation.navigation_items.map(item => (\n * <NavItem key={item.id} item={item} />\n * ))}\n * </nav>\n * );\n * }\n * ```\n */\nexport function useFluidProfile(): UseQueryResult<Profile> {\n const api = useFluidApi();\n\n return useQuery({\n queryKey: PROFILE_QUERY_KEY,\n queryFn: () => api.profile.get(),\n });\n}\n","import { useQuery, type UseQueryResult } from \"@tanstack/react-query\";\nimport { useMemo } from \"react\";\nimport { useFluidApi } from \"./use-fluid-api\";\nimport type { UserPermissions, PermissionAction } from \"../types/permissions\";\n\n/**\n * Query key for permissions data\n */\nexport const PERMISSIONS_QUERY_KEY = [\"fluid\", \"permissions\"] as const;\n\n/**\n * Result of useFluidPermissions hook\n */\nexport interface UseFluidPermissionsResult {\n /** Raw permissions query result */\n query: UseQueryResult<UserPermissions>;\n /** Permissions data (alias for query.data) */\n permissions: UserPermissions | undefined;\n /** Check if user has a specific permission */\n can: (resource: string, action?: PermissionAction) => boolean;\n /** Check if user is a super admin */\n isSuperAdmin: boolean;\n}\n\n/**\n * Hook to fetch and check user permissions\n *\n * @example\n * ```tsx\n * function TeamSettings() {\n * const { can, isSuperAdmin } = useFluidPermissions();\n *\n * if (!can(\"team\", \"manage\")) {\n * return <AccessDenied />;\n * }\n *\n * return <TeamSettingsForm canDelete={can(\"team\", \"delete\")} />;\n * }\n * ```\n */\nexport function useFluidPermissions(): UseFluidPermissionsResult {\n const api = useFluidApi();\n\n const query = useQuery({\n queryKey: PERMISSIONS_QUERY_KEY,\n queryFn: () => api.permissions.get(),\n });\n\n const permissions = query.data;\n\n // Memoize the can function to maintain referential stability\n const can = useMemo(() => {\n return (resource: string, action: PermissionAction = \"view\"): boolean => {\n if (!permissions) {\n return false;\n }\n\n // Super admins have all permissions\n if (permissions.is_super_admin) {\n return true;\n }\n\n const resourcePermissions = permissions.permissions[resource];\n if (!resourcePermissions) {\n return false;\n }\n\n return resourcePermissions[action] ?? false;\n };\n }, [permissions]);\n\n const isSuperAdmin = permissions?.is_super_admin ?? false;\n\n return {\n query,\n permissions,\n can,\n isSuperAdmin,\n };\n}\n","import { useThemeContext } from \"../providers/FluidThemeProvider\";\nimport type { Theme } from \"../types/theme\";\n\n/**\n * Result of useFluidTheme hook\n */\nexport interface UseFluidThemeResult {\n /** Currently active theme */\n currentTheme: Theme | null;\n /** Switch to a different theme */\n setTheme: (theme: Theme) => void;\n /** Switch between light and dark mode */\n setThemeMode: (mode: \"light\" | \"dark\") => void;\n /** Current theme mode (convenience accessor) */\n mode: \"light\" | \"dark\" | undefined;\n}\n\n/**\n * Hook to access and control theme settings\n *\n * @example\n * ```tsx\n * function ThemeSwitcher({ themes }: { themes: Theme[] }) {\n * const { currentTheme, setTheme, setThemeMode, mode } = useFluidTheme();\n *\n * return (\n * <div>\n * <select\n * value={currentTheme?.name}\n * onChange={(e) => {\n * const theme = themes.find(t => t.name === e.target.value);\n * if (theme) setTheme(theme);\n * }}\n * >\n * {themes.map(theme => (\n * <option key={theme.name} value={theme.name}>\n * {theme.name}\n * </option>\n * ))}\n * </select>\n *\n * <button onClick={() => setThemeMode(mode === \"dark\" ? \"light\" : \"dark\")}>\n * Toggle {mode === \"dark\" ? \"Light\" : \"Dark\"} Mode\n * </button>\n * </div>\n * );\n * }\n * ```\n */\nexport function useFluidTheme(): UseFluidThemeResult {\n const { currentTheme, setTheme, setThemeMode } = useThemeContext();\n\n return {\n currentTheme,\n setTheme,\n setThemeMode,\n mode: currentTheme?.mode,\n };\n}\n","import { useQuery, type UseQueryResult } from \"@tanstack/react-query\";\nimport { useFluidApi } from \"./use-fluid-api\";\nimport type { Rep } from \"../types/rep\";\n\n/**\n * Query key for current rep data\n */\nexport const CURRENT_REP_QUERY_KEY = [\"fluid\", \"currentRep\"] as const;\n\n/**\n * Hook to fetch the currently authenticated rep's profile\n *\n * @example\n * ```tsx\n * function RepHeader() {\n * const { data: rep, isLoading } = useCurrentRep();\n *\n * if (isLoading) return <Skeleton />;\n *\n * return (\n * <div>\n * <Avatar src={rep?.avatar_url} />\n * <span>{rep?.first_name} {rep?.last_name}</span>\n * </div>\n * );\n * }\n * ```\n */\nexport function useCurrentRep(): UseQueryResult<Rep> {\n const api = useFluidApi();\n\n return useQuery({\n queryKey: CURRENT_REP_QUERY_KEY,\n queryFn: () => api.reps.current(),\n });\n}\n","/**\n * useFluidAuth Hook\n *\n * Provides access to authentication state and utilities.\n * This is the primary hook for interacting with auth in components.\n */\n\nimport { useFluidAuthContext } from \"../providers/FluidAuthProvider\";\nimport type { FluidAuthContextValue } from \"../auth/types\";\n\n/**\n * Hook to access authentication state and utilities.\n *\n * Must be used within a `FluidAuthProvider`.\n *\n * @returns Authentication context with user info, loading state, and utilities\n * @throws Error if used outside FluidAuthProvider\n *\n * @example\n * ```tsx\n * function UserProfile() {\n * const { isAuthenticated, isLoading, user, clearAuth } = useFluidAuth();\n *\n * if (isLoading) {\n * return <Spinner />;\n * }\n *\n * if (!isAuthenticated) {\n * return <p>Please log in</p>;\n * }\n *\n * return (\n * <div>\n * <p>Welcome, {user.full_name}!</p>\n * <button onClick={clearAuth}>Log out</button>\n * </div>\n * );\n * }\n * ```\n */\nexport function useFluidAuth(): FluidAuthContextValue {\n return useFluidAuthContext();\n}\n","import type { CalendarEvent } from \"../hook-types\";\n\nconst now = new Date();\n\nfunction daysFromNow(days: number, hour: number, minute: number = 0): Date {\n const d = new Date(now);\n d.setDate(d.getDate() + days);\n d.setHours(hour, minute, 0, 0);\n return d;\n}\n\nexport const DEMO_CALENDAR_EVENTS: readonly CalendarEvent[] = [\n {\n id: 1,\n title: \"Team Standup\",\n description: { body: \"Daily sync with the sales team\" },\n color: \"#4f46e5\",\n start: daysFromNow(0, 9, 0).toISOString(),\n end: daysFromNow(0, 9, 30).toISOString(),\n active: true,\n status: \"confirmed\",\n },\n {\n id: 2,\n title: \"Client Review - Acme Corp\",\n description: { body: \"Quarterly business review with key accounts\" },\n color: \"#059669\",\n start: daysFromNow(2, 14, 0).toISOString(),\n end: daysFromNow(2, 15, 0).toISOString(),\n active: true,\n status: \"confirmed\",\n venue: \"Conference Room B\",\n },\n {\n id: 3,\n title: \"Product Training Webinar\",\n description: { body: \"New product line training for the field\" },\n color: \"#d97706\",\n start: daysFromNow(4, 11, 0).toISOString(),\n end: daysFromNow(4, 12, 30).toISOString(),\n active: true,\n status: \"confirmed\",\n url: \"https://example.com/webinar\",\n },\n {\n id: 4,\n title: \"Regional Conference\",\n description: { body: \"Annual West Coast regional conference\" },\n color: \"#dc2626\",\n start: daysFromNow(10, 8, 0).toISOString(),\n end: daysFromNow(12, 17, 0).toISOString(),\n active: true,\n status: \"confirmed\",\n venue: \"San Diego Convention Center\",\n isAllDay: true,\n },\n];\n","/**\n * Calendar events hook - stub implementation for SDK\n * In production, implement this hook to fetch from your API\n */\n\nimport type { QueryResult } from \"./hook-types\";\nimport type { CalendarEvent, CalendarEventDescription } from \"./hook-types\";\nimport { DEMO_CALENDAR_EVENTS } from \"./demo-data/calendar-events\";\n\n// Re-export types so external consumers are unaffected\nexport type { CalendarEvent, CalendarEventDescription };\n\n/**\n * Result type for useCalendarEvents hook.\n * Uses QueryResult<CalendarEvent[]> with default Error type.\n */\nexport type UseCalendarEventsResult = QueryResult<CalendarEvent[]>;\n\n/**\n * Hook to fetch calendar events.\n * This is a stub implementation - override with your own data fetching logic.\n */\nexport function useCalendarEvents(): UseCalendarEventsResult {\n // Demo data for first-run experience\n // In production, replace with actual data fetching\n return {\n data: [...DEMO_CALENDAR_EVENTS],\n isLoading: false,\n isError: false,\n };\n}\n","import type { Todo } from \"../hook-types\";\n\nconst now = new Date();\n\nfunction daysFromNow(days: number): string {\n const d = new Date(now);\n d.setDate(d.getDate() + days);\n return d.toISOString();\n}\n\nexport const DEMO_TODOS: readonly Todo[] = [\n {\n id: 1,\n body: \"Follow up with Sarah about Q2 order\",\n dueAt: daysFromNow(1),\n completedAt: null,\n createdAt: daysFromNow(-2),\n contactName: \"Sarah Johnson\",\n },\n {\n id: 2,\n body: \"Send pricing proposal to Acme Corp\",\n dueAt: daysFromNow(7),\n completedAt: null,\n createdAt: daysFromNow(-1),\n contactName: \"Mike Chen\",\n },\n {\n id: 3,\n body: \"Schedule onboarding call with new team member\",\n dueAt: daysFromNow(3),\n completedAt: null,\n createdAt: daysFromNow(0),\n contactName: \"Emily Rodriguez\",\n },\n {\n id: 4,\n body: \"Review and approve Q1 expense report\",\n dueAt: daysFromNow(-1),\n completedAt: daysFromNow(-1),\n createdAt: daysFromNow(-5),\n contactName: null,\n },\n {\n id: 5,\n body: \"Prepare presentation for Friday team meeting\",\n dueAt: daysFromNow(4),\n completedAt: daysFromNow(0),\n createdAt: daysFromNow(-3),\n contactName: null,\n },\n];\n","/**\n * Todos hook - stub implementation for SDK\n * In production, implement this hook to fetch from your API\n */\n\nimport type { QueryResult } from \"./hook-types\";\nimport type { Todo } from \"./hook-types\";\nimport { DEMO_TODOS } from \"./demo-data/todos\";\n\n// Re-export type so external consumers are unaffected\nexport type { Todo };\n\n/**\n * Result type for useTodos hook.\n * Uses QueryResult<Todo[]> with default Error type.\n */\nexport type UseTodosResult = QueryResult<Todo[]>;\n\n/**\n * Hook to fetch todo items.\n * This is a stub implementation - override with your own data fetching logic.\n */\nexport function useTodos(): UseTodosResult {\n // Demo data for first-run experience\n // In production, replace with actual data fetching\n return {\n data: [...DEMO_TODOS],\n isLoading: false,\n isError: false,\n };\n}\n","/**\n * Hook type utilities and type predicates.\n *\n * This module provides:\n * - Generic hook result types with default type parameters\n * - Type predicates for query state narrowing\n * - Reusable patterns for type-safe property access in hooks\n *\n * Following generics best practices:\n * - generics-default-type-parameters: Default E to Error for common case\n * - generics-type-predicates: Type predicates for result state narrowing\n * - generics-constrain-type-parameters: K extends keyof T for property access\n */\n\n// =============================================================================\n// Base Result Types with Default Type Parameters\n// =============================================================================\n\n/**\n * Base result type for query hooks with default error type.\n * Uses default type parameter for E (generics-default-type-parameters rule).\n *\n * @typeParam T - The data type\n * @typeParam E - The error type (defaults to Error)\n *\n * @example\n * // Error type defaults to Error\n * type UsersResult = QueryResult<User[]>;\n *\n * // Can override when needed\n * type CustomResult = QueryResult<User[], ApiError>;\n */\nexport interface QueryResult<T, E = Error> {\n readonly data: T;\n readonly isLoading: boolean;\n readonly isError: boolean;\n readonly error?: E | undefined;\n}\n\n/**\n * Result type for hooks that may not have data yet.\n * Extends QueryResult with nullable data.\n *\n * @typeParam T - The data type\n * @typeParam E - The error type (defaults to Error)\n */\nexport interface QueryResultNullable<T, E = Error> {\n readonly data: T | null | undefined;\n readonly isLoading: boolean;\n readonly isError: boolean;\n readonly error?: E | undefined;\n}\n\n/**\n * Result type for list/collection hooks with aggregates.\n *\n * @typeParam T - The item type in the array\n * @typeParam E - The error type (defaults to Error)\n */\nexport interface ListQueryResult<T, E = Error> extends QueryResult<T[], E> {\n readonly totalCount: number;\n}\n\n/**\n * Result type for list hooks with value aggregation (e.g., deals with total value).\n *\n * @typeParam T - The item type in the array\n * @typeParam E - The error type (defaults to Error)\n */\nexport interface ValueListQueryResult<T, E = Error>\n extends ListQueryResult<T, E> {\n readonly totalValue: number;\n}\n\n// =============================================================================\n// Type Predicates for Query State Narrowing\n// =============================================================================\n\n/**\n * Type predicate to check if a query result has successfully loaded data.\n * Narrows the data type from T | null | undefined to T.\n *\n * @example\n * const result = useContact(id);\n * if (hasData(result)) {\n * // TypeScript knows result.data is Contact, not Contact | null\n * console.log(result.data.name);\n * }\n */\nexport function hasData<T, E = Error>(\n result: QueryResultNullable<T, E>,\n): result is QueryResultNullable<T, E> & { readonly data: T } {\n return result.data != null && !result.isLoading && !result.isError;\n}\n\n/**\n * Type predicate to check if a query result is in loading state.\n * Useful for conditional rendering.\n *\n * @example\n * if (isLoading(result)) {\n * return <Spinner />;\n * }\n */\nexport function isLoading<T, E = Error>(\n result: QueryResult<T, E> | QueryResultNullable<T, E>,\n): boolean {\n return result.isLoading;\n}\n\n/**\n * Type predicate to check if a query result has an error.\n * Narrows to include the error property.\n *\n * @example\n * if (isErrorResult(result)) {\n * console.error(result.error); // error is E, not undefined\n * }\n */\nexport function isErrorResult<T, E = Error>(\n result: QueryResult<T, E> | QueryResultNullable<T, E>,\n): result is (QueryResult<T, E> | QueryResultNullable<T, E>) & {\n readonly isError: true;\n readonly error: E;\n} {\n return result.isError && result.error !== undefined;\n}\n\n/**\n * Type predicate to check if a query result is in idle state (not loading, no error, has data).\n *\n * @example\n * if (isIdle(result)) {\n * // Safe to access and render data\n * }\n */\nexport function isIdle<T, E = Error>(\n result: QueryResult<T, E> | QueryResultNullable<T, E>,\n): boolean {\n return !result.isLoading && !result.isError;\n}\n\n// =============================================================================\n// Generic Property Selector Pattern\n// =============================================================================\n\n/**\n * Type-safe property selector for hook results.\n * Uses K extends keyof T constraint (generics-function-constraints rule).\n *\n * @typeParam T - The data object type\n * @typeParam K - Key of T (constrained to actual keys)\n *\n * @example\n * const users = [{ name: \"Alice\", age: 30 }];\n * const names = selectProperty(users, \"name\"); // string[]\n * const ages = selectProperty(users, \"age\"); // number[]\n * selectProperty(users, \"invalid\"); // Error: \"invalid\" not in \"name\" | \"age\"\n */\nexport function selectProperty<T, K extends keyof T>(\n items: readonly T[],\n key: K,\n): T[K][] {\n return items.map((item) => item[key]);\n}\n\n/**\n * Type-safe property getter for a single item.\n * Returns undefined if item is null/undefined.\n *\n * @typeParam T - The data object type\n * @typeParam K - Key of T (constrained to actual keys)\n */\nexport function getProperty<T, K extends keyof T>(\n item: T | null | undefined,\n key: K,\n): T[K] | undefined {\n return item?.[key];\n}\n\n// =============================================================================\n// Hook Factory Types\n// =============================================================================\n\n/**\n * Generic type for hooks that fetch a single resource by ID.\n * Useful for creating consistent API across different resource types.\n *\n * @typeParam T - The resource type\n * @typeParam E - The error type (defaults to Error)\n */\nexport type UseSingleResourceHook<T, E = Error> = (\n id: string,\n) => QueryResultNullable<T, E>;\n\n/**\n * Generic type for hooks that fetch a list of resources with optional params.\n * Uses generics-default-type-parameters for the params type.\n *\n * @typeParam T - The item type\n * @typeParam P - The params type (defaults to empty object)\n * @typeParam E - The error type (defaults to Error)\n */\nexport type UseListResourceHook<\n T,\n P extends Record<string, unknown> = Record<string, never>,\n E = Error,\n> = (params?: P) => ListQueryResult<T, E>;\n\n/**\n * Transforms a nullable result to a non-nullable one if data exists.\n * Useful when you've already checked hasData().\n */\nexport type WithData<R extends QueryResultNullable<unknown>> =\n R extends QueryResultNullable<infer T, infer E>\n ? QueryResultNullable<T, E> & { readonly data: T }\n : never;\n\n// =============================================================================\n// Domain Types\n// Shared between hook files and demo-data files to avoid circular imports.\n// =============================================================================\n\n/**\n * Activity slug constants as a const object.\n * Derive the ActivitySlug type from this single source of truth.\n */\nexport const ACTIVITY_SLUGS = {\n abandonedCart: \"abandoned_cart\",\n announcements: \"announcements\",\n cartItemsAdded: \"cart_items_added\",\n commentReply: \"comment_reply\",\n directMessage: \"direct_message\",\n fantasyPoint: \"fantasy_point\",\n newLead: \"new_lead\",\n orderPlaced: \"order_placed\",\n pageViews: \"page_views\",\n pageViewsContact: \"page_views_contact\",\n tasks: \"tasks\",\n upcomingEvent: \"upcoming_event\",\n video: \"video\",\n videoComplete: \"video_complete\",\n videoCompleteContact: \"video_complete_contact\",\n videoContact: \"video_contact\",\n messageReceived: \"message_received\",\n messageSent: \"message_sent\",\n newCartItemsAdded: \"new_cart_items_added\",\n smartLinkClicked: \"smart_link_clicked\",\n reviewLeft: \"review_left\",\n} as const;\n\n/** Activity slug union type derived from ACTIVITY_SLUGS constant. */\nexport type ActivitySlug = (typeof ACTIVITY_SLUGS)[keyof typeof ACTIVITY_SLUGS];\n\n/** Type predicate to check if a string is a valid ActivitySlug. */\nexport function isActivitySlug(value: string): value is ActivitySlug {\n return Object.values(ACTIVITY_SLUGS).includes(value as ActivitySlug);\n}\n\n/** Transformed activity for display. */\nexport interface Activity {\n readonly id: number;\n readonly userName: string;\n readonly avatarUrl: string | null;\n readonly activityType: string;\n readonly targetName: string;\n readonly timestamp: string;\n readonly slug: ActivitySlug;\n}\n\n/** Description/rich text metadata for a calendar event. */\nexport interface CalendarEventDescription {\n readonly id?: number | null;\n readonly name?: string | null;\n readonly body?: string | null;\n readonly record_type?: string | null;\n readonly record_id?: number | null;\n readonly created_at?: string | null;\n readonly updated_at?: string | null;\n readonly locale?: string | null;\n}\n\n/** Calendar event data from the API. */\nexport interface CalendarEvent {\n readonly id: number;\n readonly title: string;\n readonly description?: CalendarEventDescription | null;\n readonly color?: string | null;\n readonly url?: string | null;\n readonly start: string;\n readonly end: string;\n readonly active?: boolean | null;\n readonly time_zone?: string | null;\n readonly status?: string | null;\n readonly image_url?: string | null;\n readonly images?: readonly unknown[] | null;\n readonly venue?: string | null;\n readonly countries?: readonly string[] | null;\n readonly hasTomorrow?: boolean | null;\n readonly hasYesterday?: boolean | null;\n readonly isAllDay?: boolean;\n}\n\n/** Catch up suggestion data from the API. */\nexport interface CatchUp {\n readonly id: number;\n readonly suggestion_title: string;\n}\n\n/** MySite data returned by the hook. */\nexport interface MySiteData {\n readonly url: string | null;\n readonly views: number;\n readonly leads: number;\n readonly userName: string;\n}\n\n/** Transformed todo for display. */\nexport interface Todo {\n readonly id: number;\n readonly body: string;\n readonly dueAt: string | null;\n readonly completedAt: string | null;\n readonly createdAt: string;\n readonly contactName: string | null;\n}\n","import type { Activity } from \"../hook-types\";\n\nconst now = new Date();\n\nfunction hoursAgo(hours: number): string {\n const d = new Date(now);\n d.setHours(d.getHours() - hours);\n return d.toISOString();\n}\nexport const DEMO_ACTIVITIES: readonly Activity[] = [\n {\n id: 1,\n userName: \"Sarah Johnson\",\n avatarUrl: null,\n activityType: \"New Order\",\n targetName: \"Wellness Starter Kit\",\n timestamp: hoursAgo(1),\n slug: \"order_placed\",\n },\n {\n id: 2,\n userName: \"Mike Chen\",\n avatarUrl: null,\n activityType: \"New Lead\",\n targetName: \"Referral from LinkedIn campaign\",\n timestamp: hoursAgo(3),\n slug: \"new_lead\",\n },\n {\n id: 3,\n userName: \"Emily Rodriguez\",\n avatarUrl: null,\n activityType: \"Page View\",\n targetName: \"Product Catalog\",\n timestamp: hoursAgo(5),\n slug: \"page_views\",\n },\n {\n id: 4,\n userName: \"David Park\",\n avatarUrl: null,\n activityType: \"Cart Items Added\",\n targetName: \"Premium Bundle (3 items)\",\n timestamp: hoursAgo(8),\n slug: \"cart_items_added\",\n },\n {\n id: 5,\n userName: \"Lisa Thompson\",\n avatarUrl: null,\n activityType: \"Video Watched\",\n targetName: \"Getting Started Tutorial\",\n timestamp: hoursAgo(12),\n slug: \"video_complete\",\n },\n {\n id: 6,\n userName: \"James Wilson\",\n avatarUrl: null,\n activityType: \"Message Received\",\n targetName: \"Question about shipping\",\n timestamp: hoursAgo(18),\n slug: \"message_received\",\n },\n {\n id: 7,\n userName: \"Rachel Kim\",\n avatarUrl: null,\n activityType: \"Smart Link Clicked\",\n targetName: \"Holiday Promo Link\",\n timestamp: hoursAgo(24),\n slug: \"smart_link_clicked\",\n },\n {\n id: 8,\n userName: \"Tom Martinez\",\n avatarUrl: null,\n activityType: \"Review Left\",\n targetName: \"Essential Oil Set - 5 stars\",\n timestamp: hoursAgo(36),\n slug: \"review_left\",\n },\n];\n","/**\n * Activities hook - stub implementation for SDK\n * In production, implement this hook to fetch from your API\n */\n\nimport type { QueryResult } from \"./hook-types\";\nimport {\n ACTIVITY_SLUGS,\n isActivitySlug,\n type Activity,\n type ActivitySlug,\n} from \"./hook-types\";\nimport { DEMO_ACTIVITIES } from \"./demo-data/activities\";\n\n// Re-export types and constants so external consumers are unaffected\nexport { ACTIVITY_SLUGS, isActivitySlug };\nexport type { Activity, ActivitySlug };\n\n/**\n * Result type for useActivities hook.\n * Uses QueryResult generic with Activity[] and default Error type.\n */\nexport type UseActivitiesResult = QueryResult<Activity[]>;\n\n/**\n * Hook to fetch recent activities.\n * This is a stub implementation - override with your own data fetching logic.\n */\nexport function useActivities(): UseActivitiesResult {\n // Demo data for first-run experience\n // In production, replace with actual data fetching\n return {\n data: [...DEMO_ACTIVITIES],\n isLoading: false,\n isError: false,\n };\n}\n","import type { CatchUp } from \"../hook-types\";\n\nexport const DEMO_CATCHUPS: readonly CatchUp[] = [\n {\n id: 1,\n suggestion_title: \"Sarah Johnson hasn't ordered in 30 days\",\n },\n {\n id: 2,\n suggestion_title: \"Mike Chen's subscription is expiring soon\",\n },\n {\n id: 3,\n suggestion_title: \"Emily Rodriguez left a cart with 3 items\",\n },\n];\n","/**\n * Catch ups hook - stub implementation for SDK\n * In production, implement this hook to fetch from your API\n */\n\nimport type { QueryResult } from \"./hook-types\";\nimport type { CatchUp } from \"./hook-types\";\nimport { DEMO_CATCHUPS } from \"./demo-data/catchups\";\n\n// Re-export type so external consumers are unaffected\nexport type { CatchUp };\n\n/**\n * Result type for useCatchUps hook.\n * Uses QueryResult<CatchUp[]> with default Error type.\n */\nexport type UseCatchUpsResult = QueryResult<CatchUp[]>;\n\n/**\n * Hook to fetch catch up items.\n * This is a stub implementation - override with your own data fetching logic.\n */\nexport function useCatchUps(): UseCatchUpsResult {\n // Demo data for first-run experience\n // In production, replace with actual data fetching\n return {\n data: [...DEMO_CATCHUPS],\n isLoading: false,\n isError: false,\n };\n}\n","import type { MySiteData } from \"../hook-types\";\n\nexport const DEMO_MYSITE: MySiteData = {\n url: \"https://my-portal.example.com\",\n views: 1243,\n leads: 37,\n userName: \"Demo User\",\n};\n","/**\n * MySite hook - stub implementation for SDK\n * In production, implement this hook to fetch from your API\n */\n\nimport type { QueryResultNullable } from \"./hook-types\";\nimport type { MySiteData } from \"./hook-types\";\nimport { DEMO_MYSITE } from \"./demo-data/mysite\";\n\n// Re-export type so external consumers are unaffected\nexport type { MySiteData };\n\n/**\n * Result type for useMySite hook.\n * Uses QueryResultNullable since MySite data may not be available.\n */\nexport type UseMySiteResult = QueryResultNullable<MySiteData>;\n\n/**\n * Hook to fetch MySite data.\n * This is a stub implementation - override with your own data fetching logic.\n */\nexport function useMySite(): UseMySiteResult {\n // Demo data for first-run experience\n // In production, replace with actual data fetching\n return {\n data: DEMO_MYSITE,\n isLoading: false,\n isError: false,\n };\n}\n","import type { Conversation, Message } from \"../../types/screen-types\";\n\nconst now = new Date();\n\nfunction hoursAgo(hours: number): string {\n const d = new Date(now);\n d.setHours(d.getHours() - hours);\n return d.toISOString();\n}\n\nfunction daysAgo(days: number): string {\n const d = new Date(now);\n d.setDate(d.getDate() - days);\n return d.toISOString();\n}\n\nexport const DEMO_CONVERSATIONS: readonly Conversation[] = [\n {\n id: \"conv-1\",\n title: \"Sarah Johnson\",\n participants: [\n { id: \"user-1\", name: \"You\", email: \"me@example.com\", isOnline: true },\n {\n id: \"user-2\",\n name: \"Sarah Johnson\",\n email: \"sarah.johnson@example.com\",\n isOnline: true,\n },\n ],\n lastMessage: {\n id: \"msg-1-3\",\n conversationId: \"conv-1\",\n senderId: \"user-2\",\n senderName: \"Sarah Johnson\",\n type: \"text\",\n content: \"Sounds great! I'll place the order by end of day.\",\n timestamp: hoursAgo(1),\n isRead: false,\n },\n unreadCount: 1,\n status: \"active\",\n createdAt: daysAgo(30),\n updatedAt: hoursAgo(1),\n },\n {\n id: \"conv-2\",\n title: \"Mike Chen\",\n participants: [\n { id: \"user-1\", name: \"You\", email: \"me@example.com\", isOnline: true },\n {\n id: \"user-3\",\n name: \"Mike Chen\",\n email: \"mike.chen@acmecorp.com\",\n isOnline: false,\n },\n ],\n lastMessage: {\n id: \"msg-2-2\",\n conversationId: \"conv-2\",\n senderId: \"user-1\",\n senderName: \"You\",\n type: \"text\",\n content:\n \"I've attached the updated pricing sheet. Let me know if you have any questions!\",\n timestamp: hoursAgo(5),\n isRead: true,\n },\n unreadCount: 0,\n status: \"active\",\n createdAt: daysAgo(14),\n updatedAt: hoursAgo(5),\n },\n {\n id: \"conv-3\",\n title: \"Team Updates\",\n participants: [\n { id: \"user-1\", name: \"You\", email: \"me@example.com\", isOnline: true },\n {\n id: \"user-4\",\n name: \"Emily Rodriguez\",\n email: \"emily.r@healthfirst.io\",\n },\n { id: \"user-5\", name: \"David Park\", email: \"david.park@email.com\" },\n ],\n lastMessage: {\n id: \"msg-3-4\",\n conversationId: \"conv-3\",\n senderId: \"user-4\",\n senderName: \"Emily Rodriguez\",\n type: \"text\",\n content:\n \"The new product samples arrived today. Will distribute to the team tomorrow.\",\n timestamp: daysAgo(1),\n isRead: true,\n },\n unreadCount: 0,\n status: \"active\",\n createdAt: daysAgo(60),\n updatedAt: daysAgo(1),\n },\n];\n\nexport const DEMO_MESSAGES: readonly Message[] = [\n {\n id: \"msg-1-1\",\n conversationId: \"conv-1\",\n senderId: \"user-1\",\n senderName: \"You\",\n type: \"text\",\n content:\n \"Hi Sarah! I wanted to follow up on the Wellness Starter Kit. We have a special promotion running this month.\",\n timestamp: hoursAgo(3),\n isRead: true,\n },\n {\n id: \"msg-1-2\",\n conversationId: \"conv-1\",\n senderId: \"user-2\",\n senderName: \"Sarah Johnson\",\n type: \"text\",\n content:\n \"That's perfect timing! I was just thinking about reordering. What's the promo?\",\n timestamp: hoursAgo(2),\n isRead: true,\n },\n {\n id: \"msg-1-3\",\n conversationId: \"conv-1\",\n senderId: \"user-2\",\n senderName: \"Sarah Johnson\",\n type: \"text\",\n content: \"Sounds great! I'll place the order by end of day.\",\n timestamp: hoursAgo(1),\n isRead: false,\n },\n];\n","/**\n * Conversations hooks - stub implementations for SDK\n * In production, implement these hooks to fetch from your API\n */\n\nimport type { Conversation, Message } from \"../types/screen-types\";\nimport type { QueryResult } from \"./hook-types\";\nimport { DEMO_CONVERSATIONS, DEMO_MESSAGES } from \"./demo-data/conversations\";\n\n// =============================================================================\n// useConversations Hook\n// =============================================================================\n\n/**\n * Result type for useConversations hook.\n * Uses QueryResult<Conversation[]> with default Error type.\n */\nexport type UseConversationsResult = QueryResult<Conversation[]>;\n\n/**\n * Hook to fetch all conversations.\n * This is a stub implementation - override with your own data fetching logic.\n *\n * @returns UseConversationsResult with empty data array\n *\n * @example\n * ```tsx\n * const { data: conversations, isLoading, isError } = useConversations();\n *\n * if (isLoading) return <Loading />;\n * if (isError) return <Error />;\n *\n * return conversations.map(conv => <ConversationItem key={conv.id} {...conv} />);\n * ```\n */\nexport function useConversations(): UseConversationsResult {\n // Demo data for first-run experience\n // In production, replace with actual data fetching\n return {\n data: [...DEMO_CONVERSATIONS],\n isLoading: false,\n isError: false,\n };\n}\n\n// =============================================================================\n// useConversationMessages Hook\n// =============================================================================\n\n/**\n * Result type for useConversationMessages hook.\n * Uses QueryResult<Message[]> with default Error type.\n */\nexport type UseConversationMessagesResult = QueryResult<Message[]>;\n\n/**\n * Hook to fetch messages for a specific conversation.\n * This is a stub implementation - override with your own data fetching logic.\n *\n * @param conversationId - The ID of the conversation to fetch messages for\n * @returns UseConversationMessagesResult with empty data array\n *\n * @example\n * ```tsx\n * const { data: messages, isLoading, isError } = useConversationMessages(conversationId);\n *\n * if (isLoading) return <Loading />;\n * if (isError) return <Error />;\n *\n * return messages.map(msg => <MessageBubble key={msg.id} {...msg} />);\n * ```\n */\nexport function useConversationMessages(\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n _conversationId: string,\n): UseConversationMessagesResult {\n // Demo data for first-run experience\n // In production, replace with actual data fetching using _conversationId\n return {\n data: [...DEMO_MESSAGES],\n isLoading: false,\n isError: false,\n };\n}\n","/**\n * Screen Types - Type definitions for core feature screens\n *\n * All status and type unions are derived from constants for single source of truth.\n * Use the constants (e.g., CONVERSATION_STATUSES.active) for type-safe comparisons.\n */\n\n// =============================================================================\n// Messaging Types\n// =============================================================================\n\n/**\n * Conversation status constant - single source of truth.\n */\nexport const CONVERSATION_STATUSES = {\n active: \"active\",\n archived: \"archived\",\n muted: \"muted\",\n} as const;\n\n/**\n * Union type derived from CONVERSATION_STATUSES constant.\n */\nexport type ConversationStatus =\n (typeof CONVERSATION_STATUSES)[keyof typeof CONVERSATION_STATUSES];\n\n/**\n * Message type constant - single source of truth.\n */\nexport const MESSAGE_TYPES = {\n text: \"text\",\n image: \"image\",\n file: \"file\",\n system: \"system\",\n} as const;\n\n/**\n * Union type derived from MESSAGE_TYPES constant.\n */\nexport type MessageType = (typeof MESSAGE_TYPES)[keyof typeof MESSAGE_TYPES];\n\nexport interface Participant {\n readonly id: string;\n readonly name: string;\n readonly email: string;\n readonly avatarUrl?: string;\n readonly isOnline?: boolean;\n}\n\n/**\n * Message attachment type - extracted for reusability and clarity.\n */\nexport interface MessageAttachment {\n readonly id: string;\n readonly name: string;\n readonly url: string;\n readonly type: string;\n readonly size?: number;\n}\n\nexport interface Message {\n readonly id: string;\n readonly conversationId: string;\n readonly senderId: string;\n readonly senderName: string;\n readonly senderAvatarUrl?: string;\n readonly type: MessageType;\n readonly content: string;\n readonly timestamp: string;\n readonly isRead: boolean;\n readonly attachments?: readonly MessageAttachment[];\n}\n\nexport interface Conversation {\n readonly id: string;\n readonly title: string;\n readonly participants: readonly Participant[];\n readonly lastMessage?: Message;\n readonly unreadCount: number;\n readonly status: ConversationStatus;\n readonly createdAt: string;\n readonly updatedAt: string;\n}\n\n// =============================================================================\n// Contacts Types\n// =============================================================================\n\n/**\n * Contact status constant - single source of truth.\n */\nexport const CONTACT_STATUSES = {\n active: \"active\",\n inactive: \"inactive\",\n lead: \"lead\",\n prospect: \"prospect\",\n} as const;\n\n/**\n * Union type derived from CONTACT_STATUSES constant.\n */\nexport type ContactStatus =\n (typeof CONTACT_STATUSES)[keyof typeof CONTACT_STATUSES];\n\n/**\n * Contact type constant - single source of truth.\n */\nexport const CONTACT_TYPES = {\n individual: \"individual\",\n company: \"company\",\n} as const;\n\n/**\n * Union type derived from CONTACT_TYPES constant.\n */\nexport type ContactType = (typeof CONTACT_TYPES)[keyof typeof CONTACT_TYPES];\n\nexport interface ContactAddress {\n readonly street?: string;\n readonly city?: string;\n readonly state?: string;\n readonly postalCode?: string;\n readonly country?: string;\n}\n\nexport interface Contact {\n readonly id: string;\n readonly firstName: string;\n readonly lastName: string;\n readonly email: string;\n readonly phone?: string;\n readonly company?: string;\n readonly jobTitle?: string;\n readonly avatarUrl?: string;\n readonly status: ContactStatus;\n readonly type: ContactType;\n readonly address?: ContactAddress;\n readonly tags?: readonly string[];\n readonly notes?: string;\n readonly createdAt: string;\n readonly updatedAt: string;\n}\n","import type { Contact } from \"../../types/screen-types\";\n\nconst now = new Date();\n\nfunction daysAgo(days: number): string {\n const d = new Date(now);\n d.setDate(d.getDate() - days);\n return d.toISOString();\n}\n\nexport const DEMO_CONTACTS: readonly Contact[] = [\n {\n id: \"contact-1\",\n firstName: \"Sarah\",\n lastName: \"Johnson\",\n email: \"sarah.johnson@example.com\",\n phone: \"+1 (555) 123-4567\",\n company: \"Wellness Works Inc.\",\n jobTitle: \"Purchasing Manager\",\n status: \"active\",\n type: \"individual\",\n tags: [\"VIP\", \"Repeat Buyer\"],\n createdAt: daysAgo(90),\n updatedAt: daysAgo(2),\n },\n {\n id: \"contact-2\",\n firstName: \"Mike\",\n lastName: \"Chen\",\n email: \"mike.chen@acmecorp.com\",\n phone: \"+1 (555) 234-5678\",\n company: \"Acme Corp\",\n jobTitle: \"Director of Operations\",\n status: \"active\",\n type: \"individual\",\n tags: [\"Enterprise\"],\n createdAt: daysAgo(60),\n updatedAt: daysAgo(5),\n },\n {\n id: \"contact-3\",\n firstName: \"Emily\",\n lastName: \"Rodriguez\",\n email: \"emily.r@healthfirst.io\",\n company: \"HealthFirst\",\n status: \"lead\",\n type: \"individual\",\n notes: \"Interested in bulk pricing for team orders\",\n createdAt: daysAgo(7),\n updatedAt: daysAgo(1),\n },\n {\n id: \"contact-4\",\n firstName: \"David\",\n lastName: \"Park\",\n email: \"david.park@email.com\",\n phone: \"+1 (555) 345-6789\",\n status: \"prospect\",\n type: \"individual\",\n tags: [\"Referral\"],\n createdAt: daysAgo(14),\n updatedAt: daysAgo(10),\n },\n {\n id: \"contact-5\",\n firstName: \"Lisa\",\n lastName: \"Thompson\",\n email: \"lisa.t@globalfit.com\",\n company: \"Global Fitness\",\n jobTitle: \"CEO\",\n status: \"active\",\n type: \"individual\",\n address: {\n city: \"Los Angeles\",\n state: \"CA\",\n country: \"US\",\n },\n createdAt: daysAgo(120),\n updatedAt: daysAgo(15),\n },\n {\n id: \"contact-6\",\n firstName: \"James\",\n lastName: \"Wilson\",\n email: \"jwilson@retired.net\",\n status: \"inactive\",\n type: \"individual\",\n notes: \"Moved out of area, no longer purchasing\",\n createdAt: daysAgo(200),\n updatedAt: daysAgo(45),\n },\n];\n\nexport const DEMO_CONTACT: Contact = DEMO_CONTACTS[0]!;\n","/**\n * Contacts hooks - stub implementation for SDK\n * In production, implement these hooks to fetch from your API\n */\n\nimport type { Contact, ContactStatus } from \"../types/screen-types\";\nimport { CONTACT_STATUSES } from \"../types/screen-types\";\nimport type { ListQueryResult, QueryResultNullable } from \"./hook-types\";\nimport { DEMO_CONTACTS, DEMO_CONTACT } from \"./demo-data/contacts\";\n\n/**\n * Type predicate to check if a status string is a valid ContactStatus.\n * Enables runtime validation with type narrowing.\n */\nexport function isContactStatus(value: string): value is ContactStatus {\n return Object.values(CONTACT_STATUSES).includes(value as ContactStatus);\n}\n\n/**\n * Parameters for filtering and paginating contacts.\n * Uses readonly properties and proper ContactStatus type for status.\n */\nexport interface UseContactsParams {\n /** Search query to filter contacts by name, email, or company */\n readonly search?: string;\n /** Filter contacts by status - uses ContactStatus union type for type safety */\n readonly status?: ContactStatus;\n /** Maximum number of contacts to return */\n readonly limit?: number;\n}\n\n/**\n * Result type for the useContacts hook.\n * Uses ListQueryResult<Contact> with totalCount and default Error type.\n */\nexport type UseContactsResult = ListQueryResult<Contact>;\n\n/**\n * Result type for the useContact hook.\n * Uses QueryResultNullable since a specific contact may not exist.\n */\nexport type UseContactResult = QueryResultNullable<Contact>;\n\n/**\n * Hook to fetch a list of contacts with optional filtering and pagination.\n * This is a stub implementation - override with your own data fetching logic.\n *\n * @param params - Optional parameters for filtering and pagination\n * @returns Object containing contacts data, loading state, error state, and total count\n *\n * @example\n * ```tsx\n * const { data: contacts, isLoading, totalCount } = useContacts({\n * search: 'john',\n * status: 'active',\n * limit: 20\n * });\n * ```\n */\nexport function useContacts(\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n _params?: UseContactsParams,\n): UseContactsResult {\n // Demo data for first-run experience\n // In production, replace with actual data fetching\n return {\n data: [...DEMO_CONTACTS],\n isLoading: false,\n isError: false,\n totalCount: DEMO_CONTACTS.length,\n };\n}\n\n/**\n * Hook to fetch a single contact by ID.\n * This is a stub implementation - override with your own data fetching logic.\n *\n * @param contactId - The unique identifier of the contact to fetch\n * @returns Object containing contact data, loading state, and error state\n *\n * @example\n * ```tsx\n * const { data: contact, isLoading, isError } = useContact('contact-123');\n * ```\n */\nexport function useContact(\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n _contactId: string,\n): UseContactResult {\n // Demo data for first-run experience\n // In production, replace with actual data fetching using _contactId\n return {\n data: DEMO_CONTACT,\n isLoading: false,\n isError: false,\n };\n}\n","/**\n * AuthError - Default Authentication Error Component\n *\n * Displayed when authentication fails. Can be customized or replaced\n * via the RequireAuth component's errorComponent prop.\n */\n\nimport type { ReactNode } from \"react\";\n\nexport interface AuthErrorProps {\n /** Error message to display */\n message?: string;\n /** Optional title */\n title?: string;\n /** Optional children for custom content */\n children?: ReactNode;\n}\n\n/**\n * Default authentication error component.\n *\n * Displays a simple error message when authentication fails.\n * Can be customized via props or replaced entirely in RequireAuth.\n *\n * @example\n * ```tsx\n * // Use with default message\n * <AuthError />\n *\n * // Use with custom message\n * <AuthError message=\"Session expired. Please log in again.\" />\n *\n * // Use with custom content\n * <AuthError>\n * <CustomLoginButton />\n * </AuthError>\n * ```\n */\nexport function AuthError({\n message = \"You need to be authenticated to view this content.\",\n title = \"Authentication Required\",\n children,\n}: AuthErrorProps) {\n return (\n <div\n style={{\n display: \"flex\",\n flexDirection: \"column\",\n alignItems: \"center\",\n justifyContent: \"center\",\n minHeight: \"100vh\",\n padding: \"2rem\",\n fontFamily:\n '-apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, \"Helvetica Neue\", Arial, sans-serif',\n backgroundColor: \"#f9fafb\",\n color: \"#111827\",\n }}\n >\n <div\n style={{\n maxWidth: \"400px\",\n textAlign: \"center\",\n padding: \"2rem\",\n backgroundColor: \"#ffffff\",\n borderRadius: \"0.75rem\",\n boxShadow:\n \"0 1px 3px 0 rgba(0, 0, 0, 0.1), 0 1px 2px 0 rgba(0, 0, 0, 0.06)\",\n }}\n >\n {/* Lock Icon */}\n <div\n style={{\n width: \"64px\",\n height: \"64px\",\n margin: \"0 auto 1.5rem\",\n backgroundColor: \"#fee2e2\",\n borderRadius: \"50%\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n }}\n >\n <svg\n width=\"32\"\n height=\"32\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"#dc2626\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <rect x=\"3\" y=\"11\" width=\"18\" height=\"11\" rx=\"2\" ry=\"2\" />\n <path d=\"M7 11V7a5 5 0 0 1 10 0v4\" />\n </svg>\n </div>\n\n <h1\n style={{\n fontSize: \"1.5rem\",\n fontWeight: \"600\",\n marginBottom: \"0.75rem\",\n color: \"#111827\",\n }}\n >\n {title}\n </h1>\n\n <p\n style={{\n fontSize: \"1rem\",\n color: \"#6b7280\",\n marginBottom: children ? \"1.5rem\" : \"0\",\n lineHeight: \"1.5\",\n }}\n >\n {message}\n </p>\n\n {children}\n </div>\n </div>\n );\n}\n\n/**\n * Simple loading spinner component for auth loading state.\n */\nexport function AuthLoading() {\n return (\n <div\n style={{\n display: \"flex\",\n flexDirection: \"column\",\n alignItems: \"center\",\n justifyContent: \"center\",\n minHeight: \"100vh\",\n fontFamily:\n '-apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, \"Helvetica Neue\", Arial, sans-serif',\n backgroundColor: \"#f9fafb\",\n }}\n >\n <div\n style={{\n width: \"40px\",\n height: \"40px\",\n border: \"3px solid #e5e7eb\",\n borderTopColor: \"#3b82f6\",\n borderRadius: \"50%\",\n animation: \"spin 1s linear infinite\",\n }}\n />\n <p\n style={{\n marginTop: \"1rem\",\n color: \"#6b7280\",\n fontSize: \"0.875rem\",\n }}\n >\n Authenticating...\n </p>\n <style>{`\n @keyframes spin {\n to { transform: rotate(360deg); }\n }\n `}</style>\n </div>\n );\n}\n","/**\n * RequireAuth - Route Protection Component\n *\n * Wraps content that requires authentication. Shows loading state\n * while checking auth, error component if not authenticated, or\n * children if authenticated.\n */\n\nimport type { ReactNode } from \"react\";\nimport { useFluidAuth } from \"../hooks/use-fluid-auth\";\nimport { AuthError, AuthLoading } from \"./AuthError\";\n\nexport interface RequireAuthProps {\n /** Content to render when authenticated */\n children: ReactNode;\n /** Component to show while checking authentication (default: AuthLoading) */\n fallback?: ReactNode;\n /** Component to show when not authenticated (default: AuthError) */\n errorComponent?: ReactNode;\n}\n\n/**\n * Component that protects content requiring authentication.\n *\n * **Important:** This provides UX-level protection only. It prevents\n * unauthenticated users from seeing the UI, but the real security\n * boundary is the server-side API. Client-side auth can always be\n * bypassed by modifying browser state.\n *\n * For defense-in-depth, configure `jwksUrl` in `FluidAuthConfig`\n * to enable client-side JWT signature verification.\n *\n * Shows different states based on auth status:\n * - Loading: Shows fallback (spinner by default)\n * - Not authenticated: Shows errorComponent (AuthError by default)\n * - Authenticated: Shows children\n *\n * @example\n * ```tsx\n * // Basic usage - shows default loading/error states\n * <RequireAuth>\n * <ProtectedContent />\n * </RequireAuth>\n *\n * // Custom loading state\n * <RequireAuth fallback={<CustomSpinner />}>\n * <ProtectedContent />\n * </RequireAuth>\n *\n * // Custom error component\n * <RequireAuth errorComponent={<LoginPrompt />}>\n * <ProtectedContent />\n * </RequireAuth>\n *\n * // Both custom\n * <RequireAuth\n * fallback={<SkeletonLoader />}\n * errorComponent={<RedirectToLogin />}\n * >\n * <Dashboard />\n * </RequireAuth>\n * ```\n */\nexport function RequireAuth({\n children,\n fallback = <AuthLoading />,\n errorComponent = <AuthError />,\n}: RequireAuthProps) {\n const { isAuthenticated, isLoading, error } = useFluidAuth();\n\n // Show loading state while checking authentication\n if (isLoading) {\n return <>{fallback}</>;\n }\n\n // Show error state if not authenticated\n if (!isAuthenticated || error) {\n return <>{errorComponent}</>;\n }\n\n // User is authenticated, render children\n return <>{children}</>;\n}\n","export * from \"@fluid-app/rep-core/theme\";\nexport type { Oklch, CoreColors, ThemeConfig } from \"@fluid-app/rep-core/theme\";\n","// Screen Components\nexport {\n MessagingScreen,\n messagingScreenPropertySchema,\n} from \"./MessagingScreen\";\nexport { ContactsScreen, contactsScreenPropertySchema } from \"./ContactsScreen\";\nexport { OrdersScreen, ordersScreenPropertySchema } from \"./OrdersScreen\";\nexport {\n CustomersScreen,\n customersScreenPropertySchema,\n} from \"./CustomersScreen\";\nexport { ProductsScreen, productsScreenPropertySchema } from \"./ProductsScreen\";\n\n// Re-export all property schemas as a lazy-loadable collection\nexport const screenPropertySchemas = {\n MessagingScreen: () =>\n import(\"./MessagingScreen\").then((m) => m.messagingScreenPropertySchema),\n ContactsScreen: () =>\n import(\"./ContactsScreen\").then((m) => m.contactsScreenPropertySchema),\n OrdersScreen: () =>\n import(\"./OrdersScreen\").then((m) => m.ordersScreenPropertySchema),\n CustomersScreen: () =>\n import(\"./CustomersScreen\").then((m) => m.customersScreenPropertySchema),\n ProductsScreen: () =>\n import(\"./ProductsScreen\").then((m) => m.productsScreenPropertySchema),\n};\n\n// Page Template Registration\nimport { PageTemplateRegistry } from \"../registries/page-template-registry\";\nimport { PAGE_CATEGORIES } from \"../types/page-template\";\n\n/**\n * Core page template IDs\n */\nexport const CORE_PAGE_IDS = {\n MESSAGING: \"core-messaging\",\n CONTACTS: \"core-contacts\",\n ORDERS: \"core-orders\",\n CUSTOMERS: \"core-customers\",\n PRODUCTS: \"core-products\",\n} as const;\n\n/**\n * Register core page templates.\n * These are automatically registered when the SDK is imported.\n */\nfunction registerCorePageTemplates(): void {\n // Messaging Screen\n PageTemplateRegistry.register({\n id: CORE_PAGE_IDS.MESSAGING,\n slug: \"messaging\",\n name: \"Messaging\",\n description: \"Messaging interface provided by Fluid Commerce\",\n category: PAGE_CATEGORIES.COMMUNICATION,\n tags: [\"messaging\", \"chat\", \"conversations\", \"communication\"],\n version: \"1.0.0\",\n isCore: true,\n component_tree: [\n {\n type: \"MessagingScreen\",\n id: \"messaging-screen-root\",\n props: {},\n },\n ],\n defaultProps: {},\n });\n\n // Contacts Screen\n PageTemplateRegistry.register({\n id: CORE_PAGE_IDS.CONTACTS,\n slug: \"contacts\",\n name: \"Contacts\",\n description: \"Contact management provided by Fluid Commerce\",\n category: PAGE_CATEGORIES.CORE,\n tags: [\"contacts\", \"people\", \"address-book\"],\n version: \"1.0.0\",\n isCore: true,\n component_tree: [\n {\n type: \"ContactsScreen\",\n id: \"contacts-screen-root\",\n props: {},\n },\n ],\n defaultProps: {},\n });\n\n // Orders Screen\n PageTemplateRegistry.register({\n id: CORE_PAGE_IDS.ORDERS,\n slug: \"orders\",\n name: \"Orders\",\n description: \"Order management provided by Fluid Commerce\",\n category: PAGE_CATEGORIES.CORE,\n tags: [\"orders\", \"commerce\", \"sales\"],\n version: \"1.0.0\",\n isCore: true,\n component_tree: [\n {\n type: \"OrdersScreen\",\n id: \"orders-screen-root\",\n props: {},\n },\n ],\n defaultProps: {},\n });\n\n // Customers Screen\n PageTemplateRegistry.register({\n id: CORE_PAGE_IDS.CUSTOMERS,\n slug: \"customers\",\n name: \"Customers\",\n description: \"Customer management provided by Fluid Commerce\",\n category: PAGE_CATEGORIES.CORE,\n tags: [\"customers\", \"people\", \"commerce\"],\n version: \"1.0.0\",\n isCore: true,\n component_tree: [\n {\n type: \"CustomersScreen\",\n id: \"customers-screen-root\",\n props: {},\n },\n ],\n defaultProps: {},\n });\n\n // Products Screen\n PageTemplateRegistry.register({\n id: CORE_PAGE_IDS.PRODUCTS,\n slug: \"products\",\n name: \"Products\",\n description: \"Product catalog provided by Fluid Commerce\",\n category: PAGE_CATEGORIES.CORE,\n tags: [\"products\", \"catalog\", \"commerce\"],\n version: \"1.0.0\",\n isCore: true,\n component_tree: [\n {\n type: \"ProductsScreen\",\n id: \"products-screen-root\",\n props: {},\n },\n ],\n defaultProps: {},\n });\n}\n\n// Auto-register core templates on module load\nregisterCorePageTemplates();\n"]}
|
package/package.json
ADDED
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@fluid-app/rep-sdk",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "SDK for building custom Fluid rep portals",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "./dist/index.cjs",
|
|
7
|
+
"module": "./dist/index.js",
|
|
8
|
+
"types": "./dist/index.d.ts",
|
|
9
|
+
"exports": {
|
|
10
|
+
".": {
|
|
11
|
+
"import": "./dist/index.js",
|
|
12
|
+
"require": "./dist/index.cjs",
|
|
13
|
+
"types": "./dist/index.d.ts"
|
|
14
|
+
}
|
|
15
|
+
},
|
|
16
|
+
"files": [
|
|
17
|
+
"dist"
|
|
18
|
+
],
|
|
19
|
+
"sideEffects": false,
|
|
20
|
+
"dependencies": {
|
|
21
|
+
"@radix-ui/react-slot": "^1.1.2",
|
|
22
|
+
"class-variance-authority": "^0.7.1",
|
|
23
|
+
"clsx": "^2.1.1",
|
|
24
|
+
"embla-carousel-react": "^8.6.0",
|
|
25
|
+
"jose": "^5.9.6",
|
|
26
|
+
"qrcode.react": "^4.2.0",
|
|
27
|
+
"recharts": "^2.15.4",
|
|
28
|
+
"tailwind-merge": "^3.0.2",
|
|
29
|
+
"@fluid-app/rep-core": "0.1.0",
|
|
30
|
+
"@fluid-app/rep-widgets": "0.1.0"
|
|
31
|
+
},
|
|
32
|
+
"peerDependencies": {
|
|
33
|
+
"@tanstack/react-query": ">=5.0.0",
|
|
34
|
+
"lucide-react": ">=0.400.0",
|
|
35
|
+
"react": ">=18.0.0"
|
|
36
|
+
},
|
|
37
|
+
"devDependencies": {
|
|
38
|
+
"@tanstack/react-query": "^5.90.11",
|
|
39
|
+
"@types/react": "^19.2.13",
|
|
40
|
+
"jsdom": "^28.0.0",
|
|
41
|
+
"lucide-react": "^0.475.0",
|
|
42
|
+
"react": "^19.2.4",
|
|
43
|
+
"tsup": "^8.4.0",
|
|
44
|
+
"typescript": "^5",
|
|
45
|
+
"vitest": "^4.0.18",
|
|
46
|
+
"@fluid-app/eslint-config": "0.0.0",
|
|
47
|
+
"@fluid-app/typescript-config": "0.0.0"
|
|
48
|
+
},
|
|
49
|
+
"scripts": {
|
|
50
|
+
"build": "tsup",
|
|
51
|
+
"dev": "tsup --watch",
|
|
52
|
+
"typecheck": "tsc --noEmit",
|
|
53
|
+
"lint": "eslint . --max-warnings 0",
|
|
54
|
+
"lint:fix": "eslint . --fix",
|
|
55
|
+
"test": "vitest run",
|
|
56
|
+
"test:watch": "vitest"
|
|
57
|
+
}
|
|
58
|
+
}
|