@oxyhq/services 5.18.2 → 5.18.3

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.
Files changed (148) hide show
  1. package/lib/commonjs/core/mixins/index.js +36 -13
  2. package/lib/commonjs/core/mixins/index.js.map +1 -1
  3. package/lib/commonjs/index.js +8 -0
  4. package/lib/commonjs/index.js.map +1 -1
  5. package/lib/commonjs/ui/client.js +170 -0
  6. package/lib/commonjs/ui/client.js.map +1 -0
  7. package/lib/commonjs/ui/components/profile/EditFieldModal.js +412 -0
  8. package/lib/commonjs/ui/components/profile/EditFieldModal.js.map +1 -0
  9. package/lib/commonjs/ui/context/OxyContext.js +63 -1
  10. package/lib/commonjs/ui/context/OxyContext.js.map +1 -1
  11. package/lib/commonjs/ui/hooks/useAuth.js +115 -0
  12. package/lib/commonjs/ui/hooks/useAuth.js.map +1 -0
  13. package/lib/commonjs/ui/hooks/useSettingToggle.js +7 -1
  14. package/lib/commonjs/ui/hooks/useSettingToggle.js.map +1 -1
  15. package/lib/commonjs/ui/hooks/useWebSSO.js +75 -0
  16. package/lib/commonjs/ui/hooks/useWebSSO.js.map +1 -0
  17. package/lib/commonjs/ui/index.js +17 -2
  18. package/lib/commonjs/ui/index.js.map +1 -1
  19. package/lib/commonjs/ui/screens/PrivacySettingsScreen.js +59 -65
  20. package/lib/commonjs/ui/screens/PrivacySettingsScreen.js.map +1 -1
  21. package/lib/commonjs/ui/screens/SearchSettingsScreen.js +38 -58
  22. package/lib/commonjs/ui/screens/SearchSettingsScreen.js.map +1 -1
  23. package/lib/commonjs/ui/server.js +105 -0
  24. package/lib/commonjs/ui/server.js.map +1 -0
  25. package/lib/commonjs/ui/utils/iconNames.js +133 -0
  26. package/lib/commonjs/ui/utils/iconNames.js.map +1 -0
  27. package/lib/commonjs/ui/utils/sessionHelpers.js +7 -0
  28. package/lib/commonjs/ui/utils/sessionHelpers.js.map +1 -1
  29. package/lib/commonjs/utils/requestUtils.js +4 -3
  30. package/lib/commonjs/utils/requestUtils.js.map +1 -1
  31. package/lib/module/core/mixins/index.js +36 -13
  32. package/lib/module/core/mixins/index.js.map +1 -1
  33. package/lib/module/index.js +2 -2
  34. package/lib/module/index.js.map +1 -1
  35. package/lib/module/ui/client.js +47 -0
  36. package/lib/module/ui/client.js.map +1 -0
  37. package/lib/module/ui/components/profile/EditFieldModal.js +406 -0
  38. package/lib/module/ui/components/profile/EditFieldModal.js.map +1 -0
  39. package/lib/module/ui/context/OxyContext.js +63 -1
  40. package/lib/module/ui/context/OxyContext.js.map +1 -1
  41. package/lib/module/ui/hooks/useAuth.js +106 -0
  42. package/lib/module/ui/hooks/useAuth.js.map +1 -0
  43. package/lib/module/ui/hooks/useSettingToggle.js +7 -1
  44. package/lib/module/ui/hooks/useSettingToggle.js.map +1 -1
  45. package/lib/module/ui/hooks/useWebSSO.js +71 -0
  46. package/lib/module/ui/hooks/useWebSSO.js.map +1 -0
  47. package/lib/module/ui/index.js +17 -3
  48. package/lib/module/ui/index.js.map +1 -1
  49. package/lib/module/ui/screens/PrivacySettingsScreen.js +59 -65
  50. package/lib/module/ui/screens/PrivacySettingsScreen.js.map +1 -1
  51. package/lib/module/ui/screens/SearchSettingsScreen.js +39 -59
  52. package/lib/module/ui/screens/SearchSettingsScreen.js.map +1 -1
  53. package/lib/module/ui/server.js +65 -0
  54. package/lib/module/ui/server.js.map +1 -0
  55. package/lib/module/ui/utils/iconNames.js +124 -0
  56. package/lib/module/ui/utils/iconNames.js.map +1 -0
  57. package/lib/module/ui/utils/sessionHelpers.js +7 -0
  58. package/lib/module/ui/utils/sessionHelpers.js.map +1 -1
  59. package/lib/module/utils/requestUtils.js +4 -2
  60. package/lib/module/utils/requestUtils.js.map +1 -1
  61. package/lib/typescript/commonjs/core/mixins/index.d.ts +18 -1115
  62. package/lib/typescript/commonjs/core/mixins/index.d.ts.map +1 -1
  63. package/lib/typescript/commonjs/index.d.ts +2 -0
  64. package/lib/typescript/commonjs/index.d.ts.map +1 -1
  65. package/lib/typescript/commonjs/ui/client.d.ts +33 -0
  66. package/lib/typescript/commonjs/ui/client.d.ts.map +1 -0
  67. package/lib/typescript/commonjs/ui/components/profile/EditFieldModal.d.ts +110 -0
  68. package/lib/typescript/commonjs/ui/components/profile/EditFieldModal.d.ts.map +1 -0
  69. package/lib/typescript/commonjs/ui/context/OxyContext.d.ts +3 -0
  70. package/lib/typescript/commonjs/ui/context/OxyContext.d.ts.map +1 -1
  71. package/lib/typescript/commonjs/ui/hooks/mutations/useAccountMutations.d.ts +3 -3
  72. package/lib/typescript/commonjs/ui/hooks/queries/useAccountQueries.d.ts +6 -10
  73. package/lib/typescript/commonjs/ui/hooks/queries/useAccountQueries.d.ts.map +1 -1
  74. package/lib/typescript/commonjs/ui/hooks/queries/useSecurityQueries.d.ts +1 -1
  75. package/lib/typescript/commonjs/ui/hooks/queries/useSecurityQueries.d.ts.map +1 -1
  76. package/lib/typescript/commonjs/ui/hooks/queries/useServicesQueries.d.ts +3 -5
  77. package/lib/typescript/commonjs/ui/hooks/queries/useServicesQueries.d.ts.map +1 -1
  78. package/lib/typescript/commonjs/ui/hooks/useAssets.d.ts +1 -1
  79. package/lib/typescript/commonjs/ui/hooks/useAuth.d.ts +69 -0
  80. package/lib/typescript/commonjs/ui/hooks/useAuth.d.ts.map +1 -0
  81. package/lib/typescript/commonjs/ui/hooks/useSettingToggle.d.ts +4 -2
  82. package/lib/typescript/commonjs/ui/hooks/useSettingToggle.d.ts.map +1 -1
  83. package/lib/typescript/commonjs/ui/hooks/useWebSSO.d.ts +34 -0
  84. package/lib/typescript/commonjs/ui/hooks/useWebSSO.d.ts.map +1 -0
  85. package/lib/typescript/commonjs/ui/index.d.ts +2 -2
  86. package/lib/typescript/commonjs/ui/index.d.ts.map +1 -1
  87. package/lib/typescript/commonjs/ui/screens/PrivacySettingsScreen.d.ts.map +1 -1
  88. package/lib/typescript/commonjs/ui/screens/SearchSettingsScreen.d.ts.map +1 -1
  89. package/lib/typescript/commonjs/ui/server.d.ts +43 -0
  90. package/lib/typescript/commonjs/ui/server.d.ts.map +1 -0
  91. package/lib/typescript/commonjs/ui/utils/iconNames.d.ts +112 -0
  92. package/lib/typescript/commonjs/ui/utils/iconNames.d.ts.map +1 -0
  93. package/lib/typescript/commonjs/ui/utils/sessionHelpers.d.ts +8 -3
  94. package/lib/typescript/commonjs/ui/utils/sessionHelpers.d.ts.map +1 -1
  95. package/lib/typescript/commonjs/utils/requestUtils.d.ts +3 -1
  96. package/lib/typescript/commonjs/utils/requestUtils.d.ts.map +1 -1
  97. package/lib/typescript/module/core/mixins/index.d.ts +18 -1115
  98. package/lib/typescript/module/core/mixins/index.d.ts.map +1 -1
  99. package/lib/typescript/module/index.d.ts +2 -0
  100. package/lib/typescript/module/index.d.ts.map +1 -1
  101. package/lib/typescript/module/ui/client.d.ts +33 -0
  102. package/lib/typescript/module/ui/client.d.ts.map +1 -0
  103. package/lib/typescript/module/ui/components/profile/EditFieldModal.d.ts +110 -0
  104. package/lib/typescript/module/ui/components/profile/EditFieldModal.d.ts.map +1 -0
  105. package/lib/typescript/module/ui/context/OxyContext.d.ts +3 -0
  106. package/lib/typescript/module/ui/context/OxyContext.d.ts.map +1 -1
  107. package/lib/typescript/module/ui/hooks/mutations/useAccountMutations.d.ts +3 -3
  108. package/lib/typescript/module/ui/hooks/queries/useAccountQueries.d.ts +6 -10
  109. package/lib/typescript/module/ui/hooks/queries/useAccountQueries.d.ts.map +1 -1
  110. package/lib/typescript/module/ui/hooks/queries/useSecurityQueries.d.ts +1 -1
  111. package/lib/typescript/module/ui/hooks/queries/useSecurityQueries.d.ts.map +1 -1
  112. package/lib/typescript/module/ui/hooks/queries/useServicesQueries.d.ts +3 -5
  113. package/lib/typescript/module/ui/hooks/queries/useServicesQueries.d.ts.map +1 -1
  114. package/lib/typescript/module/ui/hooks/useAssets.d.ts +1 -1
  115. package/lib/typescript/module/ui/hooks/useAuth.d.ts +69 -0
  116. package/lib/typescript/module/ui/hooks/useAuth.d.ts.map +1 -0
  117. package/lib/typescript/module/ui/hooks/useSettingToggle.d.ts +4 -2
  118. package/lib/typescript/module/ui/hooks/useSettingToggle.d.ts.map +1 -1
  119. package/lib/typescript/module/ui/hooks/useWebSSO.d.ts +34 -0
  120. package/lib/typescript/module/ui/hooks/useWebSSO.d.ts.map +1 -0
  121. package/lib/typescript/module/ui/index.d.ts +2 -2
  122. package/lib/typescript/module/ui/index.d.ts.map +1 -1
  123. package/lib/typescript/module/ui/screens/PrivacySettingsScreen.d.ts.map +1 -1
  124. package/lib/typescript/module/ui/screens/SearchSettingsScreen.d.ts.map +1 -1
  125. package/lib/typescript/module/ui/server.d.ts +43 -0
  126. package/lib/typescript/module/ui/server.d.ts.map +1 -0
  127. package/lib/typescript/module/ui/utils/iconNames.d.ts +112 -0
  128. package/lib/typescript/module/ui/utils/iconNames.d.ts.map +1 -0
  129. package/lib/typescript/module/ui/utils/sessionHelpers.d.ts +8 -3
  130. package/lib/typescript/module/ui/utils/sessionHelpers.d.ts.map +1 -1
  131. package/lib/typescript/module/utils/requestUtils.d.ts +3 -1
  132. package/lib/typescript/module/utils/requestUtils.d.ts.map +1 -1
  133. package/package.json +1 -1
  134. package/src/core/mixins/index.ts +57 -43
  135. package/src/index.ts +3 -1
  136. package/src/ui/client.ts +55 -0
  137. package/src/ui/components/profile/EditFieldModal.tsx +465 -0
  138. package/src/ui/context/OxyContext.tsx +69 -0
  139. package/src/ui/hooks/useAuth.ts +159 -0
  140. package/src/ui/hooks/useSettingToggle.ts +7 -3
  141. package/src/ui/hooks/useWebSSO.ts +93 -0
  142. package/src/ui/index.ts +17 -2
  143. package/src/ui/screens/PrivacySettingsScreen.tsx +54 -63
  144. package/src/ui/screens/SearchSettingsScreen.tsx +42 -64
  145. package/src/ui/server.ts +70 -0
  146. package/src/ui/utils/iconNames.ts +136 -0
  147. package/src/ui/utils/sessionHelpers.ts +10 -3
  148. package/src/utils/requestUtils.ts +10 -7
@@ -1,43 +1,67 @@
1
- import React, { useState, useCallback, useEffect } from 'react';
1
+ import React, { useState, useEffect } from 'react';
2
2
  import {
3
3
  View,
4
4
  StyleSheet,
5
5
  ScrollView,
6
6
  } from 'react-native';
7
7
  import type { BaseScreenProps } from '../types/navigation';
8
- import { toast } from '../../lib/sonner';
9
8
  import { Header, Section, LoadingState, SettingRow } from '../components';
10
9
  import { useI18n } from '../hooks/useI18n';
11
10
  import { useThemeStyles } from '../hooks/useThemeStyles';
11
+ import { useSettingToggles } from '../hooks/useSettingToggle';
12
12
  import { normalizeTheme } from '../utils/themeUtils';
13
13
  import { useOxy } from '../context/OxyContext';
14
+ import type { User } from '../../models/interfaces';
15
+
16
+ interface SearchSettings {
17
+ safeSearch: boolean;
18
+ searchPersonalization: boolean;
19
+ }
14
20
 
15
21
  const SearchSettingsScreen: React.FC<BaseScreenProps> = ({
16
22
  onClose,
17
23
  theme,
18
24
  goBack,
19
25
  }) => {
20
- // Use useOxy() hook for OxyContext values
21
26
  const { oxyServices, user } = useOxy();
22
27
  const { t } = useI18n();
23
- const [safeSearch, setSafeSearch] = useState(false);
24
- const [searchPersonalization, setSearchPersonalization] = useState(true);
25
28
  const [isLoading, setIsLoading] = useState(true);
26
- const [isSaving, setIsSaving] = useState(false);
27
29
 
28
- // Load settings
30
+ // Use the existing useSettingToggles hook for toggle management
31
+ const { values: settings, toggle, savingKeys, setValues } = useSettingToggles<SearchSettings>({
32
+ initialValues: { safeSearch: false, searchPersonalization: true },
33
+ onSave: async (key, value) => {
34
+ if (!user?.id || !oxyServices) return;
35
+
36
+ const fieldMap: Record<keyof SearchSettings, string> = {
37
+ safeSearch: 'autoFilter',
38
+ searchPersonalization: 'dataSharing',
39
+ };
40
+
41
+ await oxyServices.updateProfile({
42
+ privacySettings: {
43
+ [fieldMap[key]]: value,
44
+ },
45
+ });
46
+ },
47
+ errorMessage: (key) => t(`searchSettings.${key}.error`) || `Failed to update ${key}`,
48
+ });
49
+
50
+ const isSaving = savingKeys.size > 0;
51
+
52
+ // Load initial settings
29
53
  useEffect(() => {
30
54
  const loadSettings = async () => {
31
55
  try {
32
56
  setIsLoading(true);
33
57
  if (user?.id && oxyServices) {
34
- // Load from user's privacy settings
35
- const userData = await oxyServices.getCurrentUser();
36
- const privacySettings = (userData as any)?.privacySettings || {};
58
+ const userData = await oxyServices.getCurrentUser() as User & { privacySettings?: { autoFilter?: boolean; dataSharing?: boolean } };
59
+ const privacySettings = userData?.privacySettings || {};
37
60
 
38
- // SafeSearch is typically stored in privacySettings.autoFilter or a separate field
39
- setSafeSearch(privacySettings.autoFilter ?? false);
40
- setSearchPersonalization(privacySettings.dataSharing ?? true);
61
+ setValues({
62
+ safeSearch: privacySettings.autoFilter ?? false,
63
+ searchPersonalization: privacySettings.dataSharing ?? true,
64
+ });
41
65
  }
42
66
  } catch (error) {
43
67
  console.error('Failed to load search settings:', error);
@@ -47,53 +71,7 @@ const SearchSettingsScreen: React.FC<BaseScreenProps> = ({
47
71
  };
48
72
 
49
73
  loadSettings();
50
- }, [user?.id, oxyServices]);
51
-
52
- const handleSafeSearchToggle = useCallback(async (value: boolean) => {
53
- try {
54
- setIsSaving(true);
55
- setSafeSearch(value);
56
-
57
- if (user?.id && oxyServices) {
58
- // Update privacy settings
59
- await oxyServices.updateProfile({
60
- privacySettings: {
61
- autoFilter: value,
62
- },
63
- });
64
- toast.success(t('searchSettings.safeSearch.updated') || 'SafeSearch setting updated');
65
- }
66
- } catch (error) {
67
- console.error('Failed to update SafeSearch:', error);
68
- toast.error(t('searchSettings.safeSearch.error') || 'Failed to update SafeSearch');
69
- setSafeSearch(!value); // Revert on error
70
- } finally {
71
- setIsSaving(false);
72
- }
73
- }, [user?.id, oxyServices, t]);
74
-
75
- const handlePersonalizationToggle = useCallback(async (value: boolean) => {
76
- try {
77
- setIsSaving(true);
78
- setSearchPersonalization(value);
79
-
80
- if (user?.id && oxyServices) {
81
- // Update privacy settings
82
- await oxyServices.updateProfile({
83
- privacySettings: {
84
- dataSharing: value,
85
- },
86
- });
87
- toast.success(t('searchSettings.personalization.updated') || 'Search personalization updated');
88
- }
89
- } catch (error) {
90
- console.error('Failed to update personalization:', error);
91
- toast.error(t('searchSettings.personalization.error') || 'Failed to update personalization');
92
- setSearchPersonalization(!value); // Revert on error
93
- } finally {
94
- setIsSaving(false);
95
- }
96
- }, [user?.id, oxyServices, t]);
74
+ }, [user?.id, oxyServices, setValues]);
97
75
 
98
76
  const normalizedTheme = normalizeTheme(theme);
99
77
  const themeStyles = useThemeStyles(normalizedTheme);
@@ -128,8 +106,8 @@ const SearchSettingsScreen: React.FC<BaseScreenProps> = ({
128
106
  <SettingRow
129
107
  title={t('searchSettings.safeSearch.label') || 'Enable SafeSearch'}
130
108
  description={t('searchSettings.safeSearch.description') || 'Filter out explicit content from search results'}
131
- value={safeSearch}
132
- onValueChange={handleSafeSearchToggle}
109
+ value={settings.safeSearch}
110
+ onValueChange={() => toggle('safeSearch')}
133
111
  disabled={isSaving}
134
112
  textColor={themeStyles.textColor}
135
113
  mutedTextColor={themeStyles.mutedTextColor}
@@ -142,8 +120,8 @@ const SearchSettingsScreen: React.FC<BaseScreenProps> = ({
142
120
  <SettingRow
143
121
  title={t('searchSettings.personalization.label') || 'Personalized Search'}
144
122
  description={t('searchSettings.personalization.description') || 'Use your activity to improve search results'}
145
- value={searchPersonalization}
146
- onValueChange={handlePersonalizationToggle}
123
+ value={settings.searchPersonalization}
124
+ onValueChange={() => toggle('searchPersonalization')}
147
125
  disabled={isSaving}
148
126
  textColor={themeStyles.textColor}
149
127
  mutedTextColor={themeStyles.mutedTextColor}
@@ -0,0 +1,70 @@
1
+ /**
2
+ * Server-safe UI exports (noops)
3
+ *
4
+ * Import from this module for SSR environments where React components
5
+ * shouldn't be rendered on the server.
6
+ *
7
+ * @example
8
+ * import { OxyProvider, useOxy } from '@oxyhq/services/ui/server';
9
+ */
10
+
11
+ // Noop utilities
12
+ const noopComponent = () => null;
13
+ const noopHook = () => ({});
14
+ const noopStorageResult = { storage: null, isReady: false };
15
+
16
+ // Components (all render null)
17
+ export const OxyProvider = noopComponent;
18
+ export const OxySignInButton = noopComponent;
19
+ export const OxyLogo = noopComponent;
20
+ export const Avatar = noopComponent;
21
+ export const FollowButton = noopComponent;
22
+ export const OxyPayButton = noopComponent;
23
+ export const FontLoader = noopComponent;
24
+ export const setupFonts = () => {};
25
+ export const OxyIcon = noopComponent;
26
+
27
+ // Context
28
+ export const useOxy = noopHook;
29
+
30
+ // Hooks (all return empty objects)
31
+ export const useAuth = noopHook;
32
+ export const useFollow = noopHook;
33
+ export const useStorage = () => noopStorageResult;
34
+
35
+ // Screens (render null)
36
+ export const ProfileScreen = noopComponent;
37
+
38
+ // Stores (return empty objects)
39
+ export const useAuthStore = noopHook;
40
+ export const useAccountStore = noopHook;
41
+
42
+ // Styles (empty objects)
43
+ export const fontFamilies = {};
44
+ export const fontStyles = {};
45
+
46
+ // Toast (noop)
47
+ export const toast = Object.assign(
48
+ () => {},
49
+ {
50
+ success: () => {},
51
+ error: () => {},
52
+ info: () => {},
53
+ warning: () => {},
54
+ loading: () => {},
55
+ dismiss: () => {},
56
+ }
57
+ );
58
+
59
+ // Core re-exports (these work in both environments)
60
+ export { OxyServices } from '../core';
61
+ export type { User, LoginResponse, ApiError } from '../models/interfaces';
62
+
63
+ // Error handler utilities (pure functions work everywhere)
64
+ export {
65
+ handleAuthError,
66
+ isInvalidSessionError,
67
+ isTimeoutOrNetworkError,
68
+ extractErrorMessage,
69
+ } from './utils/errorHandlers';
70
+ export type { HandleAuthErrorOptions } from './utils/errorHandlers';
@@ -0,0 +1,136 @@
1
+ /**
2
+ * Type-safe icon name utilities
3
+ *
4
+ * Provides centralized, typed icon name mappings to eliminate `as any` casts
5
+ * when using dynamic icon names with @expo/vector-icons.
6
+ */
7
+
8
+ /**
9
+ * Profile field icons (MaterialCommunityIcons)
10
+ */
11
+ export const PROFILE_FIELD_ICONS = {
12
+ displayName: 'account-outline',
13
+ username: 'at',
14
+ email: 'email-outline',
15
+ bio: 'text-box-outline',
16
+ location: 'map-marker-outline',
17
+ links: 'link-variant',
18
+ website: 'web',
19
+ phone: 'phone-outline',
20
+ birthday: 'cake-variant-outline',
21
+ } as const;
22
+
23
+ export type ProfileFieldIconKey = keyof typeof PROFILE_FIELD_ICONS;
24
+
25
+ /**
26
+ * Get icon name for a profile field
27
+ */
28
+ export function getProfileFieldIcon(field: string): string {
29
+ return PROFILE_FIELD_ICONS[field as ProfileFieldIconKey] ?? 'account-outline';
30
+ }
31
+
32
+ /**
33
+ * Settings section icons (MaterialCommunityIcons)
34
+ */
35
+ export const SETTINGS_ICONS = {
36
+ account: 'account-cog-outline',
37
+ privacy: 'shield-account-outline',
38
+ security: 'lock-outline',
39
+ notifications: 'bell-outline',
40
+ language: 'translate',
41
+ appearance: 'palette-outline',
42
+ storage: 'folder-outline',
43
+ help: 'help-circle-outline',
44
+ about: 'information-outline',
45
+ logout: 'logout',
46
+ } as const;
47
+
48
+ export type SettingsIconKey = keyof typeof SETTINGS_ICONS;
49
+
50
+ /**
51
+ * Get icon name for a settings section
52
+ */
53
+ export function getSettingsIcon(section: string): string {
54
+ return SETTINGS_ICONS[section as SettingsIconKey] ?? 'cog-outline';
55
+ }
56
+
57
+ /**
58
+ * File type icons (MaterialCommunityIcons)
59
+ */
60
+ export const FILE_TYPE_ICONS = {
61
+ image: 'image-outline',
62
+ video: 'video-outline',
63
+ audio: 'music-note-outline',
64
+ document: 'file-document-outline',
65
+ pdf: 'file-pdf-box',
66
+ archive: 'folder-zip-outline',
67
+ code: 'code-tags',
68
+ spreadsheet: 'file-excel-outline',
69
+ presentation: 'file-presentation-outline',
70
+ text: 'file-document-edit-outline',
71
+ unknown: 'file-outline',
72
+ } as const;
73
+
74
+ export type FileTypeIconKey = keyof typeof FILE_TYPE_ICONS;
75
+
76
+ /**
77
+ * Get icon name for a file type
78
+ */
79
+ export function getFileTypeIcon(type: string): string {
80
+ return FILE_TYPE_ICONS[type as FileTypeIconKey] ?? FILE_TYPE_ICONS.unknown;
81
+ }
82
+
83
+ /**
84
+ * Action icons (Ionicons)
85
+ */
86
+ export const ACTION_ICONS = {
87
+ close: 'close',
88
+ back: 'chevron-back',
89
+ forward: 'chevron-forward',
90
+ add: 'add',
91
+ remove: 'remove',
92
+ delete: 'trash-outline',
93
+ edit: 'pencil-outline',
94
+ save: 'checkmark',
95
+ cancel: 'close',
96
+ search: 'search-outline',
97
+ filter: 'filter-outline',
98
+ sort: 'swap-vertical-outline',
99
+ refresh: 'refresh-outline',
100
+ share: 'share-outline',
101
+ copy: 'copy-outline',
102
+ download: 'download-outline',
103
+ upload: 'cloud-upload-outline',
104
+ } as const;
105
+
106
+ export type ActionIconKey = keyof typeof ACTION_ICONS;
107
+
108
+ /**
109
+ * Get icon name for an action
110
+ */
111
+ export function getActionIcon(action: string): string {
112
+ return ACTION_ICONS[action as ActionIconKey] ?? 'ellipsis-horizontal';
113
+ }
114
+
115
+ /**
116
+ * Status icons (Ionicons)
117
+ */
118
+ export const STATUS_ICONS = {
119
+ success: 'checkmark-circle',
120
+ error: 'alert-circle',
121
+ warning: 'warning',
122
+ info: 'information-circle',
123
+ loading: 'hourglass-outline',
124
+ pending: 'time-outline',
125
+ online: 'ellipse',
126
+ offline: 'ellipse-outline',
127
+ } as const;
128
+
129
+ export type StatusIconKey = keyof typeof STATUS_ICONS;
130
+
131
+ /**
132
+ * Get icon name for a status
133
+ */
134
+ export function getStatusIcon(status: string): string {
135
+ return STATUS_ICONS[status as StatusIconKey] ?? 'help-circle-outline';
136
+ }
@@ -1,4 +1,3 @@
1
- import type { OxyServices } from '../../core';
2
1
  import type { ClientSession } from '../../models/session';
3
2
 
4
3
  interface DeviceSession {
@@ -12,6 +11,14 @@ interface DeviceSession {
12
11
  isCurrent?: boolean;
13
12
  }
14
13
 
14
+ /**
15
+ * Service type for session helpers.
16
+ * Uses 'any' to work around TypeScript mixin composition type inference issues.
17
+ * The OxyServices class has these methods but TypeScript can't see them due to the mixin pattern.
18
+ */
19
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
20
+ type OxyServicesAny = any;
21
+
15
22
  export interface FetchSessionsWithFallbackOptions {
16
23
  fallbackDeviceId?: string;
17
24
  fallbackUserId?: string;
@@ -68,7 +75,7 @@ export const mapSessionsToClient = (
68
75
  * @param options - Optional fallback options
69
76
  */
70
77
  export const fetchSessionsWithFallback = async (
71
- oxyServices: Pick<OxyServices, 'getDeviceSessions' | 'getSessionsBySessionId'>,
78
+ oxyServices: OxyServicesAny,
72
79
  sessionId: string,
73
80
  {
74
81
  fallbackDeviceId,
@@ -97,7 +104,7 @@ export const fetchSessionsWithFallback = async (
97
104
  * @param options - Validation options
98
105
  */
99
106
  export const validateSessionBatch = async (
100
- oxyServices: Pick<OxyServices, 'validateSession'>,
107
+ oxyServices: OxyServicesAny,
101
108
  sessionIds: string[],
102
109
  { useHeaderValidation = true, maxConcurrency = 5 }: ValidateSessionBatchOptions = {},
103
110
  ): Promise<SessionValidationResult[]> => {
@@ -162,12 +162,15 @@ export class RequestQueue {
162
162
  }
163
163
  }
164
164
 
165
+ /** Log level type for SimpleLogger */
166
+ export type LogLevel = 'none' | 'error' | 'warn' | 'info' | 'debug';
167
+
165
168
  /**
166
169
  * Simple logger with level support
167
- *
170
+ *
168
171
  * Lightweight logger for HTTP clients and utilities.
169
172
  * For more advanced logging, use loggerUtils.ts
170
- *
173
+ *
171
174
  * @example
172
175
  * ```typescript
173
176
  * const logger = new SimpleLogger(true, 'debug');
@@ -178,7 +181,7 @@ export class RequestQueue {
178
181
  */
179
182
  export class SimpleLogger {
180
183
  private enabled: boolean;
181
- private level: 'none' | 'error' | 'warn' | 'info' | 'debug';
184
+ private level: LogLevel;
182
185
  private prefix: string;
183
186
 
184
187
  /**
@@ -189,17 +192,17 @@ export class SimpleLogger {
189
192
  */
190
193
  constructor(
191
194
  enabled: boolean = false,
192
- level: string = 'error',
195
+ level: LogLevel = 'error',
193
196
  prefix: string = ''
194
197
  ) {
195
198
  this.enabled = enabled;
196
- this.level = level as any;
199
+ this.level = level;
197
200
  this.prefix = prefix;
198
201
  }
199
202
 
200
- private shouldLog(level: string): boolean {
203
+ private shouldLog(level: LogLevel): boolean {
201
204
  if (!this.enabled || this.level === 'none') return false;
202
- const levels = ['none', 'error', 'warn', 'info', 'debug'];
205
+ const levels: LogLevel[] = ['none', 'error', 'warn', 'info', 'debug'];
203
206
  return levels.indexOf(level) <= levels.indexOf(this.level);
204
207
  }
205
208