@harkenapp/sdk-react-native 0.0.1-alpha.1 → 0.0.1-alpha.2

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 (278) hide show
  1. package/README.md +44 -7
  2. package/app.plugin.cjs +12 -17
  3. package/dist/__mocks__/async-storage.d.ts +16 -0
  4. package/dist/__mocks__/async-storage.d.ts.map +1 -0
  5. package/dist/__mocks__/async-storage.js +39 -0
  6. package/dist/__mocks__/async-storage.js.map +1 -0
  7. package/dist/__mocks__/expo-document-picker.d.ts +26 -0
  8. package/dist/__mocks__/expo-document-picker.d.ts.map +1 -0
  9. package/dist/__mocks__/expo-document-picker.js +25 -0
  10. package/dist/__mocks__/expo-document-picker.js.map +1 -0
  11. package/dist/__mocks__/expo-file-system.d.ts +42 -0
  12. package/dist/__mocks__/expo-file-system.d.ts.map +1 -0
  13. package/dist/__mocks__/expo-file-system.js +37 -0
  14. package/dist/__mocks__/expo-file-system.js.map +1 -0
  15. package/dist/__mocks__/expo-image-picker.d.ts +30 -0
  16. package/dist/__mocks__/expo-image-picker.d.ts.map +1 -0
  17. package/dist/__mocks__/expo-image-picker.js +30 -0
  18. package/dist/__mocks__/expo-image-picker.js.map +1 -0
  19. package/dist/__mocks__/expo-secure-store.d.ts +15 -0
  20. package/dist/__mocks__/expo-secure-store.d.ts.map +1 -0
  21. package/dist/__mocks__/expo-secure-store.js +30 -0
  22. package/dist/__mocks__/expo-secure-store.js.map +1 -0
  23. package/dist/__mocks__/react-native.d.ts +73 -0
  24. package/dist/__mocks__/react-native.d.ts.map +1 -0
  25. package/dist/__mocks__/react-native.js +45 -0
  26. package/dist/__mocks__/react-native.js.map +1 -0
  27. package/dist/api/client.d.ts +8 -8
  28. package/dist/api/client.d.ts.map +1 -1
  29. package/dist/api/client.js +17 -19
  30. package/dist/api/client.js.map +1 -1
  31. package/dist/api/client.test.d.ts +2 -0
  32. package/dist/api/client.test.d.ts.map +1 -0
  33. package/dist/api/client.test.js +417 -0
  34. package/dist/api/client.test.js.map +1 -0
  35. package/dist/api/errors.d.ts +3 -3
  36. package/dist/api/errors.d.ts.map +1 -1
  37. package/dist/api/errors.js +3 -3
  38. package/dist/api/errors.js.map +1 -1
  39. package/dist/api/errors.test.d.ts +2 -0
  40. package/dist/api/errors.test.d.ts.map +1 -0
  41. package/dist/api/errors.test.js +155 -0
  42. package/dist/api/errors.test.js.map +1 -0
  43. package/dist/api/index.d.ts +6 -6
  44. package/dist/api/index.d.ts.map +1 -1
  45. package/dist/api/index.js.map +1 -1
  46. package/dist/api/retry.d.ts +1 -1
  47. package/dist/api/retry.d.ts.map +1 -1
  48. package/dist/api/retry.js.map +1 -1
  49. package/dist/api/retry.test.d.ts +2 -0
  50. package/dist/api/retry.test.d.ts.map +1 -0
  51. package/dist/api/retry.test.js +193 -0
  52. package/dist/api/retry.test.js.map +1 -0
  53. package/dist/attachments/FeedbackSheet.d.ts +36 -13
  54. package/dist/attachments/FeedbackSheet.d.ts.map +1 -1
  55. package/dist/attachments/FeedbackSheet.js +50 -30
  56. package/dist/attachments/FeedbackSheet.js.map +1 -1
  57. package/dist/attachments/index.d.ts +2 -2
  58. package/dist/components/AttachmentGrid.d.ts +12 -4
  59. package/dist/components/AttachmentGrid.d.ts.map +1 -1
  60. package/dist/components/AttachmentGrid.js +44 -34
  61. package/dist/components/AttachmentGrid.js.map +1 -1
  62. package/dist/components/AttachmentPicker.d.ts +3 -3
  63. package/dist/components/AttachmentPicker.d.ts.map +1 -1
  64. package/dist/components/AttachmentPicker.js +34 -36
  65. package/dist/components/AttachmentPicker.js.map +1 -1
  66. package/dist/components/AttachmentPreview.d.ts +10 -4
  67. package/dist/components/AttachmentPreview.d.ts.map +1 -1
  68. package/dist/components/AttachmentPreview.js +48 -34
  69. package/dist/components/AttachmentPreview.js.map +1 -1
  70. package/dist/components/CategorySelector.d.ts +3 -3
  71. package/dist/components/CategorySelector.d.ts.map +1 -1
  72. package/dist/components/CategorySelector.js +21 -27
  73. package/dist/components/CategorySelector.js.map +1 -1
  74. package/dist/components/FeedbackForm.d.ts +3 -3
  75. package/dist/components/FeedbackForm.d.ts.map +1 -1
  76. package/dist/components/FeedbackForm.js +7 -8
  77. package/dist/components/FeedbackForm.js.map +1 -1
  78. package/dist/components/FeedbackSheet.d.ts +34 -11
  79. package/dist/components/FeedbackSheet.d.ts.map +1 -1
  80. package/dist/components/FeedbackSheet.js +46 -28
  81. package/dist/components/FeedbackSheet.js.map +1 -1
  82. package/dist/components/ThemedButton.d.ts +16 -5
  83. package/dist/components/ThemedButton.d.ts.map +1 -1
  84. package/dist/components/ThemedButton.js +38 -29
  85. package/dist/components/ThemedButton.js.map +1 -1
  86. package/dist/components/ThemedText.d.ts +3 -3
  87. package/dist/components/ThemedText.d.ts.map +1 -1
  88. package/dist/components/ThemedText.js +1 -1
  89. package/dist/components/ThemedText.js.map +1 -1
  90. package/dist/components/ThemedTextInput.d.ts +11 -2
  91. package/dist/components/ThemedTextInput.d.ts.map +1 -1
  92. package/dist/components/ThemedTextInput.js +19 -9
  93. package/dist/components/ThemedTextInput.js.map +1 -1
  94. package/dist/components/UploadStatusOverlay.d.ts +11 -3
  95. package/dist/components/UploadStatusOverlay.d.ts.map +1 -1
  96. package/dist/components/UploadStatusOverlay.js +59 -76
  97. package/dist/components/UploadStatusOverlay.js.map +1 -1
  98. package/dist/components/index.d.ts +18 -18
  99. package/dist/components/index.d.ts.map +1 -1
  100. package/dist/components/index.js.map +1 -1
  101. package/dist/context/HarkenContext.d.ts +20 -15
  102. package/dist/context/HarkenContext.d.ts.map +1 -1
  103. package/dist/context/HarkenContext.js +20 -17
  104. package/dist/context/HarkenContext.js.map +1 -1
  105. package/dist/context/index.d.ts +2 -2
  106. package/dist/domain/index.d.ts +2 -2
  107. package/dist/domain/index.d.ts.map +1 -1
  108. package/dist/domain/index.js.map +1 -1
  109. package/dist/hooks/index.d.ts +5 -5
  110. package/dist/hooks/useAnonymousId.js +1 -1
  111. package/dist/hooks/useAnonymousId.test.d.ts +2 -0
  112. package/dist/hooks/useAnonymousId.test.d.ts.map +1 -0
  113. package/dist/hooks/useAnonymousId.test.js +154 -0
  114. package/dist/hooks/useAnonymousId.test.js.map +1 -0
  115. package/dist/hooks/useAttachmentPicker.d.ts +3 -3
  116. package/dist/hooks/useAttachmentPicker.js +7 -7
  117. package/dist/hooks/useAttachmentStatus.d.ts +1 -1
  118. package/dist/hooks/useAttachmentStatus.d.ts.map +1 -1
  119. package/dist/hooks/useAttachmentStatus.js.map +1 -1
  120. package/dist/hooks/useAttachmentUpload.d.ts +2 -2
  121. package/dist/hooks/useAttachmentUpload.d.ts.map +1 -1
  122. package/dist/hooks/useAttachmentUpload.js +5 -5
  123. package/dist/hooks/useAttachmentUpload.js.map +1 -1
  124. package/dist/hooks/useAttachmentUpload.test.d.ts +2 -0
  125. package/dist/hooks/useAttachmentUpload.test.d.ts.map +1 -0
  126. package/dist/hooks/useAttachmentUpload.test.js +542 -0
  127. package/dist/hooks/useAttachmentUpload.test.js.map +1 -0
  128. package/dist/hooks/useFeedback.d.ts +4 -4
  129. package/dist/hooks/useFeedback.d.ts.map +1 -1
  130. package/dist/hooks/useFeedback.js +3 -5
  131. package/dist/hooks/useFeedback.js.map +1 -1
  132. package/dist/hooks/useFeedback.test.d.ts +2 -0
  133. package/dist/hooks/useFeedback.test.d.ts.map +1 -0
  134. package/dist/hooks/useFeedback.test.js +299 -0
  135. package/dist/hooks/useFeedback.test.js.map +1 -0
  136. package/dist/hooks/useHarkenContext.d.ts +1 -1
  137. package/dist/hooks/useHarkenContext.js +1 -1
  138. package/dist/hooks/useHarkenTheme.d.ts +27 -3
  139. package/dist/hooks/useHarkenTheme.d.ts.map +1 -1
  140. package/dist/hooks/useHarkenTheme.js +26 -2
  141. package/dist/hooks/useHarkenTheme.js.map +1 -1
  142. package/dist/index.d.ts +28 -28
  143. package/dist/index.d.ts.map +1 -1
  144. package/dist/index.js.map +1 -1
  145. package/dist/services/index.d.ts +3 -3
  146. package/dist/services/index.d.ts.map +1 -1
  147. package/dist/services/index.js.map +1 -1
  148. package/dist/services/uploadQueueService.d.ts +2 -2
  149. package/dist/services/uploadQueueService.d.ts.map +1 -1
  150. package/dist/services/uploadQueueService.js +16 -17
  151. package/dist/services/uploadQueueService.js.map +1 -1
  152. package/dist/services/uploadQueueService.test.d.ts +2 -0
  153. package/dist/services/uploadQueueService.test.d.ts.map +1 -0
  154. package/dist/services/uploadQueueService.test.js +426 -0
  155. package/dist/services/uploadQueueService.test.js.map +1 -0
  156. package/dist/services/uploadQueueStorage.d.ts +1 -1
  157. package/dist/services/uploadQueueStorage.d.ts.map +1 -1
  158. package/dist/services/uploadQueueStorage.js +4 -4
  159. package/dist/services/uploadQueueStorage.js.map +1 -1
  160. package/dist/services/uploadQueueStorage.test.d.ts +2 -0
  161. package/dist/services/uploadQueueStorage.test.d.ts.map +1 -0
  162. package/dist/services/uploadQueueStorage.test.js +200 -0
  163. package/dist/services/uploadQueueStorage.test.js.map +1 -0
  164. package/dist/storage/IdentityStore.d.ts +1 -1
  165. package/dist/storage/IdentityStore.d.ts.map +1 -1
  166. package/dist/storage/IdentityStore.js.map +1 -1
  167. package/dist/storage/IdentityStore.test.d.ts +2 -0
  168. package/dist/storage/IdentityStore.test.d.ts.map +1 -0
  169. package/dist/storage/IdentityStore.test.js +176 -0
  170. package/dist/storage/IdentityStore.test.js.map +1 -0
  171. package/dist/storage/SecureStoreAdapter.d.ts +1 -1
  172. package/dist/storage/SecureStoreAdapter.test.d.ts +2 -0
  173. package/dist/storage/SecureStoreAdapter.test.d.ts.map +1 -0
  174. package/dist/storage/SecureStoreAdapter.test.js +114 -0
  175. package/dist/storage/SecureStoreAdapter.test.js.map +1 -0
  176. package/dist/storage/defaultStorage.d.ts +1 -1
  177. package/dist/storage/defaultStorage.js +4 -4
  178. package/dist/storage/defaultStorage.test.d.ts +2 -0
  179. package/dist/storage/defaultStorage.test.d.ts.map +1 -0
  180. package/dist/storage/defaultStorage.test.js +159 -0
  181. package/dist/storage/defaultStorage.test.js.map +1 -0
  182. package/dist/storage/index.d.ts +5 -5
  183. package/dist/storage/types.js +1 -1
  184. package/dist/theme/defaults.d.ts +14 -3
  185. package/dist/theme/defaults.d.ts.map +1 -1
  186. package/dist/theme/defaults.js +58 -43
  187. package/dist/theme/defaults.js.map +1 -1
  188. package/dist/theme/index.d.ts +3 -2
  189. package/dist/theme/index.d.ts.map +1 -1
  190. package/dist/theme/index.js +4 -1
  191. package/dist/theme/index.js.map +1 -1
  192. package/dist/theme/resolver.d.ts +16 -0
  193. package/dist/theme/resolver.d.ts.map +1 -0
  194. package/dist/theme/resolver.js +375 -0
  195. package/dist/theme/resolver.js.map +1 -0
  196. package/dist/theme/resolver.test.d.ts +2 -0
  197. package/dist/theme/resolver.test.d.ts.map +1 -0
  198. package/dist/theme/resolver.test.js +344 -0
  199. package/dist/theme/resolver.test.js.map +1 -0
  200. package/dist/theme/types.d.ts +378 -5
  201. package/dist/theme/types.d.ts.map +1 -1
  202. package/dist/types/config.d.ts +4 -4
  203. package/dist/types/index.d.ts +2 -2
  204. package/dist/utils/index.d.ts +1 -1
  205. package/dist/utils/uuid.d.ts.map +1 -1
  206. package/dist/utils/uuid.js +4 -5
  207. package/dist/utils/uuid.js.map +1 -1
  208. package/dist/utils/uuid.test.d.ts +2 -0
  209. package/dist/utils/uuid.test.d.ts.map +1 -0
  210. package/dist/utils/uuid.test.js +78 -0
  211. package/dist/utils/uuid.test.js.map +1 -0
  212. package/package.json +21 -13
  213. package/src/@types/expo-file-system-legacy.d.ts +3 -3
  214. package/src/__mocks__/async-storage.ts +46 -0
  215. package/src/__mocks__/expo-document-picker.ts +41 -0
  216. package/src/__mocks__/expo-file-system.ts +62 -0
  217. package/src/__mocks__/expo-image-picker.ts +48 -0
  218. package/src/__mocks__/expo-secure-store.ts +29 -0
  219. package/src/__mocks__/react-native.ts +46 -0
  220. package/src/api/client.test.ts +515 -0
  221. package/src/api/client.ts +45 -64
  222. package/src/api/errors.test.ts +193 -0
  223. package/src/api/errors.ts +7 -11
  224. package/src/api/index.ts +6 -10
  225. package/src/api/retry.test.ts +251 -0
  226. package/src/api/retry.ts +3 -6
  227. package/src/attachments/FeedbackSheet.tsx +100 -80
  228. package/src/attachments/index.ts +2 -2
  229. package/src/components/AttachmentGrid.tsx +54 -45
  230. package/src/components/AttachmentPicker.tsx +43 -54
  231. package/src/components/AttachmentPreview.tsx +51 -47
  232. package/src/components/CategorySelector.tsx +29 -35
  233. package/src/components/FeedbackForm.tsx +23 -35
  234. package/src/components/FeedbackSheet.tsx +89 -68
  235. package/src/components/ThemedButton.tsx +49 -47
  236. package/src/components/ThemedText.tsx +7 -10
  237. package/src/components/ThemedTextInput.tsx +23 -13
  238. package/src/components/UploadStatusOverlay.tsx +66 -89
  239. package/src/components/index.ts +18 -21
  240. package/src/context/HarkenContext.tsx +29 -28
  241. package/src/context/index.ts +2 -2
  242. package/src/domain/index.ts +2 -5
  243. package/src/domain/upload-queue.ts +5 -5
  244. package/src/hooks/index.ts +5 -5
  245. package/src/hooks/useAnonymousId.test.ts +189 -0
  246. package/src/hooks/useAnonymousId.ts +3 -3
  247. package/src/hooks/useAttachmentPicker.ts +12 -12
  248. package/src/hooks/useAttachmentStatus.ts +12 -16
  249. package/src/hooks/useAttachmentUpload.test.ts +632 -0
  250. package/src/hooks/useAttachmentUpload.ts +45 -54
  251. package/src/hooks/useFeedback.test.ts +376 -0
  252. package/src/hooks/useFeedback.ts +12 -14
  253. package/src/hooks/useHarkenContext.ts +4 -4
  254. package/src/hooks/useHarkenTheme.ts +30 -6
  255. package/src/index.ts +28 -52
  256. package/src/services/index.ts +3 -9
  257. package/src/services/uploadQueueService.test.ts +489 -0
  258. package/src/services/uploadQueueService.ts +40 -56
  259. package/src/services/uploadQueueStorage.test.ts +243 -0
  260. package/src/services/uploadQueueStorage.ts +7 -9
  261. package/src/storage/IdentityStore.test.ts +173 -0
  262. package/src/storage/IdentityStore.ts +4 -5
  263. package/src/storage/SecureStoreAdapter.test.ts +147 -0
  264. package/src/storage/SecureStoreAdapter.ts +1 -1
  265. package/src/storage/defaultStorage.test.ts +159 -0
  266. package/src/storage/defaultStorage.ts +6 -6
  267. package/src/storage/index.ts +5 -5
  268. package/src/storage/types.ts +1 -1
  269. package/src/theme/defaults.ts +75 -46
  270. package/src/theme/index.ts +15 -2
  271. package/src/theme/resolver.test.ts +411 -0
  272. package/src/theme/resolver.ts +446 -0
  273. package/src/theme/types.ts +453 -15
  274. package/src/types/config.ts +4 -4
  275. package/src/types/index.ts +2 -2
  276. package/src/utils/index.ts +1 -1
  277. package/src/utils/uuid.test.ts +85 -0
  278. package/src/utils/uuid.ts +4 -7
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@harkenapp/sdk-react-native",
3
- "version": "0.0.1-alpha.1",
3
+ "version": "0.0.1-alpha.2",
4
4
  "description": "Harken React Native / Expo SDK for in-app feedback",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.js",
@@ -39,6 +39,9 @@
39
39
  "generate": "openapi-typescript openapi.yaml -o src/types/openapi.ts",
40
40
  "build": "pnpm run generate && tsc",
41
41
  "typecheck": "tsc --noEmit",
42
+ "test": "vitest run",
43
+ "test:watch": "vitest",
44
+ "test:coverage": "vitest run --coverage",
42
45
  "clean": "rm -rf dist",
43
46
  "prepublishOnly": "pnpm run clean && pnpm run build"
44
47
  },
@@ -56,28 +59,28 @@
56
59
  },
57
60
  "repository": {
58
61
  "type": "git",
59
- "url": "https://github.com/harken-app/harken.git",
62
+ "url": "https://github.com/thutch-conecrow/harken.git",
60
63
  "directory": "packages/sdk-react-native"
61
64
  },
62
65
  "bugs": {
63
- "url": "https://github.com/harken-app/harken/issues"
66
+ "url": "https://github.com/thutch-conecrow/harken/issues"
64
67
  },
65
- "homepage": "https://github.com/harken-app/harken#readme",
68
+ "homepage": "https://github.com/thutch-conecrow/harken#readme",
66
69
  "sideEffects": false,
67
70
  "expo": {
68
71
  "configPlugin": "./app.plugin.cjs"
69
72
  },
70
73
  "peerDependencies": {
71
- "react": ">=18.0.0",
72
- "react-native": ">=0.72.0",
73
- "react-native-safe-area-context": ">=4.0.0",
74
+ "@react-native-async-storage/async-storage": ">=1.21.0",
75
+ "@react-native-community/netinfo": ">=11.0.0",
74
76
  "expo": ">=54.0.0 <55.0.0",
75
- "expo-secure-store": ">=13.0.0",
77
+ "expo-document-picker": ">=12.0.0",
76
78
  "expo-file-system": ">=19.0.0",
77
79
  "expo-image-picker": ">=15.0.0",
78
- "expo-document-picker": ">=12.0.0",
79
- "@react-native-async-storage/async-storage": ">=1.21.0",
80
- "@react-native-community/netinfo": ">=11.0.0"
80
+ "expo-secure-store": ">=13.0.0",
81
+ "react": ">=18.0.0",
82
+ "react-native": ">=0.72.0",
83
+ "react-native-safe-area-context": ">=4.0.0"
81
84
  },
82
85
  "peerDependenciesMeta": {
83
86
  "react-native": {
@@ -109,16 +112,21 @@
109
112
  }
110
113
  },
111
114
  "devDependencies": {
112
- "openapi-typescript": "^7.4.4",
113
115
  "@react-native-async-storage/async-storage": "^2.1.0",
114
116
  "@react-native-community/netinfo": "^11.4.1",
117
+ "@testing-library/react": "^16.3.2",
115
118
  "@types/react": "^19.1.0",
119
+ "@vitest/coverage-v8": "^4.0.17",
116
120
  "expo-document-picker": "^14.0.0",
117
121
  "expo-file-system": "^19.0.0",
118
122
  "expo-image-picker": "^17.0.0",
123
+ "jsdom": "^27.4.0",
124
+ "openapi-typescript": "^7.4.4",
119
125
  "react": "^19.1.0",
126
+ "react-dom": "^19.1.0",
120
127
  "react-native": "^0.81.5",
121
128
  "react-native-safe-area-context": "^5.0.0",
122
- "typescript": "^5.9.0"
129
+ "typescript": "^5.9.0",
130
+ "vitest": "^4.0.17"
123
131
  }
124
132
  }
@@ -6,8 +6,8 @@
6
6
  *
7
7
  * This declaration enables TypeScript to resolve the import.
8
8
  */
9
- declare module 'expo-file-system/legacy' {
9
+ declare module "expo-file-system/legacy" {
10
10
  // Re-export types from the build output
11
- export * from 'expo-file-system/build/legacy/FileSystem';
12
- export * from 'expo-file-system/build/legacy/FileSystem.types';
11
+ export * from "expo-file-system/build/legacy/FileSystem";
12
+ export * from "expo-file-system/build/legacy/FileSystem.types";
13
13
  }
@@ -0,0 +1,46 @@
1
+ /**
2
+ * Mock @react-native-async-storage/async-storage for testing.
3
+ */
4
+
5
+ const storage = new Map<string, string>();
6
+
7
+ const AsyncStorage = {
8
+ getItem: async (key: string): Promise<string | null> => {
9
+ return storage.get(key) ?? null;
10
+ },
11
+
12
+ setItem: async (key: string, value: string): Promise<void> => {
13
+ storage.set(key, value);
14
+ },
15
+
16
+ removeItem: async (key: string): Promise<void> => {
17
+ storage.delete(key);
18
+ },
19
+
20
+ clear: async (): Promise<void> => {
21
+ storage.clear();
22
+ },
23
+
24
+ getAllKeys: async (): Promise<string[]> => {
25
+ return Array.from(storage.keys());
26
+ },
27
+
28
+ multiGet: async (keys: string[]): Promise<readonly [string, string | null][]> => {
29
+ return keys.map((key) => [key, storage.get(key) ?? null]);
30
+ },
31
+
32
+ multiSet: async (keyValuePairs: [string, string][]): Promise<void> => {
33
+ keyValuePairs.forEach(([key, value]) => storage.set(key, value));
34
+ },
35
+
36
+ multiRemove: async (keys: string[]): Promise<void> => {
37
+ keys.forEach((key) => storage.delete(key));
38
+ },
39
+ };
40
+
41
+ // Helper to clear storage between tests
42
+ export function __clearStorage(): void {
43
+ storage.clear();
44
+ }
45
+
46
+ export default AsyncStorage;
@@ -0,0 +1,41 @@
1
+ /**
2
+ * Mock expo-document-picker for testing.
3
+ */
4
+
5
+ export interface DocumentPickerOptions {
6
+ type?: string[];
7
+ copyToCacheDirectory?: boolean;
8
+ }
9
+
10
+ export interface DocumentPickerResult {
11
+ canceled: boolean;
12
+ assets: Array<{
13
+ uri: string;
14
+ name: string;
15
+ mimeType?: string;
16
+ size?: number;
17
+ }> | null;
18
+ }
19
+
20
+ let mockResult: DocumentPickerResult = { canceled: true, assets: null };
21
+
22
+ export async function getDocumentAsync(
23
+ _options?: DocumentPickerOptions
24
+ ): Promise<DocumentPickerResult> {
25
+ return mockResult;
26
+ }
27
+
28
+ // Helper to set mock result for tests
29
+ export function __setMockResult(result: DocumentPickerResult): void {
30
+ mockResult = result;
31
+ }
32
+
33
+ export function __resetMock(): void {
34
+ mockResult = { canceled: true, assets: null };
35
+ }
36
+
37
+ export default {
38
+ getDocumentAsync,
39
+ __setMockResult,
40
+ __resetMock,
41
+ };
@@ -0,0 +1,62 @@
1
+ /**
2
+ * Mock expo-file-system/legacy for testing.
3
+ */
4
+
5
+ export interface FileInfo {
6
+ exists: boolean;
7
+ uri?: string;
8
+ size?: number;
9
+ modificationTime?: number;
10
+ isDirectory?: boolean;
11
+ }
12
+
13
+ const mockFileInfo: Map<string, FileInfo> = new Map();
14
+
15
+ export async function getInfoAsync(uri: string): Promise<FileInfo> {
16
+ return mockFileInfo.get(uri) ?? { exists: false };
17
+ }
18
+
19
+ export interface UploadProgressData {
20
+ totalBytesSent: number;
21
+ totalBytesExpectedToSend: number;
22
+ }
23
+
24
+ export interface FileSystemUploadResult {
25
+ status: number;
26
+ body?: string;
27
+ }
28
+
29
+ export async function uploadAsync(
30
+ _url: string,
31
+ _fileUri: string,
32
+ _options?: {
33
+ httpMethod?: string;
34
+ uploadType?: string;
35
+ headers?: Record<string, string>;
36
+ }
37
+ ): Promise<FileSystemUploadResult> {
38
+ return { status: 200 };
39
+ }
40
+
41
+ // Constants
42
+ export const FileSystemUploadType = {
43
+ BINARY_CONTENT: "binaryContent",
44
+ MULTIPART: "multipart",
45
+ };
46
+
47
+ // Helper to set mock file info for tests
48
+ export function __setMockFileInfo(uri: string, info: FileInfo): void {
49
+ mockFileInfo.set(uri, info);
50
+ }
51
+
52
+ export function __resetMock(): void {
53
+ mockFileInfo.clear();
54
+ }
55
+
56
+ export default {
57
+ getInfoAsync,
58
+ uploadAsync,
59
+ FileSystemUploadType,
60
+ __setMockFileInfo,
61
+ __resetMock,
62
+ };
@@ -0,0 +1,48 @@
1
+ /**
2
+ * Mock expo-image-picker for testing.
3
+ */
4
+
5
+ export interface ImagePickerOptions {
6
+ mediaTypes?: string[];
7
+ quality?: number;
8
+ }
9
+
10
+ export interface ImagePickerResult {
11
+ canceled: boolean;
12
+ assets: Array<{
13
+ uri: string;
14
+ fileName?: string;
15
+ mimeType?: string;
16
+ fileSize?: number;
17
+ width?: number;
18
+ height?: number;
19
+ }> | null;
20
+ }
21
+
22
+ let mockResult: ImagePickerResult = { canceled: true, assets: null };
23
+
24
+ export async function launchCameraAsync(_options?: ImagePickerOptions): Promise<ImagePickerResult> {
25
+ return mockResult;
26
+ }
27
+
28
+ export async function launchImageLibraryAsync(
29
+ _options?: ImagePickerOptions
30
+ ): Promise<ImagePickerResult> {
31
+ return mockResult;
32
+ }
33
+
34
+ // Helper to set mock result for tests
35
+ export function __setMockResult(result: ImagePickerResult): void {
36
+ mockResult = result;
37
+ }
38
+
39
+ export function __resetMock(): void {
40
+ mockResult = { canceled: true, assets: null };
41
+ }
42
+
43
+ export default {
44
+ launchCameraAsync,
45
+ launchImageLibraryAsync,
46
+ __setMockResult,
47
+ __resetMock,
48
+ };
@@ -0,0 +1,29 @@
1
+ /**
2
+ * Mock expo-secure-store for testing.
3
+ */
4
+
5
+ const storage = new Map<string, string>();
6
+
7
+ export async function getItemAsync(key: string): Promise<string | null> {
8
+ return storage.get(key) ?? null;
9
+ }
10
+
11
+ export async function setItemAsync(key: string, value: string): Promise<void> {
12
+ storage.set(key, value);
13
+ }
14
+
15
+ export async function deleteItemAsync(key: string): Promise<void> {
16
+ storage.delete(key);
17
+ }
18
+
19
+ // Helper to clear storage between tests
20
+ export function __clearStorage(): void {
21
+ storage.clear();
22
+ }
23
+
24
+ export default {
25
+ getItemAsync,
26
+ setItemAsync,
27
+ deleteItemAsync,
28
+ __clearStorage,
29
+ };
@@ -0,0 +1,46 @@
1
+ /**
2
+ * Mock React Native module for testing.
3
+ *
4
+ * Provides minimal mocks for modules used by the SDK.
5
+ */
6
+
7
+ export const Platform = {
8
+ OS: "ios" as "ios" | "android" | "web" | "windows" | "macos",
9
+ select: <T>(options: { ios?: T; android?: T; default?: T }): T | undefined => {
10
+ return options.ios ?? options.default;
11
+ },
12
+ Version: "17.0",
13
+ };
14
+
15
+ export const StyleSheet = {
16
+ create: <T extends Record<string, unknown>>(styles: T): T => styles,
17
+ flatten: <T>(style: T | T[]): T => (Array.isArray(style) ? Object.assign({}, ...style) : style),
18
+ };
19
+
20
+ export const Dimensions = {
21
+ get: () => ({ width: 375, height: 812, scale: 2, fontScale: 1 }),
22
+ addEventListener: () => ({ remove: () => {} }),
23
+ };
24
+
25
+ export const View = "View";
26
+ export const Text = "Text";
27
+ export const TouchableOpacity = "TouchableOpacity";
28
+ export const TextInput = "TextInput";
29
+ export const ScrollView = "ScrollView";
30
+ export const ActivityIndicator = "ActivityIndicator";
31
+ export const Image = "Image";
32
+ export const Pressable = "Pressable";
33
+
34
+ export default {
35
+ Platform,
36
+ StyleSheet,
37
+ Dimensions,
38
+ View,
39
+ Text,
40
+ TouchableOpacity,
41
+ TextInput,
42
+ ScrollView,
43
+ ActivityIndicator,
44
+ Image,
45
+ Pressable,
46
+ };