@savers_app/react-native-sandbox-sdk 1.2.6

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 (212) hide show
  1. package/LICENSE +20 -0
  2. package/README.md +556 -0
  3. package/lib/module/@types/@react-native-async-storage__async-storage.d.js +2 -0
  4. package/lib/module/@types/@react-native-async-storage__async-storage.d.js.map +1 -0
  5. package/lib/module/@types/@react-native-community__geolocation.d.js +2 -0
  6. package/lib/module/@types/@react-native-community__geolocation.d.js.map +1 -0
  7. package/lib/module/@types/react-native-aes-gcm-crypto.d.js +2 -0
  8. package/lib/module/@types/react-native-aes-gcm-crypto.d.js.map +1 -0
  9. package/lib/module/@types/react-native-device-info.d.js +2 -0
  10. package/lib/module/@types/react-native-device-info.d.js.map +1 -0
  11. package/lib/module/core/runtime.js +70 -0
  12. package/lib/module/core/runtime.js.map +1 -0
  13. package/lib/module/data/models/apiResponse.js +19 -0
  14. package/lib/module/data/models/apiResponse.js.map +1 -0
  15. package/lib/module/data/models/onboardingModel.js +67 -0
  16. package/lib/module/data/models/onboardingModel.js.map +1 -0
  17. package/lib/module/data/models/tokenModel.js +25 -0
  18. package/lib/module/data/models/tokenModel.js.map +1 -0
  19. package/lib/module/data/network/apiClient.js +109 -0
  20. package/lib/module/data/network/apiClient.js.map +1 -0
  21. package/lib/module/data/network/apiEndpoints.js +7 -0
  22. package/lib/module/data/network/apiEndpoints.js.map +1 -0
  23. package/lib/module/data/network/apiExceptionHandler.js +16 -0
  24. package/lib/module/data/network/apiExceptionHandler.js.map +1 -0
  25. package/lib/module/data/network/apiRepository.js +84 -0
  26. package/lib/module/data/network/apiRepository.js.map +1 -0
  27. package/lib/module/data/network/apiService.js +102 -0
  28. package/lib/module/data/network/apiService.js.map +1 -0
  29. package/lib/module/data/network/dataTypeUtils.js +77 -0
  30. package/lib/module/data/network/dataTypeUtils.js.map +1 -0
  31. package/lib/module/data/network/interceptors/authInterceptor.js +72 -0
  32. package/lib/module/data/network/interceptors/authInterceptor.js.map +1 -0
  33. package/lib/module/data/network/interceptors/errorInterceptor.js +15 -0
  34. package/lib/module/data/network/interceptors/errorInterceptor.js.map +1 -0
  35. package/lib/module/data/network/interceptors/loggingInterceptor.js +17 -0
  36. package/lib/module/data/network/interceptors/loggingInterceptor.js.map +1 -0
  37. package/lib/module/data/network/interceptors/networkInterceptor.js +22 -0
  38. package/lib/module/data/network/interceptors/networkInterceptor.js.map +1 -0
  39. package/lib/module/data/network/interceptors/retryInterceptor.js +22 -0
  40. package/lib/module/data/network/interceptors/retryInterceptor.js.map +1 -0
  41. package/lib/module/data/storage/asyncStorageManager.js +50 -0
  42. package/lib/module/data/storage/asyncStorageManager.js.map +1 -0
  43. package/lib/module/data/storage/deviceIdManager.js +45 -0
  44. package/lib/module/data/storage/deviceIdManager.js.map +1 -0
  45. package/lib/module/data/storage/keysManager.js +70 -0
  46. package/lib/module/data/storage/keysManager.js.map +1 -0
  47. package/lib/module/data/storage/locationManager.js +30 -0
  48. package/lib/module/data/storage/locationManager.js.map +1 -0
  49. package/lib/module/data/storage/reactRefManager.js +22 -0
  50. package/lib/module/data/storage/reactRefManager.js.map +1 -0
  51. package/lib/module/data/storage/sessionManager.js +12 -0
  52. package/lib/module/data/storage/sessionManager.js.map +1 -0
  53. package/lib/module/data/storage/storageKeys.js +7 -0
  54. package/lib/module/data/storage/storageKeys.js.map +1 -0
  55. package/lib/module/data/storage/storageManager.js +76 -0
  56. package/lib/module/data/storage/storageManager.js.map +1 -0
  57. package/lib/module/index.js +20 -0
  58. package/lib/module/index.js.map +1 -0
  59. package/lib/module/package.json +1 -0
  60. package/lib/module/services/device/location.js +47 -0
  61. package/lib/module/services/device/location.js.map +1 -0
  62. package/lib/module/services/navigation/dialPad.js +29 -0
  63. package/lib/module/services/navigation/dialPad.js.map +1 -0
  64. package/lib/module/services/navigation/goBackNavigation.js +19 -0
  65. package/lib/module/services/navigation/goBackNavigation.js.map +1 -0
  66. package/lib/module/services/navigation/openBrowser.js +8 -0
  67. package/lib/module/services/navigation/openBrowser.js.map +1 -0
  68. package/lib/module/services/navigation/openMap.js +42 -0
  69. package/lib/module/services/navigation/openMap.js.map +1 -0
  70. package/lib/module/services/permissions/permissionManager.js +28 -0
  71. package/lib/module/services/permissions/permissionManager.js.map +1 -0
  72. package/lib/module/services/url/urlGenerator.js +94 -0
  73. package/lib/module/services/url/urlGenerator.js.map +1 -0
  74. package/lib/module/services/webview/messageHandler.js +72 -0
  75. package/lib/module/services/webview/messageHandler.js.map +1 -0
  76. package/lib/module/utils/config.js +34 -0
  77. package/lib/module/utils/config.js.map +1 -0
  78. package/lib/module/utils/dependencyManager.js +51 -0
  79. package/lib/module/utils/dependencyManager.js.map +1 -0
  80. package/lib/module/utils/encryption.js +63 -0
  81. package/lib/module/utils/encryption.js.map +1 -0
  82. package/lib/module/utils/errors.js +9 -0
  83. package/lib/module/utils/errors.js.map +1 -0
  84. package/lib/module/utils/logger.js +14 -0
  85. package/lib/module/utils/logger.js.map +1 -0
  86. package/lib/module/utils/platformManager.js +14 -0
  87. package/lib/module/utils/platformManager.js.map +1 -0
  88. package/lib/module/utils/validator.js +26 -0
  89. package/lib/module/utils/validator.js.map +1 -0
  90. package/lib/typescript/package.json +1 -0
  91. package/lib/typescript/src/core/runtime.d.ts +11 -0
  92. package/lib/typescript/src/core/runtime.d.ts.map +1 -0
  93. package/lib/typescript/src/data/models/apiResponse.d.ts +9 -0
  94. package/lib/typescript/src/data/models/apiResponse.d.ts.map +1 -0
  95. package/lib/typescript/src/data/models/onboardingModel.d.ts +24 -0
  96. package/lib/typescript/src/data/models/onboardingModel.d.ts.map +1 -0
  97. package/lib/typescript/src/data/models/tokenModel.d.ts +15 -0
  98. package/lib/typescript/src/data/models/tokenModel.d.ts.map +1 -0
  99. package/lib/typescript/src/data/network/apiClient.d.ts +17 -0
  100. package/lib/typescript/src/data/network/apiClient.d.ts.map +1 -0
  101. package/lib/typescript/src/data/network/apiEndpoints.d.ts +5 -0
  102. package/lib/typescript/src/data/network/apiEndpoints.d.ts.map +1 -0
  103. package/lib/typescript/src/data/network/apiExceptionHandler.d.ts +3 -0
  104. package/lib/typescript/src/data/network/apiExceptionHandler.d.ts.map +1 -0
  105. package/lib/typescript/src/data/network/apiRepository.d.ts +21 -0
  106. package/lib/typescript/src/data/network/apiRepository.d.ts.map +1 -0
  107. package/lib/typescript/src/data/network/apiService.d.ts +25 -0
  108. package/lib/typescript/src/data/network/apiService.d.ts.map +1 -0
  109. package/lib/typescript/src/data/network/dataTypeUtils.d.ts +10 -0
  110. package/lib/typescript/src/data/network/dataTypeUtils.d.ts.map +1 -0
  111. package/lib/typescript/src/data/network/interceptors/authInterceptor.d.ts +15 -0
  112. package/lib/typescript/src/data/network/interceptors/authInterceptor.d.ts.map +1 -0
  113. package/lib/typescript/src/data/network/interceptors/errorInterceptor.d.ts +4 -0
  114. package/lib/typescript/src/data/network/interceptors/errorInterceptor.d.ts.map +1 -0
  115. package/lib/typescript/src/data/network/interceptors/loggingInterceptor.d.ts +5 -0
  116. package/lib/typescript/src/data/network/interceptors/loggingInterceptor.d.ts.map +1 -0
  117. package/lib/typescript/src/data/network/interceptors/networkInterceptor.d.ts +4 -0
  118. package/lib/typescript/src/data/network/interceptors/networkInterceptor.d.ts.map +1 -0
  119. package/lib/typescript/src/data/network/interceptors/retryInterceptor.d.ts +7 -0
  120. package/lib/typescript/src/data/network/interceptors/retryInterceptor.d.ts.map +1 -0
  121. package/lib/typescript/src/data/storage/asyncStorageManager.d.ts +13 -0
  122. package/lib/typescript/src/data/storage/asyncStorageManager.d.ts.map +1 -0
  123. package/lib/typescript/src/data/storage/deviceIdManager.d.ts +2 -0
  124. package/lib/typescript/src/data/storage/deviceIdManager.d.ts.map +1 -0
  125. package/lib/typescript/src/data/storage/keysManager.d.ts +29 -0
  126. package/lib/typescript/src/data/storage/keysManager.d.ts.map +1 -0
  127. package/lib/typescript/src/data/storage/locationManager.d.ts +21 -0
  128. package/lib/typescript/src/data/storage/locationManager.d.ts.map +1 -0
  129. package/lib/typescript/src/data/storage/reactRefManager.d.ts +11 -0
  130. package/lib/typescript/src/data/storage/reactRefManager.d.ts.map +1 -0
  131. package/lib/typescript/src/data/storage/sessionManager.d.ts +3 -0
  132. package/lib/typescript/src/data/storage/sessionManager.d.ts.map +1 -0
  133. package/lib/typescript/src/data/storage/storageKeys.d.ts +5 -0
  134. package/lib/typescript/src/data/storage/storageKeys.d.ts.map +1 -0
  135. package/lib/typescript/src/data/storage/storageManager.d.ts +16 -0
  136. package/lib/typescript/src/data/storage/storageManager.d.ts.map +1 -0
  137. package/lib/typescript/src/index.d.ts +18 -0
  138. package/lib/typescript/src/index.d.ts.map +1 -0
  139. package/lib/typescript/src/services/device/location.d.ts +8 -0
  140. package/lib/typescript/src/services/device/location.d.ts.map +1 -0
  141. package/lib/typescript/src/services/navigation/dialPad.d.ts +3 -0
  142. package/lib/typescript/src/services/navigation/dialPad.d.ts.map +1 -0
  143. package/lib/typescript/src/services/navigation/goBackNavigation.d.ts +3 -0
  144. package/lib/typescript/src/services/navigation/goBackNavigation.d.ts.map +1 -0
  145. package/lib/typescript/src/services/navigation/openBrowser.d.ts +2 -0
  146. package/lib/typescript/src/services/navigation/openBrowser.d.ts.map +1 -0
  147. package/lib/typescript/src/services/navigation/openMap.d.ts +2 -0
  148. package/lib/typescript/src/services/navigation/openMap.d.ts.map +1 -0
  149. package/lib/typescript/src/services/permissions/permissionManager.d.ts +4 -0
  150. package/lib/typescript/src/services/permissions/permissionManager.d.ts.map +1 -0
  151. package/lib/typescript/src/services/url/urlGenerator.d.ts +44 -0
  152. package/lib/typescript/src/services/url/urlGenerator.d.ts.map +1 -0
  153. package/lib/typescript/src/services/webview/messageHandler.d.ts +2 -0
  154. package/lib/typescript/src/services/webview/messageHandler.d.ts.map +1 -0
  155. package/lib/typescript/src/utils/config.d.ts +5 -0
  156. package/lib/typescript/src/utils/config.d.ts.map +1 -0
  157. package/lib/typescript/src/utils/dependencyManager.d.ts +31 -0
  158. package/lib/typescript/src/utils/dependencyManager.d.ts.map +1 -0
  159. package/lib/typescript/src/utils/encryption.d.ts +5 -0
  160. package/lib/typescript/src/utils/encryption.d.ts.map +1 -0
  161. package/lib/typescript/src/utils/errors.d.ts +4 -0
  162. package/lib/typescript/src/utils/errors.d.ts.map +1 -0
  163. package/lib/typescript/src/utils/logger.d.ts +6 -0
  164. package/lib/typescript/src/utils/logger.d.ts.map +1 -0
  165. package/lib/typescript/src/utils/platformManager.d.ts +4 -0
  166. package/lib/typescript/src/utils/platformManager.d.ts.map +1 -0
  167. package/lib/typescript/src/utils/validator.d.ts +4 -0
  168. package/lib/typescript/src/utils/validator.d.ts.map +1 -0
  169. package/package.json +184 -0
  170. package/src/@types/@react-native-async-storage__async-storage.d.ts +7 -0
  171. package/src/@types/@react-native-community__geolocation.d.ts +18 -0
  172. package/src/@types/react-native-aes-gcm-crypto.d.ts +22 -0
  173. package/src/@types/react-native-device-info.d.ts +3 -0
  174. package/src/core/runtime.ts +84 -0
  175. package/src/data/models/apiResponse.ts +28 -0
  176. package/src/data/models/onboardingModel.ts +97 -0
  177. package/src/data/models/tokenModel.ts +43 -0
  178. package/src/data/network/apiClient.ts +148 -0
  179. package/src/data/network/apiEndpoints.ts +4 -0
  180. package/src/data/network/apiExceptionHandler.ts +16 -0
  181. package/src/data/network/apiRepository.ts +130 -0
  182. package/src/data/network/apiService.ts +113 -0
  183. package/src/data/network/dataTypeUtils.ts +78 -0
  184. package/src/data/network/interceptors/authInterceptor.ts +86 -0
  185. package/src/data/network/interceptors/errorInterceptor.ts +13 -0
  186. package/src/data/network/interceptors/loggingInterceptor.ts +16 -0
  187. package/src/data/network/interceptors/networkInterceptor.ts +20 -0
  188. package/src/data/network/interceptors/retryInterceptor.ts +24 -0
  189. package/src/data/storage/asyncStorageManager.ts +56 -0
  190. package/src/data/storage/deviceIdManager.ts +46 -0
  191. package/src/data/storage/keysManager.ts +89 -0
  192. package/src/data/storage/locationManager.ts +39 -0
  193. package/src/data/storage/reactRefManager.ts +25 -0
  194. package/src/data/storage/sessionManager.ts +11 -0
  195. package/src/data/storage/storageKeys.ts +4 -0
  196. package/src/data/storage/storageManager.ts +83 -0
  197. package/src/index.tsx +17 -0
  198. package/src/services/device/location.ts +51 -0
  199. package/src/services/navigation/dialPad.ts +39 -0
  200. package/src/services/navigation/goBackNavigation.ts +19 -0
  201. package/src/services/navigation/openBrowser.ts +6 -0
  202. package/src/services/navigation/openMap.ts +53 -0
  203. package/src/services/permissions/permissionManager.ts +33 -0
  204. package/src/services/url/urlGenerator.ts +140 -0
  205. package/src/services/webview/messageHandler.ts +45 -0
  206. package/src/utils/config.ts +35 -0
  207. package/src/utils/dependencyManager.ts +82 -0
  208. package/src/utils/encryption.ts +96 -0
  209. package/src/utils/errors.ts +6 -0
  210. package/src/utils/logger.ts +11 -0
  211. package/src/utils/platformManager.ts +14 -0
  212. package/src/utils/validator.ts +29 -0
package/package.json ADDED
@@ -0,0 +1,184 @@
1
+ {
2
+ "name": "@savers_app/react-native-sandbox-sdk",
3
+ "version": "1.2.6",
4
+ "description": "Cross-platform React Native SDK exposing native features (maps, dial pad, browser), device ID/location and session utilities, a URL generator, and a WebView message bridge to trigger actions from web content.",
5
+ "main": "./lib/module/index.js",
6
+ "react-native": "./src/index.tsx",
7
+ "types": "./lib/typescript/src/index.d.ts",
8
+ "exports": {
9
+ ".": {
10
+ "source": "./src/index.tsx",
11
+ "types": "./lib/typescript/src/index.d.ts",
12
+ "default": "./lib/module/index.js"
13
+ },
14
+ "./package.json": "./package.json"
15
+ },
16
+ "files": [
17
+ "src",
18
+ "lib",
19
+ "android",
20
+ "ios",
21
+ "cpp",
22
+ "*.podspec",
23
+ "react-native.config.js",
24
+ "!ios/build",
25
+ "!android/build",
26
+ "!android/gradle",
27
+ "!android/gradlew",
28
+ "!android/gradlew.bat",
29
+ "!android/local.properties",
30
+ "!**/__tests__",
31
+ "!**/__fixtures__",
32
+ "!**/__mocks__",
33
+ "!**/.*"
34
+ ],
35
+ "scripts": {
36
+ "run:android": "yarn workspace @saversapp/react-native-sdk-example android",
37
+ "run:ios": "yarn workspace @saversapp/react-native-sdk-example ios",
38
+ "clean": "del-cli lib",
39
+ "prepare": "bob build",
40
+ "set:sandbox": "cross-env SDK_ENV=sandbox SDK_PACKAGE=@savers_app/react-native-sandbox-sdk node scripts/replace-config.js",
41
+ "set:production": "cross-env SDK_ENV=production SDK_PACKAGE=@savers_app/react-native-sdk node scripts/replace-config.js",
42
+ "prepare:sandbox": "yarn set:sandbox && yarn install && yarn prepare",
43
+ "prepare:production": "yarn set:production && yarn install && yarn prepare",
44
+ "typecheck": "tsc",
45
+ "lint": "eslint \"**/*.{js,ts,tsx}\"",
46
+ "test": "jest",
47
+ "release": "release-it --only-version"
48
+ },
49
+ "keywords": [
50
+ "react-native",
51
+ "ios",
52
+ "android"
53
+ ],
54
+ "repository": {
55
+ "type": "git",
56
+ "url": "git+https://github.com/pm-code/savers-react-native-sdk.git"
57
+ },
58
+ "author": "Faisal Wahab <faisalwahab@live.com> (https://github.com/pm-code)",
59
+ "license": "MIT",
60
+ "bugs": {
61
+ "url": "https://github.com/pm-code/savers-react-native-sdk/issues"
62
+ },
63
+ "homepage": "https://github.com/pm-code/savers-react-native-sdk#readme",
64
+ "publishConfig": {
65
+ "access": "public",
66
+ "registry": "https://registry.npmjs.org/"
67
+ },
68
+ "devDependencies": {
69
+ "@commitlint/config-conventional": "^19.8.1",
70
+ "@eslint/compat": "^1.3.2",
71
+ "@eslint/eslintrc": "^3.3.1",
72
+ "@eslint/js": "^9.35.0",
73
+ "@react-native-community/netinfo": "^11.5.2",
74
+ "@react-native/babel-preset": "0.83.0",
75
+ "@react-native/eslint-config": "0.83.0",
76
+ "@react-navigation/native": "^7.0.0",
77
+ "@release-it/conventional-changelog": "^10.0.1",
78
+ "@types/jest": "^29.5.14",
79
+ "@types/react": "^19.1.12",
80
+ "commitlint": "^19.8.1",
81
+ "cross-env": "^7.0.3",
82
+ "del-cli": "^6.0.0",
83
+ "eslint": "^9.35.0",
84
+ "eslint-config-prettier": "^10.1.8",
85
+ "eslint-plugin-prettier": "^5.5.4",
86
+ "jest": "^29.7.0",
87
+ "lefthook-darwin-arm64": "^2.1.3",
88
+ "prettier": "^3.8.1",
89
+ "react": "19.1.0",
90
+ "react-native": "0.81.5",
91
+ "react-native-builder-bob": "^0.40.13",
92
+ "release-it": "^19.0.4",
93
+ "typescript": "^5.9.2"
94
+ },
95
+ "peerDependencies": {
96
+ "@react-native-async-storage/async-storage": "*",
97
+ "@react-native-community/geolocation": "*",
98
+ "@react-native-community/netinfo": "*",
99
+ "@react-navigation/native": "*",
100
+ "react": "*",
101
+ "react-native": "*",
102
+ "react-native-aes-gcm-crypto": "*",
103
+ "react-native-device-info": "*"
104
+ },
105
+ "workspaces": [
106
+ "example",
107
+ "."
108
+ ],
109
+ "packageManager": "yarn@4.11.0",
110
+ "react-native-builder-bob": {
111
+ "source": "src",
112
+ "output": "lib",
113
+ "targets": [
114
+ [
115
+ "module",
116
+ {
117
+ "esm": true
118
+ }
119
+ ],
120
+ [
121
+ "typescript",
122
+ {
123
+ "project": "tsconfig.build.json"
124
+ }
125
+ ]
126
+ ]
127
+ },
128
+ "prettier": {
129
+ "quoteProps": "consistent",
130
+ "singleQuote": true,
131
+ "tabWidth": 2,
132
+ "trailingComma": "es5",
133
+ "useTabs": false
134
+ },
135
+ "jest": {
136
+ "preset": "react-native",
137
+ "modulePathIgnorePatterns": [
138
+ "<rootDir>/example/node_modules",
139
+ "<rootDir>/lib/"
140
+ ],
141
+ "moduleNameMapper": {
142
+ "^@savers_app/react-native-sdk$": "<rootDir>/src/index.tsx",
143
+ "^@savers_app/react-native-sandbox-sdk$": "<rootDir>/src/index.tsx",
144
+ "^react-native-device-info$": "<rootDir>/src/__mocks__/react-native-device-info.ts",
145
+ "^@react-native-community/geolocation$": "<rootDir>/src/__mocks__/@react-native-community__geolocation.ts",
146
+ "^@react-native-async-storage/async-storage$": "<rootDir>/src/__mocks__/@react-native-async-storage__async-storage.ts"
147
+ }
148
+ },
149
+ "commitlint": {
150
+ "extends": [
151
+ "@commitlint/config-conventional"
152
+ ]
153
+ },
154
+ "release-it": {
155
+ "git": {
156
+ "commitMessage": "chore: release ${version}",
157
+ "tagName": "v${version}"
158
+ },
159
+ "npm": {
160
+ "publish": true
161
+ },
162
+ "github": {
163
+ "release": true
164
+ },
165
+ "plugins": {
166
+ "@release-it/conventional-changelog": {
167
+ "preset": {
168
+ "name": "angular"
169
+ }
170
+ }
171
+ }
172
+ },
173
+ "create-react-native-library": {
174
+ "type": "library",
175
+ "languages": "js",
176
+ "tools": [
177
+ "eslint",
178
+ "jest",
179
+ "lefthook",
180
+ "release-it"
181
+ ],
182
+ "version": "0.56.1"
183
+ }
184
+ }
@@ -0,0 +1,7 @@
1
+ declare module '@react-native-async-storage/async-storage' {
2
+ const AsyncStorage: {
3
+ getItem(key: string): Promise<string | null>;
4
+ setItem(key: string, value: string): Promise<void>;
5
+ };
6
+ export = AsyncStorage;
7
+ }
@@ -0,0 +1,18 @@
1
+ declare module '@react-native-community/geolocation' {
2
+ type Position = {
3
+ coords: { latitude: number; longitude: number };
4
+ };
5
+ type Options = {
6
+ enableHighAccuracy?: boolean;
7
+ timeout?: number;
8
+ maximumAge?: number;
9
+ };
10
+ const Geolocation: {
11
+ getCurrentPosition(
12
+ success: (pos: Position) => void,
13
+ error?: (err: unknown) => void,
14
+ options?: Options
15
+ ): void;
16
+ };
17
+ export default Geolocation;
18
+ }
@@ -0,0 +1,22 @@
1
+ declare module 'react-native-aes-gcm-crypto' {
2
+ export type EncryptedData = {
3
+ iv: string;
4
+ tag: string;
5
+ content: string;
6
+ };
7
+ const AesGcmCrypto: {
8
+ encrypt(
9
+ plainText: string,
10
+ inBinary: boolean,
11
+ key: string
12
+ ): Promise<EncryptedData>;
13
+ decrypt(
14
+ base64Ciphertext: string,
15
+ key: string,
16
+ iv: string,
17
+ tag: string,
18
+ isBinary: boolean
19
+ ): Promise<string>;
20
+ };
21
+ export default AesGcmCrypto;
22
+ }
@@ -0,0 +1,3 @@
1
+ declare module 'react-native-device-info' {
2
+ export function getUniqueId(): Promise<string>;
3
+ }
@@ -0,0 +1,84 @@
1
+ // Utilities
2
+ import { logger } from '../utils/logger';
3
+ import { SDKRequirements } from '../utils/dependencyManager';
4
+
5
+ // Data / Storage
6
+ import {
7
+ setApiKey,
8
+ setEncryptionKey,
9
+ setPRefCode,
10
+ setAuthMode,
11
+ } from '../data/storage/keysManager';
12
+ import { getDeviceId } from '../data/storage/deviceIdManager';
13
+ import { setReactRef } from '../data/storage/reactRefManager';
14
+
15
+ // Services
16
+ // import { getDeviceLocation } from '../services/device/location';
17
+
18
+ export function initializeSDK(providedKeys: {
19
+ apiKey: string;
20
+ encryptionKey: string;
21
+ pRefCode: string;
22
+ authMode: string;
23
+ navigationRef: any;
24
+ }) {
25
+ const keys = providedKeys;
26
+ const missing: string[] = [];
27
+ if (!keys.apiKey) missing.push('apiKey');
28
+ if (!keys.encryptionKey) missing.push('encryptionKey');
29
+ if (!keys.pRefCode) missing.push('pRefCode');
30
+ if (!keys.authMode) missing.push('authMode');
31
+ if (!keys.navigationRef) missing.push('navigationRef');
32
+
33
+ if (missing.length) {
34
+ const msg = `[SDK] Missing required keys: ${missing.join(', ')}`;
35
+ logger.warn(msg);
36
+ throw new Error(msg);
37
+ }
38
+ setApiKey(keys.apiKey);
39
+ setEncryptionKey(keys.encryptionKey);
40
+ setPRefCode(keys.pRefCode);
41
+ setAuthMode(keys.authMode);
42
+ setReactRef(keys.navigationRef);
43
+
44
+ getDeviceId()
45
+ .then((id) => {
46
+ logger.info('[SDK] Device ID availability', { deviceId: Boolean(id) });
47
+ })
48
+ .catch(() => {
49
+ logger.warn('[SDK] Device ID unavailable');
50
+ });
51
+
52
+ // getDeviceLocation()
53
+ // .then((loc) => {
54
+ // logger.info('[SDK] Device location availability', {
55
+ // location: Boolean(loc),
56
+ // });
57
+ // })
58
+ // .catch(() => {
59
+ // logger.warn('[SDK] Device location unavailable');
60
+ // });
61
+
62
+ const { asyncStorage, geolocation, deviceInfo } = SDKRequirements;
63
+ if (asyncStorage && geolocation && deviceInfo) return;
64
+ if (!asyncStorage) {
65
+ logger.warn(
66
+ '[SDK] Missing AsyncStorage. Install @react-native-async-storage/async-storage for session/device features.'
67
+ );
68
+ }
69
+ if (!geolocation) {
70
+ logger.warn(
71
+ '[SDK] Missing Geolocation. Install @react-native-community/geolocation for location features.'
72
+ );
73
+ }
74
+
75
+ if (!deviceInfo) {
76
+ logger.warn(
77
+ '[SDK] Missing DeviceInfo. Install react-native-device-info for device identification.'
78
+ );
79
+ }
80
+ }
81
+
82
+ export const SaversAppSDK = {
83
+ initialized: initializeSDK,
84
+ };
@@ -0,0 +1,28 @@
1
+ export type ApiResponse<T> = {
2
+ data?: T | null;
3
+ status?: boolean;
4
+ message?: string;
5
+ fromCache: boolean;
6
+ };
7
+
8
+ export function apiError(message?: string): ApiResponse<null> {
9
+ return {
10
+ data: null,
11
+ status: false,
12
+ message: message ?? '',
13
+ fromCache: false,
14
+ };
15
+ }
16
+
17
+ export function apiSuccess<T>(
18
+ data: T,
19
+ message?: string,
20
+ fromCache?: boolean
21
+ ): ApiResponse<T> {
22
+ return {
23
+ data,
24
+ status: true,
25
+ message: message ?? '',
26
+ fromCache: !!fromCache,
27
+ };
28
+ }
@@ -0,0 +1,97 @@
1
+ export type OnBoardingImage = {
2
+ id?: number | null;
3
+ url?: string | null;
4
+ };
5
+
6
+ export function onBoardingImageFromJson(
7
+ json: Record<string, any>
8
+ ): OnBoardingImage {
9
+ return {
10
+ id: typeof json.id === 'number' ? json.id : null,
11
+ url: typeof json.url === 'string' ? json.url : null,
12
+ };
13
+ }
14
+
15
+ export function onBoardingImageListFromJson(list: any[]): OnBoardingImage[] {
16
+ const out: OnBoardingImage[] = [];
17
+ for (const item of list) {
18
+ if (item && typeof item === 'object' && !Array.isArray(item)) {
19
+ try {
20
+ out.push(onBoardingImageFromJson(item as Record<string, any>));
21
+ } catch {}
22
+ }
23
+ }
24
+ return out;
25
+ }
26
+
27
+ export type OnBoardingThemeData = {
28
+ total?: number | null;
29
+ images?: OnBoardingImage[] | null;
30
+ };
31
+
32
+ export function onBoardingThemeFromJson(json: any): OnBoardingThemeData {
33
+ const map = { ...(json as Record<string, any>) };
34
+ const imagesRaw = Array.isArray(map.images) ? (map.images as any[]) : [];
35
+ const images = onBoardingImageListFromJson(imagesRaw);
36
+ const total =
37
+ typeof map.total === 'number'
38
+ ? map.total
39
+ : typeof map.total === 'string'
40
+ ? Number(map.total)
41
+ : null;
42
+ return {
43
+ total: total ?? null,
44
+ images: images.length > 0 ? images : null,
45
+ };
46
+ }
47
+
48
+ export type OnBoardingData = {
49
+ day?: OnBoardingThemeData | null;
50
+ night?: OnBoardingThemeData | null;
51
+ };
52
+
53
+ export function onBoardingDataFromJson(json: any): OnBoardingData {
54
+ const map = { ...(json as Record<string, any>) };
55
+ const hasDayNight = 'day' in map || 'night' in map;
56
+ if (hasDayNight) {
57
+ const day = map.day ? onBoardingThemeFromJson(map.day) : null;
58
+ const night = map.night ? onBoardingThemeFromJson(map.night) : null;
59
+ return { day, night };
60
+ }
61
+ const legacyImages = Array.isArray(map.images)
62
+ ? onBoardingImageListFromJson(map.images as any[])
63
+ : [];
64
+ const legacyTotal =
65
+ typeof map.total === 'number'
66
+ ? map.total
67
+ : typeof map.total === 'string'
68
+ ? Number(map.total)
69
+ : null;
70
+ const legacyTheme: OnBoardingThemeData = {
71
+ total: legacyTotal ?? null,
72
+ images: legacyImages.length > 0 ? legacyImages : null,
73
+ };
74
+ return { day: legacyTheme, night: null };
75
+ }
76
+
77
+ export const images = (d?: OnBoardingData | null): OnBoardingImage[] | null =>
78
+ d?.day?.images ?? d?.night?.images ?? null;
79
+ export const total = (d?: OnBoardingData | null): number | null =>
80
+ d?.day?.total ?? d?.night?.total ?? null;
81
+ export const hasTotal = (d?: OnBoardingData | null): boolean =>
82
+ total(d) !== null;
83
+ export const hasImages = (d?: OnBoardingData | null): boolean =>
84
+ !!images(d) && (images(d)?.length ?? 0) > 0;
85
+ export const imageCount = (d?: OnBoardingData | null): number =>
86
+ images(d)?.length ?? 0;
87
+ export const isValid = (d?: OnBoardingData | null): boolean =>
88
+ !!(d?.day?.total && d?.day?.images) ||
89
+ !!(d?.night?.total && d?.night?.images);
90
+ export const getImage = (
91
+ d: OnBoardingData | null | undefined,
92
+ index: number
93
+ ): OnBoardingImage | null => {
94
+ const list = images(d);
95
+ if (list && index >= 0 && index < list.length) return list[index] ?? null;
96
+ return null;
97
+ };
@@ -0,0 +1,43 @@
1
+ export type TokenResponse = {
2
+ token?: string | null;
3
+ statusCode?: number | null;
4
+ error?: string | null;
5
+ messages?: string[] | null;
6
+ };
7
+
8
+ export function tokenResponseFromJson(json: any): TokenResponse {
9
+ const map = { ...(json as Record<string, any>) };
10
+ const token =
11
+ typeof map.token === 'string' && map.token.length > 0 ? map.token : null;
12
+ const statusCode =
13
+ typeof map.statusCode === 'number'
14
+ ? map.statusCode
15
+ : typeof map.statusCode === 'string'
16
+ ? Number(map.statusCode)
17
+ : null;
18
+ const error =
19
+ typeof map.error === 'string' && map.error.length > 0 ? map.error : null;
20
+ const messages = Array.isArray(map.message)
21
+ ? (map.message.filter((m: any) => typeof m === 'string') as string[])
22
+ : null;
23
+ return {
24
+ token: token ?? null,
25
+ statusCode: statusCode ?? null,
26
+ error: error ?? null,
27
+ messages: messages && messages.length > 0 ? messages : null,
28
+ };
29
+ }
30
+
31
+ export const token = (d?: TokenResponse | null): string | null =>
32
+ d?.token ?? null;
33
+ export const hasToken = (d?: TokenResponse | null): boolean =>
34
+ !!(d?.token && d.token.length > 0);
35
+ export const isValid = (d?: TokenResponse | null): boolean => hasToken(d);
36
+ export const status = (d?: TokenResponse | null): number | null =>
37
+ d?.statusCode ?? null;
38
+ export const error = (d?: TokenResponse | null): string | null =>
39
+ d?.error ?? null;
40
+ export const messages = (d?: TokenResponse | null): string[] | null =>
41
+ d?.messages ?? null;
42
+ export const hasError = (d?: TokenResponse | null): boolean =>
43
+ !!(d?.error || (d?.messages && d.messages.length > 0) || d?.statusCode);
@@ -0,0 +1,148 @@
1
+ /* eslint-disable prettier/prettier */
2
+
3
+ // Utilities / Helpers
4
+ import { logger } from '../../utils/logger';
5
+
6
+ // Services / API clients
7
+ import { AuthInterceptor } from './interceptors/authInterceptor';
8
+ import { RetryInterceptor } from './interceptors/retryInterceptor';
9
+ import { ErrorInterceptor } from './interceptors/errorInterceptor';
10
+ import { NetworkInterceptor } from './interceptors/networkInterceptor';
11
+ import { LoggingInterceptor } from './interceptors/loggingInterceptor';
12
+
13
+ export enum Environment {
14
+ production = 'production',
15
+ staging = 'staging',
16
+ }
17
+
18
+ export class ApiClient {
19
+ private static readonly baseUrls: Record<Environment, string> = {
20
+ [Environment.production]: 'https://devapi.saversapp.com/clo/v1/',
21
+ [Environment.staging]: 'https://devapi.saversapp.com/clo/v1/',
22
+ };
23
+
24
+ private baseUrl: string;
25
+ private interceptors: any[] = [];
26
+
27
+ constructor(environment: Environment = Environment.production) {
28
+ this.baseUrl = ApiClient.baseUrls[environment];
29
+
30
+ this.interceptors = [
31
+ new LoggingInterceptor(),
32
+ new NetworkInterceptor(),
33
+ new AuthInterceptor(),
34
+ new RetryInterceptor(2),
35
+ new ErrorInterceptor(),
36
+ ];
37
+ }
38
+
39
+ async get(endpoint: string, params?: Record<string, any>): Promise<any> {
40
+ return this.request('GET', endpoint, undefined, params);
41
+ }
42
+
43
+ async post(
44
+ endpoint: string,
45
+ data?: any,
46
+ params?: Record<string, any>
47
+ ): Promise<any> {
48
+ return this.request('POST', endpoint, data, params);
49
+ }
50
+
51
+ async put(
52
+ endpoint: string,
53
+ data?: any,
54
+ params?: Record<string, any>
55
+ ): Promise<any> {
56
+ return this.request('PUT', endpoint, data, params);
57
+ }
58
+
59
+ async delete(
60
+ endpoint: string,
61
+ data?: any,
62
+ params?: Record<string, any>
63
+ ): Promise<any> {
64
+ return this.request('DELETE', endpoint, data, params);
65
+ }
66
+
67
+ private async request(
68
+ method: string,
69
+ endpoint: string,
70
+ data?: any,
71
+ params?: Record<string, any>
72
+ ): Promise<any> {
73
+ const url = this.buildUrl(endpoint, params);
74
+ let options: any = {
75
+ method,
76
+ url,
77
+ headers: {
78
+ 'Content-Type': 'application/json',
79
+ },
80
+ body: data,
81
+ params, // kept for interceptors
82
+ };
83
+
84
+ // Apply request interceptors
85
+ for (const interceptor of this.interceptors) {
86
+ if (interceptor.onRequest) {
87
+ options = await interceptor.onRequest(options);
88
+ if (!options) throw new Error('Interceptor blocked request');
89
+ }
90
+ }
91
+
92
+ try {
93
+ const response = await fetch(options.url, {
94
+ method: options.method,
95
+ headers: options.headers,
96
+ body: options.body ? JSON.stringify(options.body) : undefined,
97
+ });
98
+
99
+ let responseData: any = null;
100
+ try {
101
+ responseData = await response.json();
102
+ } catch {
103
+ // ignore JSON parse error
104
+ }
105
+
106
+ // Apply response interceptors
107
+ let responseObj = {
108
+ data: responseData,
109
+ status: response.status,
110
+ statusText: response.statusText,
111
+ };
112
+
113
+ for (const interceptor of this.interceptors) {
114
+ if (interceptor.onResponse) {
115
+ responseObj = await interceptor.onResponse(responseObj);
116
+ }
117
+ }
118
+
119
+ return responseObj;
120
+ } catch (error) {
121
+ // Apply error interceptors
122
+ logger.error('API Request failed', error);
123
+ const handledError = error;
124
+ for (const interceptor of this.interceptors) {
125
+ if (interceptor.onError) {
126
+ // This is complex to mock fully without a real handler
127
+ // interceptor.onError(handledError, handler);
128
+ }
129
+ }
130
+ throw handledError;
131
+ }
132
+ }
133
+
134
+ private buildUrl(endpoint: string, params?: Record<string, any>): string {
135
+ let url = `${this.baseUrl}${endpoint}`;
136
+ if (params) {
137
+ const queryString = Object.keys(params)
138
+ .map(
139
+ (key) => `${encodeURIComponent(key)}=${encodeURIComponent(params[key])}`
140
+ )
141
+ .join('&');
142
+ if (queryString) {
143
+ url += `?${queryString}`;
144
+ }
145
+ }
146
+ return url;
147
+ }
148
+ }
@@ -0,0 +1,4 @@
1
+ export const ApiEndpoints = {
2
+ onboarding: 'on-boarding/listings',
3
+ get_nonce: 'sys/sys/c/s/t',
4
+ } as const;
@@ -0,0 +1,16 @@
1
+ export function getErrorMessage(status?: number, type?: string): string {
2
+ if (type === 'timeout') return 'Connection timeout. Please try again.';
3
+ if (type === 'sendtimeout') return 'Send timeout. Please try again.';
4
+ if (type === 'receivetimeout') return 'Receive timeout. Please try again.';
5
+ if (typeof status === 'number') {
6
+ if (status >= 400 && status < 500)
7
+ return `Request error [${status}]. Please check your input.`;
8
+ if (status >= 500)
9
+ return `Server error [${status}]. Please try again later.`;
10
+ }
11
+ return 'Something went wrong. Please try again.';
12
+ }
13
+
14
+ export function noInternetError(): string {
15
+ return 'No internet connection. Please check your network.';
16
+ }