@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.
- package/LICENSE +20 -0
- package/README.md +556 -0
- package/lib/module/@types/@react-native-async-storage__async-storage.d.js +2 -0
- package/lib/module/@types/@react-native-async-storage__async-storage.d.js.map +1 -0
- package/lib/module/@types/@react-native-community__geolocation.d.js +2 -0
- package/lib/module/@types/@react-native-community__geolocation.d.js.map +1 -0
- package/lib/module/@types/react-native-aes-gcm-crypto.d.js +2 -0
- package/lib/module/@types/react-native-aes-gcm-crypto.d.js.map +1 -0
- package/lib/module/@types/react-native-device-info.d.js +2 -0
- package/lib/module/@types/react-native-device-info.d.js.map +1 -0
- package/lib/module/core/runtime.js +70 -0
- package/lib/module/core/runtime.js.map +1 -0
- package/lib/module/data/models/apiResponse.js +19 -0
- package/lib/module/data/models/apiResponse.js.map +1 -0
- package/lib/module/data/models/onboardingModel.js +67 -0
- package/lib/module/data/models/onboardingModel.js.map +1 -0
- package/lib/module/data/models/tokenModel.js +25 -0
- package/lib/module/data/models/tokenModel.js.map +1 -0
- package/lib/module/data/network/apiClient.js +109 -0
- package/lib/module/data/network/apiClient.js.map +1 -0
- package/lib/module/data/network/apiEndpoints.js +7 -0
- package/lib/module/data/network/apiEndpoints.js.map +1 -0
- package/lib/module/data/network/apiExceptionHandler.js +16 -0
- package/lib/module/data/network/apiExceptionHandler.js.map +1 -0
- package/lib/module/data/network/apiRepository.js +84 -0
- package/lib/module/data/network/apiRepository.js.map +1 -0
- package/lib/module/data/network/apiService.js +102 -0
- package/lib/module/data/network/apiService.js.map +1 -0
- package/lib/module/data/network/dataTypeUtils.js +77 -0
- package/lib/module/data/network/dataTypeUtils.js.map +1 -0
- package/lib/module/data/network/interceptors/authInterceptor.js +72 -0
- package/lib/module/data/network/interceptors/authInterceptor.js.map +1 -0
- package/lib/module/data/network/interceptors/errorInterceptor.js +15 -0
- package/lib/module/data/network/interceptors/errorInterceptor.js.map +1 -0
- package/lib/module/data/network/interceptors/loggingInterceptor.js +17 -0
- package/lib/module/data/network/interceptors/loggingInterceptor.js.map +1 -0
- package/lib/module/data/network/interceptors/networkInterceptor.js +22 -0
- package/lib/module/data/network/interceptors/networkInterceptor.js.map +1 -0
- package/lib/module/data/network/interceptors/retryInterceptor.js +22 -0
- package/lib/module/data/network/interceptors/retryInterceptor.js.map +1 -0
- package/lib/module/data/storage/asyncStorageManager.js +50 -0
- package/lib/module/data/storage/asyncStorageManager.js.map +1 -0
- package/lib/module/data/storage/deviceIdManager.js +45 -0
- package/lib/module/data/storage/deviceIdManager.js.map +1 -0
- package/lib/module/data/storage/keysManager.js +70 -0
- package/lib/module/data/storage/keysManager.js.map +1 -0
- package/lib/module/data/storage/locationManager.js +30 -0
- package/lib/module/data/storage/locationManager.js.map +1 -0
- package/lib/module/data/storage/reactRefManager.js +22 -0
- package/lib/module/data/storage/reactRefManager.js.map +1 -0
- package/lib/module/data/storage/sessionManager.js +12 -0
- package/lib/module/data/storage/sessionManager.js.map +1 -0
- package/lib/module/data/storage/storageKeys.js +7 -0
- package/lib/module/data/storage/storageKeys.js.map +1 -0
- package/lib/module/data/storage/storageManager.js +76 -0
- package/lib/module/data/storage/storageManager.js.map +1 -0
- package/lib/module/index.js +20 -0
- package/lib/module/index.js.map +1 -0
- package/lib/module/package.json +1 -0
- package/lib/module/services/device/location.js +47 -0
- package/lib/module/services/device/location.js.map +1 -0
- package/lib/module/services/navigation/dialPad.js +29 -0
- package/lib/module/services/navigation/dialPad.js.map +1 -0
- package/lib/module/services/navigation/goBackNavigation.js +19 -0
- package/lib/module/services/navigation/goBackNavigation.js.map +1 -0
- package/lib/module/services/navigation/openBrowser.js +8 -0
- package/lib/module/services/navigation/openBrowser.js.map +1 -0
- package/lib/module/services/navigation/openMap.js +42 -0
- package/lib/module/services/navigation/openMap.js.map +1 -0
- package/lib/module/services/permissions/permissionManager.js +28 -0
- package/lib/module/services/permissions/permissionManager.js.map +1 -0
- package/lib/module/services/url/urlGenerator.js +94 -0
- package/lib/module/services/url/urlGenerator.js.map +1 -0
- package/lib/module/services/webview/messageHandler.js +72 -0
- package/lib/module/services/webview/messageHandler.js.map +1 -0
- package/lib/module/utils/config.js +34 -0
- package/lib/module/utils/config.js.map +1 -0
- package/lib/module/utils/dependencyManager.js +51 -0
- package/lib/module/utils/dependencyManager.js.map +1 -0
- package/lib/module/utils/encryption.js +63 -0
- package/lib/module/utils/encryption.js.map +1 -0
- package/lib/module/utils/errors.js +9 -0
- package/lib/module/utils/errors.js.map +1 -0
- package/lib/module/utils/logger.js +14 -0
- package/lib/module/utils/logger.js.map +1 -0
- package/lib/module/utils/platformManager.js +14 -0
- package/lib/module/utils/platformManager.js.map +1 -0
- package/lib/module/utils/validator.js +26 -0
- package/lib/module/utils/validator.js.map +1 -0
- package/lib/typescript/package.json +1 -0
- package/lib/typescript/src/core/runtime.d.ts +11 -0
- package/lib/typescript/src/core/runtime.d.ts.map +1 -0
- package/lib/typescript/src/data/models/apiResponse.d.ts +9 -0
- package/lib/typescript/src/data/models/apiResponse.d.ts.map +1 -0
- package/lib/typescript/src/data/models/onboardingModel.d.ts +24 -0
- package/lib/typescript/src/data/models/onboardingModel.d.ts.map +1 -0
- package/lib/typescript/src/data/models/tokenModel.d.ts +15 -0
- package/lib/typescript/src/data/models/tokenModel.d.ts.map +1 -0
- package/lib/typescript/src/data/network/apiClient.d.ts +17 -0
- package/lib/typescript/src/data/network/apiClient.d.ts.map +1 -0
- package/lib/typescript/src/data/network/apiEndpoints.d.ts +5 -0
- package/lib/typescript/src/data/network/apiEndpoints.d.ts.map +1 -0
- package/lib/typescript/src/data/network/apiExceptionHandler.d.ts +3 -0
- package/lib/typescript/src/data/network/apiExceptionHandler.d.ts.map +1 -0
- package/lib/typescript/src/data/network/apiRepository.d.ts +21 -0
- package/lib/typescript/src/data/network/apiRepository.d.ts.map +1 -0
- package/lib/typescript/src/data/network/apiService.d.ts +25 -0
- package/lib/typescript/src/data/network/apiService.d.ts.map +1 -0
- package/lib/typescript/src/data/network/dataTypeUtils.d.ts +10 -0
- package/lib/typescript/src/data/network/dataTypeUtils.d.ts.map +1 -0
- package/lib/typescript/src/data/network/interceptors/authInterceptor.d.ts +15 -0
- package/lib/typescript/src/data/network/interceptors/authInterceptor.d.ts.map +1 -0
- package/lib/typescript/src/data/network/interceptors/errorInterceptor.d.ts +4 -0
- package/lib/typescript/src/data/network/interceptors/errorInterceptor.d.ts.map +1 -0
- package/lib/typescript/src/data/network/interceptors/loggingInterceptor.d.ts +5 -0
- package/lib/typescript/src/data/network/interceptors/loggingInterceptor.d.ts.map +1 -0
- package/lib/typescript/src/data/network/interceptors/networkInterceptor.d.ts +4 -0
- package/lib/typescript/src/data/network/interceptors/networkInterceptor.d.ts.map +1 -0
- package/lib/typescript/src/data/network/interceptors/retryInterceptor.d.ts +7 -0
- package/lib/typescript/src/data/network/interceptors/retryInterceptor.d.ts.map +1 -0
- package/lib/typescript/src/data/storage/asyncStorageManager.d.ts +13 -0
- package/lib/typescript/src/data/storage/asyncStorageManager.d.ts.map +1 -0
- package/lib/typescript/src/data/storage/deviceIdManager.d.ts +2 -0
- package/lib/typescript/src/data/storage/deviceIdManager.d.ts.map +1 -0
- package/lib/typescript/src/data/storage/keysManager.d.ts +29 -0
- package/lib/typescript/src/data/storage/keysManager.d.ts.map +1 -0
- package/lib/typescript/src/data/storage/locationManager.d.ts +21 -0
- package/lib/typescript/src/data/storage/locationManager.d.ts.map +1 -0
- package/lib/typescript/src/data/storage/reactRefManager.d.ts +11 -0
- package/lib/typescript/src/data/storage/reactRefManager.d.ts.map +1 -0
- package/lib/typescript/src/data/storage/sessionManager.d.ts +3 -0
- package/lib/typescript/src/data/storage/sessionManager.d.ts.map +1 -0
- package/lib/typescript/src/data/storage/storageKeys.d.ts +5 -0
- package/lib/typescript/src/data/storage/storageKeys.d.ts.map +1 -0
- package/lib/typescript/src/data/storage/storageManager.d.ts +16 -0
- package/lib/typescript/src/data/storage/storageManager.d.ts.map +1 -0
- package/lib/typescript/src/index.d.ts +18 -0
- package/lib/typescript/src/index.d.ts.map +1 -0
- package/lib/typescript/src/services/device/location.d.ts +8 -0
- package/lib/typescript/src/services/device/location.d.ts.map +1 -0
- package/lib/typescript/src/services/navigation/dialPad.d.ts +3 -0
- package/lib/typescript/src/services/navigation/dialPad.d.ts.map +1 -0
- package/lib/typescript/src/services/navigation/goBackNavigation.d.ts +3 -0
- package/lib/typescript/src/services/navigation/goBackNavigation.d.ts.map +1 -0
- package/lib/typescript/src/services/navigation/openBrowser.d.ts +2 -0
- package/lib/typescript/src/services/navigation/openBrowser.d.ts.map +1 -0
- package/lib/typescript/src/services/navigation/openMap.d.ts +2 -0
- package/lib/typescript/src/services/navigation/openMap.d.ts.map +1 -0
- package/lib/typescript/src/services/permissions/permissionManager.d.ts +4 -0
- package/lib/typescript/src/services/permissions/permissionManager.d.ts.map +1 -0
- package/lib/typescript/src/services/url/urlGenerator.d.ts +44 -0
- package/lib/typescript/src/services/url/urlGenerator.d.ts.map +1 -0
- package/lib/typescript/src/services/webview/messageHandler.d.ts +2 -0
- package/lib/typescript/src/services/webview/messageHandler.d.ts.map +1 -0
- package/lib/typescript/src/utils/config.d.ts +5 -0
- package/lib/typescript/src/utils/config.d.ts.map +1 -0
- package/lib/typescript/src/utils/dependencyManager.d.ts +31 -0
- package/lib/typescript/src/utils/dependencyManager.d.ts.map +1 -0
- package/lib/typescript/src/utils/encryption.d.ts +5 -0
- package/lib/typescript/src/utils/encryption.d.ts.map +1 -0
- package/lib/typescript/src/utils/errors.d.ts +4 -0
- package/lib/typescript/src/utils/errors.d.ts.map +1 -0
- package/lib/typescript/src/utils/logger.d.ts +6 -0
- package/lib/typescript/src/utils/logger.d.ts.map +1 -0
- package/lib/typescript/src/utils/platformManager.d.ts +4 -0
- package/lib/typescript/src/utils/platformManager.d.ts.map +1 -0
- package/lib/typescript/src/utils/validator.d.ts +4 -0
- package/lib/typescript/src/utils/validator.d.ts.map +1 -0
- package/package.json +184 -0
- package/src/@types/@react-native-async-storage__async-storage.d.ts +7 -0
- package/src/@types/@react-native-community__geolocation.d.ts +18 -0
- package/src/@types/react-native-aes-gcm-crypto.d.ts +22 -0
- package/src/@types/react-native-device-info.d.ts +3 -0
- package/src/core/runtime.ts +84 -0
- package/src/data/models/apiResponse.ts +28 -0
- package/src/data/models/onboardingModel.ts +97 -0
- package/src/data/models/tokenModel.ts +43 -0
- package/src/data/network/apiClient.ts +148 -0
- package/src/data/network/apiEndpoints.ts +4 -0
- package/src/data/network/apiExceptionHandler.ts +16 -0
- package/src/data/network/apiRepository.ts +130 -0
- package/src/data/network/apiService.ts +113 -0
- package/src/data/network/dataTypeUtils.ts +78 -0
- package/src/data/network/interceptors/authInterceptor.ts +86 -0
- package/src/data/network/interceptors/errorInterceptor.ts +13 -0
- package/src/data/network/interceptors/loggingInterceptor.ts +16 -0
- package/src/data/network/interceptors/networkInterceptor.ts +20 -0
- package/src/data/network/interceptors/retryInterceptor.ts +24 -0
- package/src/data/storage/asyncStorageManager.ts +56 -0
- package/src/data/storage/deviceIdManager.ts +46 -0
- package/src/data/storage/keysManager.ts +89 -0
- package/src/data/storage/locationManager.ts +39 -0
- package/src/data/storage/reactRefManager.ts +25 -0
- package/src/data/storage/sessionManager.ts +11 -0
- package/src/data/storage/storageKeys.ts +4 -0
- package/src/data/storage/storageManager.ts +83 -0
- package/src/index.tsx +17 -0
- package/src/services/device/location.ts +51 -0
- package/src/services/navigation/dialPad.ts +39 -0
- package/src/services/navigation/goBackNavigation.ts +19 -0
- package/src/services/navigation/openBrowser.ts +6 -0
- package/src/services/navigation/openMap.ts +53 -0
- package/src/services/permissions/permissionManager.ts +33 -0
- package/src/services/url/urlGenerator.ts +140 -0
- package/src/services/webview/messageHandler.ts +45 -0
- package/src/utils/config.ts +35 -0
- package/src/utils/dependencyManager.ts +82 -0
- package/src/utils/encryption.ts +96 -0
- package/src/utils/errors.ts +6 -0
- package/src/utils/logger.ts +11 -0
- package/src/utils/platformManager.ts +14 -0
- 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,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,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,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
|
+
}
|