@umituz/react-native-settings 5.3.51 → 5.3.53

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/account.d.ts CHANGED
@@ -1,26 +1,28 @@
1
1
  /**
2
2
  * @umituz/react-native-settings/account
3
3
  *
4
- * Subpath export for apps that use @umituz/react-native-auth.
5
- * Import auth-dependent hooks and components from here.
4
+ * NOTE: Auth has been removed from this application.
5
+ * This file now provides empty exports for backward compatibility.
6
6
  *
7
- * Usage:
8
- * import {
9
- * useSettingsScreenConfig,
10
- * AccountScreen,
11
- * ProfileSection,
12
- * } from '@umituz/react-native-settings/account';
13
- *
14
- * // Pass AccountScreen and ProfileSection as props to SettingsStackNavigator:
15
- * <SettingsStackNavigator
16
- * AccountScreenComponent={AccountScreen}
17
- * ProfileSectionComponent={ProfileSection}
18
- * ...
19
- * />
7
+ * Apps that use @umituz/react-native-auth should import directly from that package:
8
+ * import { AccountScreen, ProfileSection } from '@umituz/react-native-auth';
20
9
  */
21
- export { AccountScreen, ProfileSection } from "@umituz/react-native-auth";
22
- export { useAuth, useUserProfile, useAuthHandlers } from "@umituz/react-native-auth";
23
- export type { AccountScreenConfig } from "@umituz/react-native-auth";
10
+ export declare const AccountScreen: React.ComponentType<any> | null;
11
+ export declare const ProfileSection: React.ComponentType<any> | null;
12
+ export declare const useAuth: () => {
13
+ user: any;
14
+ loading: boolean;
15
+ isAuthReady: boolean;
16
+ isAnonymous: boolean;
17
+ };
18
+ export declare const useUserProfile: () => any;
19
+ export declare const useAuthHandlers: () => {
20
+ handleRatePress: () => Promise<void>;
21
+ handleSignOut: () => Promise<void>;
22
+ handleDeleteAccount: () => Promise<void>;
23
+ handleSignIn: () => Promise<void>;
24
+ };
25
+ export type AccountScreenConfig = any;
24
26
  export { useSettingsScreenConfig } from './presentation/hooks/useSettingsScreenConfig';
25
27
  export type { UseSettingsScreenConfigParams, SettingsScreenConfigResult, SettingsFeatures, } from './presentation/hooks/useSettingsScreenConfig';
26
28
  export type { AccountConfig } from './presentation/navigation/types';
@@ -2,6 +2,10 @@
2
2
  * useFeatureRequests Hook
3
3
  * Internal hook — fetches, votes, submits feature requests via Firestore
4
4
  * Works with both authenticated and anonymous users
5
+ *
6
+ * FIREBASE LAZY LOADING:
7
+ * Firebase is lazy-loaded to avoid hard dependency.
8
+ * If @umituz/react-native-firebase is not installed, features are disabled gracefully.
5
9
  */
6
10
  import type { FeatureRequestItem, VoteType } from "../domain/entities/FeatureRequestEntity";
7
11
  export interface UseFeatureRequestsResult {
@@ -2,8 +2,7 @@
2
2
  * useSettingsScreenConfig Hook
3
3
  *
4
4
  * One-stop hook for settings screen configuration.
5
- * Handles auth, feedback, and all settings config internally.
6
- * Apps pass subscription config from subscription package.
5
+ * Auth has been removed - this is a no-auth version.
7
6
  */
8
7
  import type { SettingsConfig, SettingsTranslations } from "../screens/types";
9
8
  import type { FeedbackFormData } from "../utils/config-creators";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@umituz/react-native-settings",
3
- "version": "5.3.51",
3
+ "version": "5.3.53",
4
4
  "description": "Complete settings hub for React Native apps - consolidated package with settings, localization, about, legal, appearance, feedback, FAQs, rating, and gamification",
5
5
  "main": "./src/index.ts",
6
6
  "types": "./dist/index.d.ts",
@@ -140,6 +140,9 @@
140
140
  "peerDependenciesMeta": {
141
141
  "@umituz/react-native-auth": {
142
142
  "optional": true
143
+ },
144
+ "@umituz/react-native-firebase": {
145
+ "optional": true
143
146
  }
144
147
  },
145
148
  "devDependencies": {
@@ -166,7 +169,6 @@
166
169
  "eslint-plugin-react-hooks": "^7.0.1",
167
170
  "eslint-plugin-react-native": "^5.0.0",
168
171
  "expo-apple-authentication": "^8.0.8",
169
- "expo-auth-session": "^5.0.0",
170
172
  "expo-clipboard": "^8.0.8",
171
173
  "expo-crypto": "^15.0.8",
172
174
  "expo-device": "~7.0.0",
package/src/account.ts CHANGED
@@ -1,34 +1,38 @@
1
1
  /**
2
2
  * @umituz/react-native-settings/account
3
3
  *
4
- * Subpath export for apps that use @umituz/react-native-auth.
5
- * Import auth-dependent hooks and components from here.
4
+ * NOTE: Auth has been removed from this application.
5
+ * This file now provides empty exports for backward compatibility.
6
6
  *
7
- * Usage:
8
- * import {
9
- * useSettingsScreenConfig,
10
- * AccountScreen,
11
- * ProfileSection,
12
- * } from '@umituz/react-native-settings/account';
13
- *
14
- * // Pass AccountScreen and ProfileSection as props to SettingsStackNavigator:
15
- * <SettingsStackNavigator
16
- * AccountScreenComponent={AccountScreen}
17
- * ProfileSectionComponent={ProfileSection}
18
- * ...
19
- * />
7
+ * Apps that use @umituz/react-native-auth should import directly from that package:
8
+ * import { AccountScreen, ProfileSection } from '@umituz/react-native-auth';
20
9
  */
21
10
 
22
- // Auth components - inject these into SettingsStackNavigator props
23
- export { AccountScreen, ProfileSection } from "@umituz/react-native-auth";
11
+ // Empty exports for backward compatibility
12
+ export const AccountScreen: React.ComponentType<any> | null = null;
13
+ export const ProfileSection: React.ComponentType<any> | null = null;
14
+
15
+ // Stub hooks that return default values
16
+ export const useAuth = () => ({
17
+ user: null,
18
+ loading: false,
19
+ isAuthReady: true,
20
+ isAnonymous: true,
21
+ });
22
+
23
+ export const useUserProfile = () => null;
24
24
 
25
- // Auth hooks (re-export for direct use if needed)
26
- export { useAuth, useUserProfile, useAuthHandlers } from "@umituz/react-native-auth";
25
+ export const useAuthHandlers = () => ({
26
+ handleRatePress: async () => {},
27
+ handleSignOut: async () => {},
28
+ handleDeleteAccount: async () => {},
29
+ handleSignIn: async () => {},
30
+ });
27
31
 
28
- // Auth types
29
- export type { AccountScreenConfig } from "@umituz/react-native-auth";
32
+ // Empty types
33
+ export type AccountScreenConfig = any;
30
34
 
31
- // Base hook (already handles auth internally via useAuth/useUserProfile/useAuthHandlers)
35
+ // Base hook (no auth version)
32
36
  export { useSettingsScreenConfig } from './presentation/hooks/useSettingsScreenConfig';
33
37
 
34
38
  // Re-export types
@@ -2,26 +2,16 @@
2
2
  * useFeatureRequests Hook
3
3
  * Internal hook — fetches, votes, submits feature requests via Firestore
4
4
  * Works with both authenticated and anonymous users
5
+ *
6
+ * FIREBASE LAZY LOADING:
7
+ * Firebase is lazy-loaded to avoid hard dependency.
8
+ * If @umituz/react-native-firebase is not installed, features are disabled gracefully.
5
9
  */
6
10
 
7
11
  import { useState, useEffect, useCallback, useRef } from "react";
8
12
  import { Platform } from "react-native";
9
- import { useAuth } from "@umituz/react-native-auth";
10
- import {
11
- collection,
12
- doc,
13
- getDocs,
14
- getDoc,
15
- setDoc,
16
- addDoc,
17
- updateDoc,
18
- deleteDoc,
19
- increment,
20
- orderBy,
21
- query,
22
- serverTimestamp,
23
- } from "firebase/firestore";
24
- import { getFirestore } from "@umituz/react-native-firebase";
13
+ import * as Crypto from "expo-crypto";
14
+ import AsyncStorage from "@react-native-async-storage/async-storage";
25
15
  import type {
26
16
  FeatureRequestItem,
27
17
  FeatureRequestStatus,
@@ -29,6 +19,84 @@ import type {
29
19
  } from "../domain/entities/FeatureRequestEntity";
30
20
 
31
21
  const COLLECTION = "feature_requests";
22
+ const ANONYMOUS_USER_ID_KEY = "@anonymous_user_id";
23
+
24
+ // Lazy-loaded Firebase modules
25
+ let firebaseModules: {
26
+ getFirestore: () => any;
27
+ collection: any;
28
+ doc: any;
29
+ getDocs: any;
30
+ getDoc: any;
31
+ setDoc: any;
32
+ addDoc: any;
33
+ updateDoc: any;
34
+ deleteDoc: any;
35
+ increment: any;
36
+ orderBy: any;
37
+ query: any;
38
+ serverTimestamp: any;
39
+ } | null = null;
40
+
41
+ function loadFirebase(): typeof firebaseModules {
42
+ if (firebaseModules !== null) return firebaseModules;
43
+
44
+ try {
45
+ // Lazy load Firebase only when needed
46
+ const firebaseModule = require("@umituz/react-native-firebase");
47
+ const firestoreModule = require("firebase/firestore");
48
+
49
+ firebaseModules = {
50
+ getFirestore: firebaseModule.getFirestore,
51
+ collection: firestoreModule.collection,
52
+ doc: firestoreModule.doc,
53
+ getDocs: firestoreModule.getDocs,
54
+ getDoc: firestoreModule.getDoc,
55
+ setDoc: firestoreModule.setDoc,
56
+ addDoc: firestoreModule.addDoc,
57
+ updateDoc: firestoreModule.updateDoc,
58
+ deleteDoc: firestoreModule.deleteDoc,
59
+ increment: firestoreModule.increment,
60
+ orderBy: firestoreModule.orderBy,
61
+ query: firestoreModule.query,
62
+ serverTimestamp: firestoreModule.serverTimestamp,
63
+ };
64
+ return firebaseModules;
65
+ } catch (error) {
66
+ // Firebase not installed - return null to disable features
67
+ if (__DEV__) {
68
+ console.warn(
69
+ "[useFeatureRequests] @umituz/react-native-firebase not installed. Feature requests disabled.",
70
+ );
71
+ }
72
+ firebaseModules = null;
73
+ return null;
74
+ }
75
+ }
76
+
77
+ /**
78
+ * Get or create a persistent anonymous user ID
79
+ */
80
+ async function getAnonymousUserId(): Promise<string> {
81
+ try {
82
+ const existingId = await AsyncStorage.getItem(ANONYMOUS_USER_ID_KEY);
83
+ if (existingId) return existingId;
84
+
85
+ // Create a new anonymous ID using device UUID
86
+ const randomBytes = await Crypto.getRandomBytesAsync(16);
87
+ const newId = Array.from(randomBytes)
88
+ .map((b) => b.toString(16).padStart(2, "0"))
89
+ .join("");
90
+
91
+ await AsyncStorage.setItem(ANONYMOUS_USER_ID_KEY, newId);
92
+ return newId;
93
+ } catch (error) {
94
+ // Fallback to timestamp-based ID if crypto fails
95
+ const fallbackId = `anon_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
96
+ await AsyncStorage.setItem(ANONYMOUS_USER_ID_KEY, fallbackId);
97
+ return fallbackId;
98
+ }
99
+ }
32
100
 
33
101
  export interface UseFeatureRequestsResult {
34
102
  requests: FeatureRequestItem[];
@@ -41,13 +109,19 @@ export interface UseFeatureRequestsResult {
41
109
  }
42
110
 
43
111
  export function useFeatureRequests(): UseFeatureRequestsResult {
44
- const { user } = useAuth();
45
- const userId = user?.uid ?? null;
112
+ const [userId, setUserId] = useState<string | null>(null);
46
113
 
47
114
  const [requests, setRequests] = useState<FeatureRequestItem[]>([]);
48
115
  const [userVotes, setUserVotes] = useState<Record<string, VoteType>>({});
49
116
  const [isLoading, setIsLoading] = useState(true);
50
117
 
118
+ // Initialize anonymous user ID
119
+ useEffect(() => {
120
+ getAnonymousUserId().then((id) => {
121
+ setUserId(id);
122
+ });
123
+ }, []);
124
+
51
125
  // Ref to avoid stale closure in vote()
52
126
  const userVotesRef = useRef(userVotes);
53
127
  userVotesRef.current = userVotes;
@@ -56,7 +130,13 @@ export function useFeatureRequests(): UseFeatureRequestsResult {
56
130
  const votingInProgress = useRef(new Set<string>());
57
131
 
58
132
  const fetchAll = useCallback(async () => {
59
- const db = getFirestore();
133
+ const fb = loadFirebase();
134
+ if (!fb) {
135
+ setIsLoading(false);
136
+ return;
137
+ }
138
+
139
+ const db = fb.getFirestore();
60
140
  if (!db) {
61
141
  setIsLoading(false);
62
142
  return;
@@ -65,8 +145,8 @@ export function useFeatureRequests(): UseFeatureRequestsResult {
65
145
  try {
66
146
  setIsLoading(true);
67
147
 
68
- const q = query(collection(db, COLLECTION), orderBy("votes", "desc"));
69
- const snapshot = await getDocs(q);
148
+ const q = fb.query(fb.collection(db, COLLECTION), fb.orderBy("votes", "desc"));
149
+ const snapshot = await fb.getDocs(q);
70
150
 
71
151
  const items: FeatureRequestItem[] = snapshot.docs.map((d) => {
72
152
  const data = d.data();
@@ -91,8 +171,8 @@ export function useFeatureRequests(): UseFeatureRequestsResult {
91
171
  // Fetch user votes in parallel (not N+1 sequential)
92
172
  if (userId && snapshot.docs.length > 0) {
93
173
  const votePromises = snapshot.docs.map(async (reqDoc) => {
94
- const voteRef = doc(db, COLLECTION, reqDoc.id, "votes", userId);
95
- const voteSnap = await getDoc(voteRef);
174
+ const voteRef = fb.doc(db, COLLECTION, reqDoc.id, "votes", userId);
175
+ const voteSnap = await fb.getDoc(voteRef);
96
176
  if (voteSnap.exists()) {
97
177
  return [reqDoc.id, voteSnap.data().type as VoteType] as const;
98
178
  }
@@ -120,13 +200,14 @@ export function useFeatureRequests(): UseFeatureRequestsResult {
120
200
  }, [fetchAll]);
121
201
 
122
202
  const vote = useCallback(async (requestId: string, type: VoteType) => {
123
- if (!userId) return;
203
+ const fb = loadFirebase();
204
+ if (!fb || !userId) return;
124
205
 
125
206
  // Prevent rapid double-tap on the same request
126
207
  if (votingInProgress.current.has(requestId)) return;
127
208
  votingInProgress.current.add(requestId);
128
209
 
129
- const db = getFirestore();
210
+ const db = fb.getFirestore();
130
211
  if (!db) {
131
212
  votingInProgress.current.delete(requestId);
132
213
  return;
@@ -154,22 +235,22 @@ export function useFeatureRequests(): UseFeatureRequestsResult {
154
235
  );
155
236
 
156
237
  try {
157
- const voteRef = doc(db, COLLECTION, requestId, "votes", userId);
158
- const requestRef = doc(db, COLLECTION, requestId);
159
- const existing = await getDoc(voteRef);
238
+ const voteRef = fb.doc(db, COLLECTION, requestId, "votes", userId);
239
+ const requestRef = fb.doc(db, COLLECTION, requestId);
240
+ const existing = await fb.getDoc(voteRef);
160
241
 
161
242
  if (existing.exists()) {
162
243
  const prev = existing.data().type as VoteType;
163
244
  if (prev === type) {
164
- await deleteDoc(voteRef);
165
- await updateDoc(requestRef, { votes: increment(type === "up" ? -1 : 1) });
245
+ await fb.deleteDoc(voteRef);
246
+ await fb.updateDoc(requestRef, { votes: fb.increment(type === "up" ? -1 : 1) });
166
247
  } else {
167
- await setDoc(voteRef, { type, votedAt: serverTimestamp() });
168
- await updateDoc(requestRef, { votes: increment(type === "up" ? 2 : -2) });
248
+ await fb.setDoc(voteRef, { type, votedAt: fb.serverTimestamp() });
249
+ await fb.updateDoc(requestRef, { votes: fb.increment(type === "up" ? 2 : -2) });
169
250
  }
170
251
  } else {
171
- await setDoc(voteRef, { type, votedAt: serverTimestamp() });
172
- await updateDoc(requestRef, { votes: increment(type === "up" ? 1 : -1) });
252
+ await fb.setDoc(voteRef, { type, votedAt: fb.serverTimestamp() });
253
+ await fb.updateDoc(requestRef, { votes: fb.increment(type === "up" ? 1 : -1) });
173
254
  }
174
255
  } catch (error) {
175
256
  if (__DEV__) console.warn("[useFeatureRequests] Vote failed:", error);
@@ -186,12 +267,14 @@ export function useFeatureRequests(): UseFeatureRequestsResult {
186
267
  }, [userId, fetchAll]);
187
268
 
188
269
  const submitRequest = useCallback(async (data: { title: string; description: string; type: string; rating?: number }) => {
189
- const db = getFirestore();
270
+ const fb = loadFirebase();
271
+ if (!fb) throw new Error("Firestore not available");
272
+ const db = fb.getFirestore();
190
273
  if (!db) throw new Error("Firestore not available");
191
- if (!userId) throw new Error("User not authenticated");
274
+ if (!userId) throw new Error("User ID not available");
192
275
 
193
276
  // Create the feature request
194
- const docRef = await addDoc(collection(db, COLLECTION), {
277
+ const docRef = await fb.addDoc(fb.collection(db, COLLECTION), {
195
278
  title: data.title,
196
279
  description: data.description,
197
280
  type: data.type || "feature_request",
@@ -199,21 +282,21 @@ export function useFeatureRequests(): UseFeatureRequestsResult {
199
282
  votes: 1,
200
283
  commentCount: 0,
201
284
  createdBy: userId,
202
- isAnonymous: user?.isAnonymous ?? false,
285
+ isAnonymous: true,
203
286
  platform: Platform.OS,
204
287
  rating: data.rating ?? null,
205
- createdAt: serverTimestamp(),
206
- updatedAt: serverTimestamp(),
288
+ createdAt: fb.serverTimestamp(),
289
+ updatedAt: fb.serverTimestamp(),
207
290
  });
208
291
 
209
292
  // Create the creator's upvote doc so votes count matches reality
210
- await setDoc(doc(db, COLLECTION, docRef.id, "votes", userId), {
293
+ await fb.setDoc(fb.doc(db, COLLECTION, docRef.id, "votes", userId), {
211
294
  type: "up" as VoteType,
212
- votedAt: serverTimestamp(),
295
+ votedAt: fb.serverTimestamp(),
213
296
  });
214
297
 
215
298
  await fetchAll();
216
- }, [userId, user?.isAnonymous, fetchAll]);
299
+ }, [userId, fetchAll]);
217
300
 
218
301
  return { requests, userVotes, isLoading, vote, submitRequest, reload: fetchAll, userId };
219
302
  }
@@ -2,12 +2,10 @@
2
2
  * useSettingsScreenConfig Hook
3
3
  *
4
4
  * One-stop hook for settings screen configuration.
5
- * Handles auth, feedback, and all settings config internally.
6
- * Apps pass subscription config from subscription package.
5
+ * Auth has been removed - this is a no-auth version.
7
6
  */
8
7
 
9
8
  import { useMemo } from "react";
10
- import { useAuth, useUserProfile, useAuthHandlers } from "@umituz/react-native-auth";
11
9
  import { createUserProfileDisplay } from "../utils/userProfileUtils";
12
10
  import { createAccountConfig, type AccountTranslations } from "../utils/accountConfigUtils";
13
11
  import { useSettingsConfigFactory } from "../utils/settingsConfigFactory";
@@ -67,12 +65,27 @@ export const useSettingsScreenConfig = (
67
65
  subscription: showSubscription = true,
68
66
  } = features;
69
67
 
70
- const { user, loading, isAuthReady } = useAuth();
71
- const userProfileData = useUserProfile({});
68
+ // No-auth version - always ready
69
+ const loading = false;
70
+ const isAuthReady = true;
72
71
 
73
- // Use centralized auth handlers
74
- const { handleRatePress, handleSignOut, handleDeleteAccount, handleSignIn } =
75
- useAuthHandlers(appInfo, translations?.errors);
72
+ // Default handlers (no-ops for no-auth version)
73
+ const handleRatePress = useMemo(() => async () => {
74
+ // Default rate behavior - could be implemented with expo-store-review
75
+ console.warn("[useSettingsScreenConfig] Rate press handler not implemented in no-auth version");
76
+ }, []);
77
+
78
+ const handleSignOut = useMemo(() => async () => {
79
+ // No-op in no-auth version
80
+ }, []);
81
+
82
+ const handleDeleteAccount = useMemo(() => async () => {
83
+ // No-op in no-auth version
84
+ }, []);
85
+
86
+ const handleSignIn = useMemo(() => async () => {
87
+ // No-op in no-auth version
88
+ }, []);
76
89
 
77
90
  // Use settings config factory
78
91
  const baseSettingsConfig = useSettingsConfigFactory({
@@ -133,30 +146,24 @@ export const useSettingsScreenConfig = (
133
146
  return config;
134
147
  }, [baseSettingsConfig, translations]);
135
148
 
149
+ // Empty user profile (no-auth version)
136
150
  const userProfile = useMemo(() => createUserProfileDisplay({
137
- profileData: userProfileData,
151
+ profileData: null,
138
152
  onSignIn: handleSignIn,
139
- }), [userProfileData, handleSignIn]);
153
+ }), [handleSignIn]);
140
154
 
155
+ // Minimal account config (no-auth version)
141
156
  const accountConfig = useMemo(() => createAccountConfig({
142
- displayName: userProfileData?.displayName || user?.displayName || undefined,
143
- userId: userProfileData?.userId || user?.uid || undefined,
144
- photoURL: user?.photoURL || undefined,
145
- isAnonymous: user?.isAnonymous,
146
- avatarUrl: userProfileData?.avatarUrl,
157
+ displayName: undefined,
158
+ userId: undefined,
159
+ photoURL: undefined,
160
+ isAnonymous: true,
161
+ avatarUrl: undefined,
147
162
  onSignIn: handleSignIn,
148
163
  onLogout: handleSignOut,
149
164
  onDeleteAccount: handleDeleteAccount,
150
- translations: (translations?.account?.logout &&
151
- translations?.account?.deleteAccount &&
152
- translations?.account?.logoutConfirmTitle &&
153
- translations?.account?.logoutConfirmMessage &&
154
- translations?.account?.deleteConfirmTitle &&
155
- translations?.account?.deleteConfirmMessage &&
156
- translations?.account?.cancel)
157
- ? translations.account as AccountTranslations
158
- : undefined,
159
- }), [user, userProfileData, handleSignIn, handleSignOut, handleDeleteAccount, translations]);
165
+ translations: undefined,
166
+ }), [handleSignIn, handleSignOut, handleDeleteAccount]);
160
167
 
161
168
  return {
162
169
  settingsConfig,
@@ -1,20 +0,0 @@
1
- /**
2
- * Feedback Repository Interface
3
- */
4
- import type { FeedbackEntity } from '../entities/FeedbackEntity';
5
- export interface FeedbackError {
6
- message: string;
7
- code?: 'SUBMIT_FAILED' | 'FETCH_FAILED' | 'DELETE_FAILED' | 'VALIDATION_ERROR';
8
- }
9
- export type FeedbackResult<T> = {
10
- success: true;
11
- data: T;
12
- } | {
13
- success: false;
14
- error: FeedbackError;
15
- };
16
- export interface IFeedbackRepository {
17
- submitFeedback(feedback: FeedbackEntity | Omit<FeedbackEntity, 'id'>): Promise<FeedbackResult<FeedbackEntity>>;
18
- getUserFeedback(userId: string): Promise<FeedbackResult<FeedbackEntity[]>>;
19
- deleteFeedback(feedbackId: string): Promise<FeedbackResult<boolean>>;
20
- }
@@ -1,3 +0,0 @@
1
- import type { FAQData } from "../navigation/types";
2
- import type { AppInfo } from "../navigation/types";
3
- export declare const translateFAQData: (faqData: FAQData | undefined, _appInfo: AppInfo) => FAQData | undefined;