@oxyhq/services 5.19.0 → 5.20.0
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/README.md +51 -42
- package/lib/commonjs/ui/components/OxyProvider.js +106 -40
- package/lib/commonjs/ui/components/OxyProvider.js.map +1 -1
- package/lib/commonjs/ui/components/WebOxyProvider.js +9 -10
- package/lib/commonjs/ui/components/WebOxyProvider.js.map +1 -1
- package/lib/module/ui/components/OxyProvider.js +106 -39
- package/lib/module/ui/components/OxyProvider.js.map +1 -1
- package/lib/module/ui/components/WebOxyProvider.js +9 -10
- package/lib/module/ui/components/WebOxyProvider.js.map +1 -1
- package/lib/typescript/commonjs/ui/components/OxyProvider.d.ts +26 -3
- package/lib/typescript/commonjs/ui/components/OxyProvider.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/components/WebOxyProvider.d.ts +9 -10
- package/lib/typescript/commonjs/ui/components/WebOxyProvider.d.ts.map +1 -1
- package/lib/typescript/module/ui/components/OxyProvider.d.ts +26 -3
- package/lib/typescript/module/ui/components/OxyProvider.d.ts.map +1 -1
- package/lib/typescript/module/ui/components/WebOxyProvider.d.ts +9 -10
- package/lib/typescript/module/ui/components/WebOxyProvider.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/ui/components/OxyProvider.tsx +112 -47
- package/src/ui/components/WebOxyProvider.tsx +9 -10
package/README.md
CHANGED
|
@@ -22,12 +22,13 @@ A comprehensive TypeScript client library for the Oxy API providing authenticati
|
|
|
22
22
|
## ✨ Features
|
|
23
23
|
|
|
24
24
|
- 🔐 **Zero-Config Authentication**: Automatic token management and refresh
|
|
25
|
-
-
|
|
26
|
-
-
|
|
27
|
-
-
|
|
25
|
+
- 🌐 **Cross-Domain SSO**: Sign in once, authenticated everywhere (FedCM-based)
|
|
26
|
+
- 📱 **Universal Provider**: Single `OxyProvider` works on iOS, Android, and Web
|
|
27
|
+
- 🎨 **UI Components**: Pre-built components for auth, profiles, and more
|
|
28
|
+
- 🔄 **Cross-Platform**: Works in Expo, React Native, and Node.js
|
|
28
29
|
- 📱 **Multi-Session Support**: Manage multiple user sessions simultaneously
|
|
29
30
|
- 🔧 **TypeScript First**: Full type safety and IntelliSense support
|
|
30
|
-
- 🚀 **Performance Optimized**: Automatic caching
|
|
31
|
+
- 🚀 **Performance Optimized**: Automatic caching with TanStack Query
|
|
31
32
|
- 🛡️ **Production Ready**: Error handling, retry logic, and security best practices
|
|
32
33
|
|
|
33
34
|
## 📦 Installation
|
|
@@ -65,10 +66,10 @@ import 'react-native-url-polyfill/auto';
|
|
|
65
66
|
|
|
66
67
|
## 🚀 Quick Start
|
|
67
68
|
|
|
68
|
-
###
|
|
69
|
+
### Expo Apps (Native + Web)
|
|
69
70
|
|
|
70
71
|
```typescript
|
|
71
|
-
import { OxyProvider,
|
|
72
|
+
import { OxyProvider, useAuth } from '@oxyhq/services';
|
|
72
73
|
|
|
73
74
|
function App() {
|
|
74
75
|
return (
|
|
@@ -79,13 +80,32 @@ function App() {
|
|
|
79
80
|
}
|
|
80
81
|
|
|
81
82
|
function UserProfile() {
|
|
82
|
-
const {
|
|
83
|
-
|
|
83
|
+
const { user, isAuthenticated, signIn, signOut } = useAuth();
|
|
84
|
+
|
|
84
85
|
if (!isAuthenticated) {
|
|
85
|
-
return <
|
|
86
|
+
return <Button onPress={() => signIn()} title="Sign In" />;
|
|
86
87
|
}
|
|
87
|
-
|
|
88
|
-
return
|
|
88
|
+
|
|
89
|
+
return (
|
|
90
|
+
<View>
|
|
91
|
+
<Text>Welcome, {user?.username}!</Text>
|
|
92
|
+
<Button onPress={signOut} title="Sign Out" />
|
|
93
|
+
</View>
|
|
94
|
+
);
|
|
95
|
+
}
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
### Pure React/Next.js (No Expo)
|
|
99
|
+
|
|
100
|
+
```typescript
|
|
101
|
+
import { WebOxyProvider, useAuth } from '@oxyhq/services';
|
|
102
|
+
|
|
103
|
+
function App() {
|
|
104
|
+
return (
|
|
105
|
+
<WebOxyProvider baseURL="https://api.oxy.so">
|
|
106
|
+
<YourApp />
|
|
107
|
+
</WebOxyProvider>
|
|
108
|
+
);
|
|
89
109
|
}
|
|
90
110
|
```
|
|
91
111
|
|
|
@@ -129,19 +149,19 @@ app.listen(3000);
|
|
|
129
149
|
|
|
130
150
|
## 📖 Usage Patterns
|
|
131
151
|
|
|
132
|
-
###
|
|
152
|
+
### Expo Apps (Native + Web)
|
|
133
153
|
|
|
134
|
-
#### 1. **OxyProvider +
|
|
154
|
+
#### 1. **OxyProvider + useAuth Hook (Recommended)**
|
|
135
155
|
|
|
136
|
-
|
|
156
|
+
`OxyProvider` works on all platforms (iOS, Android, Web). Use `useAuth` for authentication.
|
|
137
157
|
|
|
138
158
|
```typescript
|
|
139
|
-
import { OxyProvider,
|
|
159
|
+
import { OxyProvider, useAuth, OxySignInButton } from '@oxyhq/services';
|
|
140
160
|
|
|
141
161
|
// App.tsx - Setup the provider
|
|
142
162
|
function App() {
|
|
143
163
|
return (
|
|
144
|
-
<OxyProvider
|
|
164
|
+
<OxyProvider
|
|
145
165
|
baseURL="https://api.oxy.so"
|
|
146
166
|
onAuthStateChange={(user) => {
|
|
147
167
|
console.log('Auth state changed:', user ? 'logged in' : 'logged out');
|
|
@@ -154,36 +174,25 @@ function App() {
|
|
|
154
174
|
|
|
155
175
|
// Component.tsx - Use the hook
|
|
156
176
|
function UserProfile() {
|
|
157
|
-
const {
|
|
158
|
-
oxyServices, // OxyServices instance
|
|
159
|
-
user, // Current user data
|
|
160
|
-
isAuthenticated, // Authentication state
|
|
161
|
-
login, // Login method
|
|
162
|
-
logout // Logout method
|
|
163
|
-
} = useOxy();
|
|
177
|
+
const { user, isAuthenticated, signIn, signOut, isLoading } = useAuth();
|
|
164
178
|
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
179
|
+
if (isLoading) return <ActivityIndicator />;
|
|
180
|
+
|
|
181
|
+
if (!isAuthenticated) {
|
|
182
|
+
return (
|
|
183
|
+
<View>
|
|
184
|
+
<Text>Welcome! Please sign in.</Text>
|
|
185
|
+
<OxySignInButton />
|
|
186
|
+
{/* Or use signIn() directly: */}
|
|
187
|
+
<Button onPress={() => signIn()} title="Sign In" />
|
|
188
|
+
</View>
|
|
189
|
+
);
|
|
190
|
+
}
|
|
172
191
|
|
|
173
192
|
return (
|
|
174
193
|
<View>
|
|
175
|
-
{
|
|
176
|
-
|
|
177
|
-
<Text style={styles.title}>Welcome, {user?.name}!</Text>
|
|
178
|
-
<TouchableOpacity onPress={logout} style={styles.button}>
|
|
179
|
-
<Text>Sign Out</Text>
|
|
180
|
-
</TouchableOpacity>
|
|
181
|
-
</View>
|
|
182
|
-
) : (
|
|
183
|
-
<TouchableOpacity onPress={handleLogin} style={styles.button}>
|
|
184
|
-
<Text>Sign In</Text>
|
|
185
|
-
</TouchableOpacity>
|
|
186
|
-
)}
|
|
194
|
+
<Text style={styles.title}>Welcome, {user?.username}!</Text>
|
|
195
|
+
<Button onPress={signOut} title="Sign Out" />
|
|
187
196
|
</View>
|
|
188
197
|
);
|
|
189
198
|
}
|
|
@@ -8,24 +8,62 @@ var _react = require("react");
|
|
|
8
8
|
var _reactNative = require("react-native");
|
|
9
9
|
var _reactNativeGestureHandler = require("react-native-gesture-handler");
|
|
10
10
|
var _reactNativeSafeAreaContext = require("react-native-safe-area-context");
|
|
11
|
-
var _reactNativeKeyboardController = require("react-native-keyboard-controller");
|
|
12
11
|
var _OxyContext = require("../context/OxyContext.js");
|
|
13
12
|
var _reactQuery = require("@tanstack/react-query");
|
|
14
13
|
var _FontLoader = require("./FontLoader.js");
|
|
15
|
-
var _BottomSheetRouter = _interopRequireDefault(require("./BottomSheetRouter.js"));
|
|
16
14
|
var _sonner = require("../../lib/sonner.js");
|
|
17
15
|
var _queryClient = require("../hooks/queryClient.js");
|
|
18
16
|
var _storageHelpers = require("../utils/storageHelpers.js");
|
|
19
17
|
var _jsxRuntime = require("react/jsx-runtime");
|
|
20
|
-
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
21
18
|
function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function (e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (const t in e) "default" !== t && {}.hasOwnProperty.call(e, t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, t)) && (i.get || i.set) ? o(f, t, i) : f[t] = e[t]); return f; })(e, t); } // Initialize fonts automatically
|
|
22
19
|
(0, _FontLoader.setupFonts)();
|
|
23
20
|
|
|
21
|
+
// Detect if running on web
|
|
22
|
+
const isWeb = _reactNative.Platform.OS === 'web';
|
|
23
|
+
|
|
24
|
+
// Conditionally import native-only components
|
|
25
|
+
let KeyboardProvider = ({
|
|
26
|
+
children
|
|
27
|
+
}) => children;
|
|
28
|
+
let BottomSheetRouter = () => null;
|
|
29
|
+
if (!isWeb) {
|
|
30
|
+
try {
|
|
31
|
+
// Only import on native platforms
|
|
32
|
+
KeyboardProvider = require('react-native-keyboard-controller').KeyboardProvider;
|
|
33
|
+
BottomSheetRouter = require('./BottomSheetRouter').default;
|
|
34
|
+
} catch {
|
|
35
|
+
// Fallback if imports fail
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
24
39
|
/**
|
|
25
|
-
* OxyProvider
|
|
40
|
+
* OxyProvider - Universal provider for Expo apps (native + web)
|
|
41
|
+
*
|
|
42
|
+
* Zero-config authentication and session management:
|
|
43
|
+
* - Native (iOS/Android): Keychain-based identity, bottom sheet auth UI
|
|
44
|
+
* - Web: FedCM cross-domain SSO, popup fallback
|
|
45
|
+
*
|
|
46
|
+
* Usage:
|
|
47
|
+
* ```tsx
|
|
48
|
+
* import { OxyProvider, useAuth } from '@oxyhq/services';
|
|
26
49
|
*
|
|
27
|
-
*
|
|
28
|
-
*
|
|
50
|
+
* function App() {
|
|
51
|
+
* return (
|
|
52
|
+
* <OxyProvider baseURL="https://api.oxy.so">
|
|
53
|
+
* <YourApp />
|
|
54
|
+
* </OxyProvider>
|
|
55
|
+
* );
|
|
56
|
+
* }
|
|
57
|
+
*
|
|
58
|
+
* function MyComponent() {
|
|
59
|
+
* const { isAuthenticated, user, signIn, signOut } = useAuth();
|
|
60
|
+
*
|
|
61
|
+
* if (!isAuthenticated) {
|
|
62
|
+
* return <OxySignInButton />;
|
|
63
|
+
* }
|
|
64
|
+
* return <Text>Welcome, {user?.username}!</Text>;
|
|
65
|
+
* }
|
|
66
|
+
* ```
|
|
29
67
|
*/
|
|
30
68
|
const OxyProvider = ({
|
|
31
69
|
oxyServices,
|
|
@@ -73,14 +111,26 @@ const OxyProvider = ({
|
|
|
73
111
|
};
|
|
74
112
|
}, [providedQueryClient]);
|
|
75
113
|
|
|
76
|
-
// Hook React Query focus manager into
|
|
114
|
+
// Hook React Query focus manager into app state (native) or visibility (web)
|
|
77
115
|
(0, _react.useEffect)(() => {
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
116
|
+
if (isWeb) {
|
|
117
|
+
// Web: use document visibility
|
|
118
|
+
const handleVisibilityChange = () => {
|
|
119
|
+
_reactQuery.focusManager.setFocused(document.visibilityState === 'visible');
|
|
120
|
+
};
|
|
121
|
+
document.addEventListener('visibilitychange', handleVisibilityChange);
|
|
122
|
+
return () => {
|
|
123
|
+
document.removeEventListener('visibilitychange', handleVisibilityChange);
|
|
124
|
+
};
|
|
125
|
+
} else {
|
|
126
|
+
// Native: use AppState
|
|
127
|
+
const subscription = _reactNative.AppState.addEventListener('change', state => {
|
|
128
|
+
_reactQuery.focusManager.setFocused(state === 'active');
|
|
129
|
+
});
|
|
130
|
+
return () => {
|
|
131
|
+
subscription.remove();
|
|
132
|
+
};
|
|
133
|
+
}
|
|
84
134
|
}, []);
|
|
85
135
|
|
|
86
136
|
// Setup network status monitoring for offline detection
|
|
@@ -88,8 +138,19 @@ const OxyProvider = ({
|
|
|
88
138
|
let cleanup;
|
|
89
139
|
const setupNetworkMonitoring = async () => {
|
|
90
140
|
try {
|
|
91
|
-
|
|
92
|
-
|
|
141
|
+
if (isWeb) {
|
|
142
|
+
// Web: use navigator.onLine
|
|
143
|
+
_reactQuery.onlineManager.setOnline(navigator.onLine);
|
|
144
|
+
const handleOnline = () => _reactQuery.onlineManager.setOnline(true);
|
|
145
|
+
const handleOffline = () => _reactQuery.onlineManager.setOnline(false);
|
|
146
|
+
window.addEventListener('online', handleOnline);
|
|
147
|
+
window.addEventListener('offline', handleOffline);
|
|
148
|
+
cleanup = () => {
|
|
149
|
+
window.removeEventListener('online', handleOnline);
|
|
150
|
+
window.removeEventListener('offline', handleOffline);
|
|
151
|
+
};
|
|
152
|
+
} else {
|
|
153
|
+
// Native: try to use NetInfo
|
|
93
154
|
try {
|
|
94
155
|
const NetInfo = await Promise.resolve().then(() => _interopRequireWildcard(require('@react-native-community/netinfo')));
|
|
95
156
|
const state = await NetInfo.default.fetch();
|
|
@@ -102,17 +163,6 @@ const OxyProvider = ({
|
|
|
102
163
|
// NetInfo not available, default to online
|
|
103
164
|
_reactQuery.onlineManager.setOnline(true);
|
|
104
165
|
}
|
|
105
|
-
} else {
|
|
106
|
-
// For web, use navigator.onLine
|
|
107
|
-
_reactQuery.onlineManager.setOnline(navigator.onLine);
|
|
108
|
-
const handleOnline = () => _reactQuery.onlineManager.setOnline(true);
|
|
109
|
-
const handleOffline = () => _reactQuery.onlineManager.setOnline(false);
|
|
110
|
-
window.addEventListener('online', handleOnline);
|
|
111
|
-
window.addEventListener('offline', handleOffline);
|
|
112
|
-
cleanup = () => {
|
|
113
|
-
window.removeEventListener('online', handleOnline);
|
|
114
|
-
window.removeEventListener('offline', handleOffline);
|
|
115
|
-
};
|
|
116
166
|
}
|
|
117
167
|
} catch (error) {
|
|
118
168
|
// Default to online if detection fails
|
|
@@ -127,27 +177,43 @@ const OxyProvider = ({
|
|
|
127
177
|
|
|
128
178
|
// Ensure we have a valid QueryClient
|
|
129
179
|
if (!queryClient) {
|
|
130
|
-
// Return loading state or fallback
|
|
131
180
|
return null;
|
|
132
181
|
}
|
|
182
|
+
|
|
183
|
+
// Core content that works on all platforms
|
|
184
|
+
const coreContent = /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactQuery.QueryClientProvider, {
|
|
185
|
+
client: queryClient,
|
|
186
|
+
children: /*#__PURE__*/(0, _jsxRuntime.jsxs)(_OxyContext.OxyContextProvider, {
|
|
187
|
+
oxyServices: oxyServices,
|
|
188
|
+
baseURL: baseURL,
|
|
189
|
+
authWebUrl: authWebUrl,
|
|
190
|
+
authRedirectUri: authRedirectUri,
|
|
191
|
+
storageKeyPrefix: storageKeyPrefix,
|
|
192
|
+
onAuthStateChange: onAuthStateChange,
|
|
193
|
+
children: [children, !isWeb && /*#__PURE__*/(0, _jsxRuntime.jsx)(BottomSheetRouter, {}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_sonner.Toaster, {})]
|
|
194
|
+
})
|
|
195
|
+
});
|
|
196
|
+
|
|
197
|
+
// On web, minimal wrappers (GestureHandler and SafeArea work via react-native-web)
|
|
198
|
+
if (isWeb) {
|
|
199
|
+
return /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNativeSafeAreaContext.SafeAreaProvider, {
|
|
200
|
+
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNativeGestureHandler.GestureHandlerRootView, {
|
|
201
|
+
style: {
|
|
202
|
+
flex: 1
|
|
203
|
+
},
|
|
204
|
+
children: coreContent
|
|
205
|
+
})
|
|
206
|
+
});
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
// On native, full wrappers including KeyboardProvider
|
|
133
210
|
return /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNativeSafeAreaContext.SafeAreaProvider, {
|
|
134
211
|
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNativeGestureHandler.GestureHandlerRootView, {
|
|
135
212
|
style: {
|
|
136
213
|
flex: 1
|
|
137
214
|
},
|
|
138
|
-
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(
|
|
139
|
-
children:
|
|
140
|
-
client: queryClient,
|
|
141
|
-
children: /*#__PURE__*/(0, _jsxRuntime.jsxs)(_OxyContext.OxyContextProvider, {
|
|
142
|
-
oxyServices: oxyServices,
|
|
143
|
-
baseURL: baseURL,
|
|
144
|
-
authWebUrl: authWebUrl,
|
|
145
|
-
authRedirectUri: authRedirectUri,
|
|
146
|
-
storageKeyPrefix: storageKeyPrefix,
|
|
147
|
-
onAuthStateChange: onAuthStateChange,
|
|
148
|
-
children: [children, /*#__PURE__*/(0, _jsxRuntime.jsx)(_BottomSheetRouter.default, {}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_sonner.Toaster, {})]
|
|
149
|
-
})
|
|
150
|
-
})
|
|
215
|
+
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(KeyboardProvider, {
|
|
216
|
+
children: coreContent
|
|
151
217
|
})
|
|
152
218
|
})
|
|
153
219
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["_react","require","_reactNative","_reactNativeGestureHandler","_reactNativeSafeAreaContext","
|
|
1
|
+
{"version":3,"names":["_react","require","_reactNative","_reactNativeGestureHandler","_reactNativeSafeAreaContext","_OxyContext","_reactQuery","_FontLoader","_sonner","_queryClient","_storageHelpers","_jsxRuntime","_interopRequireWildcard","e","t","WeakMap","r","n","__esModule","o","i","f","__proto__","default","has","get","set","hasOwnProperty","call","Object","defineProperty","getOwnPropertyDescriptor","setupFonts","isWeb","Platform","OS","KeyboardProvider","children","BottomSheetRouter","OxyProvider","oxyServices","onAuthStateChange","storageKeyPrefix","baseURL","authWebUrl","authRedirectUri","queryClient","providedQueryClient","storageRef","useRef","queryClientRef","setQueryClient","useState","useEffect","current","mounted","createPlatformStorage","then","storage","client","createQueryClient","catch","error","__DEV__","console","warn","handleVisibilityChange","focusManager","setFocused","document","visibilityState","addEventListener","removeEventListener","subscription","AppState","state","remove","cleanup","setupNetworkMonitoring","onlineManager","setOnline","navigator","onLine","handleOnline","handleOffline","window","NetInfo","Promise","resolve","fetch","isConnected","unsubscribe","coreContent","jsx","QueryClientProvider","jsxs","OxyContextProvider","Toaster","SafeAreaProvider","GestureHandlerRootView","style","flex","_default","exports"],"sourceRoot":"../../../../src","sources":["ui/components/OxyProvider.tsx"],"mappings":"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","ignoreList":[]}
|
|
@@ -11,18 +11,20 @@ var _queryClient = require("../hooks/queryClient.js");
|
|
|
11
11
|
var _storageHelpers = require("../utils/storageHelpers.js");
|
|
12
12
|
var _jsxRuntime = require("react/jsx-runtime");
|
|
13
13
|
/**
|
|
14
|
-
* WebOxyProvider -
|
|
14
|
+
* WebOxyProvider - Lightweight provider for pure React/Next.js apps
|
|
15
15
|
*
|
|
16
|
-
*
|
|
17
|
-
*
|
|
16
|
+
* Use this provider for web apps that DON'T use Expo/React Native.
|
|
17
|
+
* For Expo apps (native + web), use `OxyProvider` instead - it works on all platforms.
|
|
18
|
+
*
|
|
19
|
+
* Features:
|
|
18
20
|
* - Automatic cross-domain SSO via FedCM (Chrome 108+, Safari 16.4+, Edge 108+)
|
|
21
|
+
* - No React Native dependencies
|
|
19
22
|
* - Session management
|
|
20
23
|
* - All useOxy/useAuth functionality
|
|
21
24
|
*
|
|
22
|
-
* Zero-config: Just wrap your app and SSO works automatically across domains.
|
|
23
|
-
*
|
|
24
25
|
* Usage:
|
|
25
26
|
* ```tsx
|
|
27
|
+
* // For pure React/Next.js apps (no Expo):
|
|
26
28
|
* import { WebOxyProvider, useAuth } from '@oxyhq/services';
|
|
27
29
|
*
|
|
28
30
|
* function App() {
|
|
@@ -33,11 +35,8 @@ var _jsxRuntime = require("react/jsx-runtime");
|
|
|
33
35
|
* );
|
|
34
36
|
* }
|
|
35
37
|
*
|
|
36
|
-
*
|
|
37
|
-
*
|
|
38
|
-
* if (isAuthenticated) return <span>Welcome, {user?.username}!</span>;
|
|
39
|
-
* return <button onClick={() => signIn()}>Sign In</button>;
|
|
40
|
-
* }
|
|
38
|
+
* // For Expo apps (native + web), use OxyProvider instead:
|
|
39
|
+
* import { OxyProvider, useAuth } from '@oxyhq/services';
|
|
41
40
|
* ```
|
|
42
41
|
*/
|
|
43
42
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["_react","require","_OxyContext","_reactQuery","_queryClient","_storageHelpers","_jsxRuntime","WebOxyProvider","children","baseURL","authWebUrl","onAuthStateChange","storageKeyPrefix","queryClient","providedQueryClient","storageRef","useRef","queryClientRef","setQueryClient","useState","useEffect","current","mounted","createPlatformStorage","then","storage","client","createQueryClient","catch","jsx","QueryClientProvider","OxyContextProvider","_default","exports","default"],"sourceRoot":"../../../../src","sources":["ui/components/WebOxyProvider.tsx"],"mappings":";;;;;;
|
|
1
|
+
{"version":3,"names":["_react","require","_OxyContext","_reactQuery","_queryClient","_storageHelpers","_jsxRuntime","WebOxyProvider","children","baseURL","authWebUrl","onAuthStateChange","storageKeyPrefix","queryClient","providedQueryClient","storageRef","useRef","queryClientRef","setQueryClient","useState","useEffect","current","mounted","createPlatformStorage","then","storage","client","createQueryClient","catch","jsx","QueryClientProvider","OxyContextProvider","_default","exports","default"],"sourceRoot":"../../../../src","sources":["ui/components/WebOxyProvider.tsx"],"mappings":";;;;;;AA8BA,IAAAA,MAAA,GAAAC,OAAA;AACA,IAAAC,WAAA,GAAAD,OAAA;AACA,IAAAE,WAAA,GAAAF,OAAA;AACA,IAAAG,YAAA,GAAAH,OAAA;AACA,IAAAI,eAAA,GAAAJ,OAAA;AAAuF,IAAAK,WAAA,GAAAL,OAAA;AAlCvF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAiBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAMM,cAAuC,GAAGA,CAAC;EAC/CC,QAAQ;EACRC,OAAO;EACPC,UAAU;EACVC,iBAAiB;EACjBC,gBAAgB;EAChBC,WAAW,EAAEC;AACf,CAAC,KAAK;EACJ,MAAMC,UAAU,GAAG,IAAAC,aAAM,EAA0B,IAAI,CAAC;EACxD,MAAMC,cAAc,GAAG,IAAAD,aAAM,EAA8C,IAAI,CAAC;EAChF,MAAM,CAACH,WAAW,EAAEK,cAAc,CAAC,GAAG,IAAAC,eAAQ,EAA8C,IAAI,CAAC;EAEjG,IAAAC,gBAAS,EAAC,MAAM;IACd,IAAIN,mBAAmB,EAAE;MACvBG,cAAc,CAACI,OAAO,GAAGP,mBAAmB;MAC5CI,cAAc,CAACJ,mBAAmB,CAAC;MACnC;IACF;IAEA,IAAIQ,OAAO,GAAG,IAAI;IAClB,IAAAC,qCAAqB,EAAC,CAAC,CACpBC,IAAI,CAAEC,OAAO,IAAK;MACjB,IAAIH,OAAO,IAAI,CAACL,cAAc,CAACI,OAAO,EAAE;QACtCN,UAAU,CAACM,OAAO,GAAGI,OAAO;QAC5B,MAAMC,MAAM,GAAG,IAAAC,8BAAiB,EAACF,OAAO,CAAC;QACzCR,cAAc,CAACI,OAAO,GAAGK,MAAM;QAC/BR,cAAc,CAACQ,MAAM,CAAC;MACxB;IACF,CAAC,CAAC,CACDE,KAAK,CAAC,MAAM;MACX,IAAIN,OAAO,IAAI,CAACL,cAAc,CAACI,OAAO,EAAE;QACtC,MAAMK,MAAM,GAAG,IAAAC,8BAAiB,EAAC,IAAI,CAAC;QACtCV,cAAc,CAACI,OAAO,GAAGK,MAAM;QAC/BR,cAAc,CAACQ,MAAM,CAAC;MACxB;IACF,CAAC,CAAC;IAEJ,OAAO,MAAM;MACXJ,OAAO,GAAG,KAAK;IACjB,CAAC;EACH,CAAC,EAAE,CAACR,mBAAmB,CAAC,CAAC;;EAEzB;EACA,IAAI,CAACD,WAAW,EAAE;IAChB,OAAO,IAAI;EACb;EAEA,oBACE,IAAAP,WAAA,CAAAuB,GAAA,EAAC1B,WAAA,CAAA2B,mBAAmB;IAACJ,MAAM,EAAEb,WAAY;IAAAL,QAAA,eACvC,IAAAF,WAAA,CAAAuB,GAAA,EAAC3B,WAAA,CAAA6B,kBAAkB;MACjBtB,OAAO,EAAEA,OAAQ;MACjBC,UAAU,EAAEA,UAAW;MACvBE,gBAAgB,EAAEA,gBAAiB;MACnCD,iBAAiB,EAAEA,iBAAkB;MAAAH,QAAA,EAEpCA;IAAQ,CACS;EAAC,CACF,CAAC;AAE1B,CAAC;AAAC,IAAAwB,QAAA,GAAAC,OAAA,CAAAC,OAAA,GAEa3B,cAAc","ignoreList":[]}
|
|
@@ -1,14 +1,12 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
|
|
3
3
|
import { useEffect, useRef, useState } from 'react';
|
|
4
|
-
import { AppState } from 'react-native';
|
|
4
|
+
import { AppState, Platform } from 'react-native';
|
|
5
5
|
import { GestureHandlerRootView } from 'react-native-gesture-handler';
|
|
6
6
|
import { SafeAreaProvider } from 'react-native-safe-area-context';
|
|
7
|
-
import { KeyboardProvider } from 'react-native-keyboard-controller';
|
|
8
7
|
import { OxyContextProvider } from "../context/OxyContext.js";
|
|
9
8
|
import { QueryClientProvider, focusManager, onlineManager } from '@tanstack/react-query';
|
|
10
9
|
import { setupFonts } from "./FontLoader.js";
|
|
11
|
-
import BottomSheetRouter from "./BottomSheetRouter.js";
|
|
12
10
|
import { Toaster } from "../../lib/sonner.js";
|
|
13
11
|
import { createQueryClient } from "../hooks/queryClient.js";
|
|
14
12
|
import { createPlatformStorage } from "../utils/storageHelpers.js";
|
|
@@ -17,11 +15,52 @@ import { createPlatformStorage } from "../utils/storageHelpers.js";
|
|
|
17
15
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
18
16
|
setupFonts();
|
|
19
17
|
|
|
18
|
+
// Detect if running on web
|
|
19
|
+
const isWeb = Platform.OS === 'web';
|
|
20
|
+
|
|
21
|
+
// Conditionally import native-only components
|
|
22
|
+
let KeyboardProvider = ({
|
|
23
|
+
children
|
|
24
|
+
}) => children;
|
|
25
|
+
let BottomSheetRouter = () => null;
|
|
26
|
+
if (!isWeb) {
|
|
27
|
+
try {
|
|
28
|
+
// Only import on native platforms
|
|
29
|
+
KeyboardProvider = require('react-native-keyboard-controller').KeyboardProvider;
|
|
30
|
+
BottomSheetRouter = require('./BottomSheetRouter').default;
|
|
31
|
+
} catch {
|
|
32
|
+
// Fallback if imports fail
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
20
36
|
/**
|
|
21
|
-
* OxyProvider
|
|
37
|
+
* OxyProvider - Universal provider for Expo apps (native + web)
|
|
38
|
+
*
|
|
39
|
+
* Zero-config authentication and session management:
|
|
40
|
+
* - Native (iOS/Android): Keychain-based identity, bottom sheet auth UI
|
|
41
|
+
* - Web: FedCM cross-domain SSO, popup fallback
|
|
42
|
+
*
|
|
43
|
+
* Usage:
|
|
44
|
+
* ```tsx
|
|
45
|
+
* import { OxyProvider, useAuth } from '@oxyhq/services';
|
|
22
46
|
*
|
|
23
|
-
*
|
|
24
|
-
*
|
|
47
|
+
* function App() {
|
|
48
|
+
* return (
|
|
49
|
+
* <OxyProvider baseURL="https://api.oxy.so">
|
|
50
|
+
* <YourApp />
|
|
51
|
+
* </OxyProvider>
|
|
52
|
+
* );
|
|
53
|
+
* }
|
|
54
|
+
*
|
|
55
|
+
* function MyComponent() {
|
|
56
|
+
* const { isAuthenticated, user, signIn, signOut } = useAuth();
|
|
57
|
+
*
|
|
58
|
+
* if (!isAuthenticated) {
|
|
59
|
+
* return <OxySignInButton />;
|
|
60
|
+
* }
|
|
61
|
+
* return <Text>Welcome, {user?.username}!</Text>;
|
|
62
|
+
* }
|
|
63
|
+
* ```
|
|
25
64
|
*/
|
|
26
65
|
const OxyProvider = ({
|
|
27
66
|
oxyServices,
|
|
@@ -69,14 +108,26 @@ const OxyProvider = ({
|
|
|
69
108
|
};
|
|
70
109
|
}, [providedQueryClient]);
|
|
71
110
|
|
|
72
|
-
// Hook React Query focus manager into
|
|
111
|
+
// Hook React Query focus manager into app state (native) or visibility (web)
|
|
73
112
|
useEffect(() => {
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
113
|
+
if (isWeb) {
|
|
114
|
+
// Web: use document visibility
|
|
115
|
+
const handleVisibilityChange = () => {
|
|
116
|
+
focusManager.setFocused(document.visibilityState === 'visible');
|
|
117
|
+
};
|
|
118
|
+
document.addEventListener('visibilitychange', handleVisibilityChange);
|
|
119
|
+
return () => {
|
|
120
|
+
document.removeEventListener('visibilitychange', handleVisibilityChange);
|
|
121
|
+
};
|
|
122
|
+
} else {
|
|
123
|
+
// Native: use AppState
|
|
124
|
+
const subscription = AppState.addEventListener('change', state => {
|
|
125
|
+
focusManager.setFocused(state === 'active');
|
|
126
|
+
});
|
|
127
|
+
return () => {
|
|
128
|
+
subscription.remove();
|
|
129
|
+
};
|
|
130
|
+
}
|
|
80
131
|
}, []);
|
|
81
132
|
|
|
82
133
|
// Setup network status monitoring for offline detection
|
|
@@ -84,8 +135,19 @@ const OxyProvider = ({
|
|
|
84
135
|
let cleanup;
|
|
85
136
|
const setupNetworkMonitoring = async () => {
|
|
86
137
|
try {
|
|
87
|
-
|
|
88
|
-
|
|
138
|
+
if (isWeb) {
|
|
139
|
+
// Web: use navigator.onLine
|
|
140
|
+
onlineManager.setOnline(navigator.onLine);
|
|
141
|
+
const handleOnline = () => onlineManager.setOnline(true);
|
|
142
|
+
const handleOffline = () => onlineManager.setOnline(false);
|
|
143
|
+
window.addEventListener('online', handleOnline);
|
|
144
|
+
window.addEventListener('offline', handleOffline);
|
|
145
|
+
cleanup = () => {
|
|
146
|
+
window.removeEventListener('online', handleOnline);
|
|
147
|
+
window.removeEventListener('offline', handleOffline);
|
|
148
|
+
};
|
|
149
|
+
} else {
|
|
150
|
+
// Native: try to use NetInfo
|
|
89
151
|
try {
|
|
90
152
|
const NetInfo = await import('@react-native-community/netinfo');
|
|
91
153
|
const state = await NetInfo.default.fetch();
|
|
@@ -98,17 +160,6 @@ const OxyProvider = ({
|
|
|
98
160
|
// NetInfo not available, default to online
|
|
99
161
|
onlineManager.setOnline(true);
|
|
100
162
|
}
|
|
101
|
-
} else {
|
|
102
|
-
// For web, use navigator.onLine
|
|
103
|
-
onlineManager.setOnline(navigator.onLine);
|
|
104
|
-
const handleOnline = () => onlineManager.setOnline(true);
|
|
105
|
-
const handleOffline = () => onlineManager.setOnline(false);
|
|
106
|
-
window.addEventListener('online', handleOnline);
|
|
107
|
-
window.addEventListener('offline', handleOffline);
|
|
108
|
-
cleanup = () => {
|
|
109
|
-
window.removeEventListener('online', handleOnline);
|
|
110
|
-
window.removeEventListener('offline', handleOffline);
|
|
111
|
-
};
|
|
112
163
|
}
|
|
113
164
|
} catch (error) {
|
|
114
165
|
// Default to online if detection fails
|
|
@@ -123,27 +174,43 @@ const OxyProvider = ({
|
|
|
123
174
|
|
|
124
175
|
// Ensure we have a valid QueryClient
|
|
125
176
|
if (!queryClient) {
|
|
126
|
-
// Return loading state or fallback
|
|
127
177
|
return null;
|
|
128
178
|
}
|
|
179
|
+
|
|
180
|
+
// Core content that works on all platforms
|
|
181
|
+
const coreContent = /*#__PURE__*/_jsx(QueryClientProvider, {
|
|
182
|
+
client: queryClient,
|
|
183
|
+
children: /*#__PURE__*/_jsxs(OxyContextProvider, {
|
|
184
|
+
oxyServices: oxyServices,
|
|
185
|
+
baseURL: baseURL,
|
|
186
|
+
authWebUrl: authWebUrl,
|
|
187
|
+
authRedirectUri: authRedirectUri,
|
|
188
|
+
storageKeyPrefix: storageKeyPrefix,
|
|
189
|
+
onAuthStateChange: onAuthStateChange,
|
|
190
|
+
children: [children, !isWeb && /*#__PURE__*/_jsx(BottomSheetRouter, {}), /*#__PURE__*/_jsx(Toaster, {})]
|
|
191
|
+
})
|
|
192
|
+
});
|
|
193
|
+
|
|
194
|
+
// On web, minimal wrappers (GestureHandler and SafeArea work via react-native-web)
|
|
195
|
+
if (isWeb) {
|
|
196
|
+
return /*#__PURE__*/_jsx(SafeAreaProvider, {
|
|
197
|
+
children: /*#__PURE__*/_jsx(GestureHandlerRootView, {
|
|
198
|
+
style: {
|
|
199
|
+
flex: 1
|
|
200
|
+
},
|
|
201
|
+
children: coreContent
|
|
202
|
+
})
|
|
203
|
+
});
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
// On native, full wrappers including KeyboardProvider
|
|
129
207
|
return /*#__PURE__*/_jsx(SafeAreaProvider, {
|
|
130
208
|
children: /*#__PURE__*/_jsx(GestureHandlerRootView, {
|
|
131
209
|
style: {
|
|
132
210
|
flex: 1
|
|
133
211
|
},
|
|
134
212
|
children: /*#__PURE__*/_jsx(KeyboardProvider, {
|
|
135
|
-
children:
|
|
136
|
-
client: queryClient,
|
|
137
|
-
children: /*#__PURE__*/_jsxs(OxyContextProvider, {
|
|
138
|
-
oxyServices: oxyServices,
|
|
139
|
-
baseURL: baseURL,
|
|
140
|
-
authWebUrl: authWebUrl,
|
|
141
|
-
authRedirectUri: authRedirectUri,
|
|
142
|
-
storageKeyPrefix: storageKeyPrefix,
|
|
143
|
-
onAuthStateChange: onAuthStateChange,
|
|
144
|
-
children: [children, /*#__PURE__*/_jsx(BottomSheetRouter, {}), /*#__PURE__*/_jsx(Toaster, {})]
|
|
145
|
-
})
|
|
146
|
-
})
|
|
213
|
+
children: coreContent
|
|
147
214
|
})
|
|
148
215
|
})
|
|
149
216
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["useEffect","useRef","useState","AppState","
|
|
1
|
+
{"version":3,"names":["useEffect","useRef","useState","AppState","Platform","GestureHandlerRootView","SafeAreaProvider","OxyContextProvider","QueryClientProvider","focusManager","onlineManager","setupFonts","Toaster","createQueryClient","createPlatformStorage","jsx","_jsx","jsxs","_jsxs","isWeb","OS","KeyboardProvider","children","BottomSheetRouter","require","default","OxyProvider","oxyServices","onAuthStateChange","storageKeyPrefix","baseURL","authWebUrl","authRedirectUri","queryClient","providedQueryClient","storageRef","queryClientRef","setQueryClient","current","mounted","then","storage","client","catch","error","__DEV__","console","warn","handleVisibilityChange","setFocused","document","visibilityState","addEventListener","removeEventListener","subscription","state","remove","cleanup","setupNetworkMonitoring","setOnline","navigator","onLine","handleOnline","handleOffline","window","NetInfo","fetch","isConnected","unsubscribe","coreContent","style","flex"],"sourceRoot":"../../../../src","sources":["ui/components/OxyProvider.tsx"],"mappings":";;AAAA,SAASA,SAAS,EAAEC,MAAM,EAAEC,QAAQ,QAAiB,OAAO;AAC5D,SAASC,QAAQ,EAAEC,QAAQ,QAAQ,cAAc;AACjD,SAASC,sBAAsB,QAAQ,8BAA8B;AACrE,SAASC,gBAAgB,QAAQ,gCAAgC;AAEjE,SAASC,kBAAkB,QAAQ,0BAAuB;AAC1D,SAASC,mBAAmB,EAAEC,YAAY,EAAEC,aAAa,QAAQ,uBAAuB;AACxF,SAASC,UAAU,QAAQ,iBAAc;AACzC,SAASC,OAAO,QAAQ,qBAAkB;AAC1C,SAASC,iBAAiB,QAAQ,yBAAsB;AACxD,SAASC,qBAAqB,QAA+B,4BAAyB;;AAEtF;AAAA,SAAAC,GAAA,IAAAC,IAAA,EAAAC,IAAA,IAAAC,KAAA;AACAP,UAAU,CAAC,CAAC;;AAEZ;AACA,MAAMQ,KAAK,GAAGf,QAAQ,CAACgB,EAAE,KAAK,KAAK;;AAEnC;AACA,IAAIC,gBAAqB,GAAGA,CAAC;EAAEC;AAAc,CAAC,KAAKA,QAAQ;AAC3D,IAAIC,iBAAsB,GAAGA,CAAA,KAAM,IAAI;AAEvC,IAAI,CAACJ,KAAK,EAAE;EACR,IAAI;IACA;IACAE,gBAAgB,GAAGG,OAAO,CAAC,kCAAkC,CAAC,CAACH,gBAAgB;IAC/EE,iBAAiB,GAAGC,OAAO,CAAC,qBAAqB,CAAC,CAACC,OAAO;EAC9D,CAAC,CAAC,MAAM;IACJ;EAAA;AAER;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAMC,WAAiC,GAAGA,CAAC;EACvCC,WAAW;EACXL,QAAQ;EACRM,iBAAiB;EACjBC,gBAAgB;EAChBC,OAAO;EACPC,UAAU;EACVC,eAAe;EACfC,WAAW,EAAEC;AACjB,CAAC,KAAK;EAEF;EACA,MAAMC,UAAU,GAAGlC,MAAM,CAA0B,IAAI,CAAC;EACxD,MAAMmC,cAAc,GAAGnC,MAAM,CAA8C,IAAI,CAAC;EAChF,MAAM,CAACgC,WAAW,EAAEI,cAAc,CAAC,GAAGnC,QAAQ,CAA8C,IAAI,CAAC;EAEjGF,SAAS,CAAC,MAAM;IACZ,IAAIkC,mBAAmB,EAAE;MACrBE,cAAc,CAACE,OAAO,GAAGJ,mBAAmB;MAC5CG,cAAc,CAACH,mBAAmB,CAAC;MACnC;IACJ;;IAEA;IACA,IAAIK,OAAO,GAAG,IAAI;IAClBzB,qBAAqB,CAAC,CAAC,CAClB0B,IAAI,CAAEC,OAAO,IAAK;MACf,IAAIF,OAAO,IAAI,CAACH,cAAc,CAACE,OAAO,EAAE;QACpCH,UAAU,CAACG,OAAO,GAAGG,OAAO;QAC5B,MAAMC,MAAM,GAAG7B,iBAAiB,CAAC4B,OAAO,CAAC;QACzCL,cAAc,CAACE,OAAO,GAAGI,MAAM;QAC/BL,cAAc,CAACK,MAAM,CAAC;MAC1B;IACJ,CAAC,CAAC,CACDC,KAAK,CAAEC,KAAK,IAAK;MACd;MACA,IAAIL,OAAO,IAAI,CAACH,cAAc,CAACE,OAAO,EAAE;QACpC,IAAIO,OAAO,EAAE;UACTC,OAAO,CAACC,IAAI,CAAC,kEAAkE,EAAEH,KAAK,CAAC;QAC3F;QACA,MAAMF,MAAM,GAAG7B,iBAAiB,CAAC,IAAI,CAAC;QACtCuB,cAAc,CAACE,OAAO,GAAGI,MAAM;QAC/BL,cAAc,CAACK,MAAM,CAAC;MAC1B;IACJ,CAAC,CAAC;IAEN,OAAO,MAAM;MACTH,OAAO,GAAG,KAAK;IACnB,CAAC;EACL,CAAC,EAAE,CAACL,mBAAmB,CAAC,CAAC;;EAEzB;EACAlC,SAAS,CAAC,MAAM;IACZ,IAAImB,KAAK,EAAE;MACP;MACA,MAAM6B,sBAAsB,GAAGA,CAAA,KAAM;QACjCvC,YAAY,CAACwC,UAAU,CAACC,QAAQ,CAACC,eAAe,KAAK,SAAS,CAAC;MACnE,CAAC;MACDD,QAAQ,CAACE,gBAAgB,CAAC,kBAAkB,EAAEJ,sBAAsB,CAAC;MACrE,OAAO,MAAM;QACTE,QAAQ,CAACG,mBAAmB,CAAC,kBAAkB,EAAEL,sBAAsB,CAAC;MAC5E,CAAC;IACL,CAAC,MAAM;MACH;MACA,MAAMM,YAAY,GAAGnD,QAAQ,CAACiD,gBAAgB,CAAC,QAAQ,EAAGG,KAAK,IAAK;QAChE9C,YAAY,CAACwC,UAAU,CAACM,KAAK,KAAK,QAAQ,CAAC;MAC/C,CAAC,CAAC;MACF,OAAO,MAAM;QACTD,YAAY,CAACE,MAAM,CAAC,CAAC;MACzB,CAAC;IACL;EACJ,CAAC,EAAE,EAAE,CAAC;;EAEN;EACAxD,SAAS,CAAC,MAAM;IACZ,IAAIyD,OAAiC;IAErC,MAAMC,sBAAsB,GAAG,MAAAA,CAAA,KAAY;MACvC,IAAI;QACA,IAAIvC,KAAK,EAAE;UACP;UACAT,aAAa,CAACiD,SAAS,CAACC,SAAS,CAACC,MAAM,CAAC;UACzC,MAAMC,YAAY,GAAGA,CAAA,KAAMpD,aAAa,CAACiD,SAAS,CAAC,IAAI,CAAC;UACxD,MAAMI,aAAa,GAAGA,CAAA,KAAMrD,aAAa,CAACiD,SAAS,CAAC,KAAK,CAAC;UAE1DK,MAAM,CAACZ,gBAAgB,CAAC,QAAQ,EAAEU,YAAY,CAAC;UAC/CE,MAAM,CAACZ,gBAAgB,CAAC,SAAS,EAAEW,aAAa,CAAC;UAEjDN,OAAO,GAAGA,CAAA,KAAM;YACZO,MAAM,CAACX,mBAAmB,CAAC,QAAQ,EAAES,YAAY,CAAC;YAClDE,MAAM,CAACX,mBAAmB,CAAC,SAAS,EAAEU,aAAa,CAAC;UACxD,CAAC;QACL,CAAC,MAAM;UACH;UACA,IAAI;YACA,MAAME,OAAO,GAAG,MAAM,MAAM,CAAC,iCAAiC,CAAC;YAC/D,MAAMV,KAAK,GAAG,MAAMU,OAAO,CAACxC,OAAO,CAACyC,KAAK,CAAC,CAAC;YAC3CxD,aAAa,CAACiD,SAAS,CAACJ,KAAK,CAACY,WAAW,IAAI,IAAI,CAAC;YAElD,MAAMC,WAAW,GAAGH,OAAO,CAACxC,OAAO,CAAC2B,gBAAgB,CAAEG,KAAsC,IAAK;cAC7F7C,aAAa,CAACiD,SAAS,CAACJ,KAAK,CAACY,WAAW,IAAI,IAAI,CAAC;YACtD,CAAC,CAAC;YAEFV,OAAO,GAAGA,CAAA,KAAMW,WAAW,CAAC,CAAC;UACjC,CAAC,CAAC,MAAM;YACJ;YACA1D,aAAa,CAACiD,SAAS,CAAC,IAAI,CAAC;UACjC;QACJ;MACJ,CAAC,CAAC,OAAOf,KAAK,EAAE;QACZ;QACAlC,aAAa,CAACiD,SAAS,CAAC,IAAI,CAAC;MACjC;IACJ,CAAC;IAEDD,sBAAsB,CAAC,CAAC;IAExB,OAAO,MAAM;MACTD,OAAO,GAAG,CAAC;IACf,CAAC;EACL,CAAC,EAAE,EAAE,CAAC;;EAEN;EACA,IAAI,CAACxB,WAAW,EAAE;IACd,OAAO,IAAI;EACf;;EAEA;EACA,MAAMoC,WAAW,gBACbrD,IAAA,CAACR,mBAAmB;IAACkC,MAAM,EAAET,WAAY;IAAAX,QAAA,eACrCJ,KAAA,CAACX,kBAAkB;MACfoB,WAAW,EAAEA,WAAmB;MAChCG,OAAO,EAAEA,OAAQ;MACjBC,UAAU,EAAEA,UAAW;MACvBC,eAAe,EAAEA,eAAgB;MACjCH,gBAAgB,EAAEA,gBAAiB;MACnCD,iBAAiB,EAAEA,iBAAyB;MAAAN,QAAA,GAE3CA,QAAQ,EAER,CAACH,KAAK,iBAAIH,IAAA,CAACO,iBAAiB,IAAE,CAAC,eAChCP,IAAA,CAACJ,OAAO,IAAE,CAAC;IAAA,CACK;EAAC,CACJ,CACxB;;EAED;EACA,IAAIO,KAAK,EAAE;IACP,oBACIH,IAAA,CAACV,gBAAgB;MAAAgB,QAAA,eACbN,IAAA,CAACX,sBAAsB;QAACiE,KAAK,EAAE;UAAEC,IAAI,EAAE;QAAE,CAAE;QAAAjD,QAAA,EACtC+C;MAAW,CACQ;IAAC,CACX,CAAC;EAE3B;;EAEA;EACA,oBACIrD,IAAA,CAACV,gBAAgB;IAAAgB,QAAA,eACbN,IAAA,CAACX,sBAAsB;MAACiE,KAAK,EAAE;QAAEC,IAAI,EAAE;MAAE,CAAE;MAAAjD,QAAA,eACvCN,IAAA,CAACK,gBAAgB;QAAAC,QAAA,EACZ+C;MAAW,CACE;IAAC,CACC;EAAC,CACX,CAAC;AAE3B,CAAC;AAED,eAAe3C,WAAW","ignoreList":[]}
|
|
@@ -1,18 +1,20 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
|
-
* WebOxyProvider -
|
|
4
|
+
* WebOxyProvider - Lightweight provider for pure React/Next.js apps
|
|
5
5
|
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
6
|
+
* Use this provider for web apps that DON'T use Expo/React Native.
|
|
7
|
+
* For Expo apps (native + web), use `OxyProvider` instead - it works on all platforms.
|
|
8
|
+
*
|
|
9
|
+
* Features:
|
|
8
10
|
* - Automatic cross-domain SSO via FedCM (Chrome 108+, Safari 16.4+, Edge 108+)
|
|
11
|
+
* - No React Native dependencies
|
|
9
12
|
* - Session management
|
|
10
13
|
* - All useOxy/useAuth functionality
|
|
11
14
|
*
|
|
12
|
-
* Zero-config: Just wrap your app and SSO works automatically across domains.
|
|
13
|
-
*
|
|
14
15
|
* Usage:
|
|
15
16
|
* ```tsx
|
|
17
|
+
* // For pure React/Next.js apps (no Expo):
|
|
16
18
|
* import { WebOxyProvider, useAuth } from '@oxyhq/services';
|
|
17
19
|
*
|
|
18
20
|
* function App() {
|
|
@@ -23,11 +25,8 @@
|
|
|
23
25
|
* );
|
|
24
26
|
* }
|
|
25
27
|
*
|
|
26
|
-
*
|
|
27
|
-
*
|
|
28
|
-
* if (isAuthenticated) return <span>Welcome, {user?.username}!</span>;
|
|
29
|
-
* return <button onClick={() => signIn()}>Sign In</button>;
|
|
30
|
-
* }
|
|
28
|
+
* // For Expo apps (native + web), use OxyProvider instead:
|
|
29
|
+
* import { OxyProvider, useAuth } from '@oxyhq/services';
|
|
31
30
|
* ```
|
|
32
31
|
*/
|
|
33
32
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["useEffect","useRef","useState","OxyContextProvider","QueryClientProvider","createQueryClient","createPlatformStorage","jsx","_jsx","WebOxyProvider","children","baseURL","authWebUrl","onAuthStateChange","storageKeyPrefix","queryClient","providedQueryClient","storageRef","queryClientRef","setQueryClient","current","mounted","then","storage","client","catch"],"sourceRoot":"../../../../src","sources":["ui/components/WebOxyProvider.tsx"],"mappings":";;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA
|
|
1
|
+
{"version":3,"names":["useEffect","useRef","useState","OxyContextProvider","QueryClientProvider","createQueryClient","createPlatformStorage","jsx","_jsx","WebOxyProvider","children","baseURL","authWebUrl","onAuthStateChange","storageKeyPrefix","queryClient","providedQueryClient","storageRef","queryClientRef","setQueryClient","current","mounted","then","storage","client","catch"],"sourceRoot":"../../../../src","sources":["ui/components/WebOxyProvider.tsx"],"mappings":";;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,SAASA,SAAS,EAAEC,MAAM,EAAEC,QAAQ,QAAiC,OAAO;AAC5E,SAASC,kBAAkB,QAAQ,0BAAuB;AAC1D,SAASC,mBAAmB,QAAQ,uBAAuB;AAC3D,SAASC,iBAAiB,QAAQ,yBAAsB;AACxD,SAASC,qBAAqB,QAA+B,4BAAyB;AAAC,SAAAC,GAAA,IAAAC,IAAA;AAWvF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAMC,cAAuC,GAAGA,CAAC;EAC/CC,QAAQ;EACRC,OAAO;EACPC,UAAU;EACVC,iBAAiB;EACjBC,gBAAgB;EAChBC,WAAW,EAAEC;AACf,CAAC,KAAK;EACJ,MAAMC,UAAU,GAAGhB,MAAM,CAA0B,IAAI,CAAC;EACxD,MAAMiB,cAAc,GAAGjB,MAAM,CAA8C,IAAI,CAAC;EAChF,MAAM,CAACc,WAAW,EAAEI,cAAc,CAAC,GAAGjB,QAAQ,CAA8C,IAAI,CAAC;EAEjGF,SAAS,CAAC,MAAM;IACd,IAAIgB,mBAAmB,EAAE;MACvBE,cAAc,CAACE,OAAO,GAAGJ,mBAAmB;MAC5CG,cAAc,CAACH,mBAAmB,CAAC;MACnC;IACF;IAEA,IAAIK,OAAO,GAAG,IAAI;IAClBf,qBAAqB,CAAC,CAAC,CACpBgB,IAAI,CAAEC,OAAO,IAAK;MACjB,IAAIF,OAAO,IAAI,CAACH,cAAc,CAACE,OAAO,EAAE;QACtCH,UAAU,CAACG,OAAO,GAAGG,OAAO;QAC5B,MAAMC,MAAM,GAAGnB,iBAAiB,CAACkB,OAAO,CAAC;QACzCL,cAAc,CAACE,OAAO,GAAGI,MAAM;QAC/BL,cAAc,CAACK,MAAM,CAAC;MACxB;IACF,CAAC,CAAC,CACDC,KAAK,CAAC,MAAM;MACX,IAAIJ,OAAO,IAAI,CAACH,cAAc,CAACE,OAAO,EAAE;QACtC,MAAMI,MAAM,GAAGnB,iBAAiB,CAAC,IAAI,CAAC;QACtCa,cAAc,CAACE,OAAO,GAAGI,MAAM;QAC/BL,cAAc,CAACK,MAAM,CAAC;MACxB;IACF,CAAC,CAAC;IAEJ,OAAO,MAAM;MACXH,OAAO,GAAG,KAAK;IACjB,CAAC;EACH,CAAC,EAAE,CAACL,mBAAmB,CAAC,CAAC;;EAEzB;EACA,IAAI,CAACD,WAAW,EAAE;IAChB,OAAO,IAAI;EACb;EAEA,oBACEP,IAAA,CAACJ,mBAAmB;IAACoB,MAAM,EAAET,WAAY;IAAAL,QAAA,eACvCF,IAAA,CAACL,kBAAkB;MACjBQ,OAAO,EAAEA,OAAQ;MACjBC,UAAU,EAAEA,UAAW;MACvBE,gBAAgB,EAAEA,gBAAiB;MACnCD,iBAAiB,EAAEA,iBAAkB;MAAAH,QAAA,EAEpCA;IAAQ,CACS;EAAC,CACF,CAAC;AAE1B,CAAC;AAED,eAAeD,cAAc","ignoreList":[]}
|
|
@@ -1,10 +1,33 @@
|
|
|
1
1
|
import { type FC } from 'react';
|
|
2
2
|
import type { OxyProviderProps } from '../types/navigation';
|
|
3
3
|
/**
|
|
4
|
-
* OxyProvider
|
|
4
|
+
* OxyProvider - Universal provider for Expo apps (native + web)
|
|
5
5
|
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
6
|
+
* Zero-config authentication and session management:
|
|
7
|
+
* - Native (iOS/Android): Keychain-based identity, bottom sheet auth UI
|
|
8
|
+
* - Web: FedCM cross-domain SSO, popup fallback
|
|
9
|
+
*
|
|
10
|
+
* Usage:
|
|
11
|
+
* ```tsx
|
|
12
|
+
* import { OxyProvider, useAuth } from '@oxyhq/services';
|
|
13
|
+
*
|
|
14
|
+
* function App() {
|
|
15
|
+
* return (
|
|
16
|
+
* <OxyProvider baseURL="https://api.oxy.so">
|
|
17
|
+
* <YourApp />
|
|
18
|
+
* </OxyProvider>
|
|
19
|
+
* );
|
|
20
|
+
* }
|
|
21
|
+
*
|
|
22
|
+
* function MyComponent() {
|
|
23
|
+
* const { isAuthenticated, user, signIn, signOut } = useAuth();
|
|
24
|
+
*
|
|
25
|
+
* if (!isAuthenticated) {
|
|
26
|
+
* return <OxySignInButton />;
|
|
27
|
+
* }
|
|
28
|
+
* return <Text>Welcome, {user?.username}!</Text>;
|
|
29
|
+
* }
|
|
30
|
+
* ```
|
|
8
31
|
*/
|
|
9
32
|
declare const OxyProvider: FC<OxyProviderProps>;
|
|
10
33
|
export default OxyProvider;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"OxyProvider.d.ts","sourceRoot":"","sources":["../../../../../src/ui/components/OxyProvider.tsx"],"names":[],"mappings":"AAAA,OAAO,EAA+B,KAAK,EAAE,EAAE,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"OxyProvider.d.ts","sourceRoot":"","sources":["../../../../../src/ui/components/OxyProvider.tsx"],"names":[],"mappings":"AAAA,OAAO,EAA+B,KAAK,EAAE,EAAE,MAAM,OAAO,CAAC;AAI7D,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AA4B5D;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,QAAA,MAAM,WAAW,EAAE,EAAE,CAAC,gBAAgB,CAuKrC,CAAC;AAEF,eAAe,WAAW,CAAC"}
|
|
@@ -1,16 +1,18 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* WebOxyProvider -
|
|
2
|
+
* WebOxyProvider - Lightweight provider for pure React/Next.js apps
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
4
|
+
* Use this provider for web apps that DON'T use Expo/React Native.
|
|
5
|
+
* For Expo apps (native + web), use `OxyProvider` instead - it works on all platforms.
|
|
6
|
+
*
|
|
7
|
+
* Features:
|
|
6
8
|
* - Automatic cross-domain SSO via FedCM (Chrome 108+, Safari 16.4+, Edge 108+)
|
|
9
|
+
* - No React Native dependencies
|
|
7
10
|
* - Session management
|
|
8
11
|
* - All useOxy/useAuth functionality
|
|
9
12
|
*
|
|
10
|
-
* Zero-config: Just wrap your app and SSO works automatically across domains.
|
|
11
|
-
*
|
|
12
13
|
* Usage:
|
|
13
14
|
* ```tsx
|
|
15
|
+
* // For pure React/Next.js apps (no Expo):
|
|
14
16
|
* import { WebOxyProvider, useAuth } from '@oxyhq/services';
|
|
15
17
|
*
|
|
16
18
|
* function App() {
|
|
@@ -21,11 +23,8 @@
|
|
|
21
23
|
* );
|
|
22
24
|
* }
|
|
23
25
|
*
|
|
24
|
-
*
|
|
25
|
-
*
|
|
26
|
-
* if (isAuthenticated) return <span>Welcome, {user?.username}!</span>;
|
|
27
|
-
* return <button onClick={() => signIn()}>Sign In</button>;
|
|
28
|
-
* }
|
|
26
|
+
* // For Expo apps (native + web), use OxyProvider instead:
|
|
27
|
+
* import { OxyProvider, useAuth } from '@oxyhq/services';
|
|
29
28
|
* ```
|
|
30
29
|
*/
|
|
31
30
|
import { type FC, type ReactNode } from 'react';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"WebOxyProvider.d.ts","sourceRoot":"","sources":["../../../../../src/ui/components/WebOxyProvider.tsx"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"WebOxyProvider.d.ts","sourceRoot":"","sources":["../../../../../src/ui/components/WebOxyProvider.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AAEH,OAAO,EAA+B,KAAK,EAAE,EAAE,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAG7E,OAAO,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AAGzD,MAAM,WAAW,mBAAmB;IAClC,QAAQ,EAAE,SAAS,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,iBAAiB,CAAC,EAAE,CAAC,IAAI,EAAE,GAAG,KAAK,IAAI,CAAC;IACxC,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,WAAW,CAAC,EAAE,UAAU,CAAC,OAAO,iBAAiB,CAAC,CAAC;CACpD;AAED;;;;;;;;;GASG;AACH,QAAA,MAAM,cAAc,EAAE,EAAE,CAAC,mBAAmB,CA2D3C,CAAC;AAEF,eAAe,cAAc,CAAC"}
|
|
@@ -1,10 +1,33 @@
|
|
|
1
1
|
import { type FC } from 'react';
|
|
2
2
|
import type { OxyProviderProps } from '../types/navigation';
|
|
3
3
|
/**
|
|
4
|
-
* OxyProvider
|
|
4
|
+
* OxyProvider - Universal provider for Expo apps (native + web)
|
|
5
5
|
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
6
|
+
* Zero-config authentication and session management:
|
|
7
|
+
* - Native (iOS/Android): Keychain-based identity, bottom sheet auth UI
|
|
8
|
+
* - Web: FedCM cross-domain SSO, popup fallback
|
|
9
|
+
*
|
|
10
|
+
* Usage:
|
|
11
|
+
* ```tsx
|
|
12
|
+
* import { OxyProvider, useAuth } from '@oxyhq/services';
|
|
13
|
+
*
|
|
14
|
+
* function App() {
|
|
15
|
+
* return (
|
|
16
|
+
* <OxyProvider baseURL="https://api.oxy.so">
|
|
17
|
+
* <YourApp />
|
|
18
|
+
* </OxyProvider>
|
|
19
|
+
* );
|
|
20
|
+
* }
|
|
21
|
+
*
|
|
22
|
+
* function MyComponent() {
|
|
23
|
+
* const { isAuthenticated, user, signIn, signOut } = useAuth();
|
|
24
|
+
*
|
|
25
|
+
* if (!isAuthenticated) {
|
|
26
|
+
* return <OxySignInButton />;
|
|
27
|
+
* }
|
|
28
|
+
* return <Text>Welcome, {user?.username}!</Text>;
|
|
29
|
+
* }
|
|
30
|
+
* ```
|
|
8
31
|
*/
|
|
9
32
|
declare const OxyProvider: FC<OxyProviderProps>;
|
|
10
33
|
export default OxyProvider;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"OxyProvider.d.ts","sourceRoot":"","sources":["../../../../../src/ui/components/OxyProvider.tsx"],"names":[],"mappings":"AAAA,OAAO,EAA+B,KAAK,EAAE,EAAE,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"OxyProvider.d.ts","sourceRoot":"","sources":["../../../../../src/ui/components/OxyProvider.tsx"],"names":[],"mappings":"AAAA,OAAO,EAA+B,KAAK,EAAE,EAAE,MAAM,OAAO,CAAC;AAI7D,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AA4B5D;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,QAAA,MAAM,WAAW,EAAE,EAAE,CAAC,gBAAgB,CAuKrC,CAAC;AAEF,eAAe,WAAW,CAAC"}
|
|
@@ -1,16 +1,18 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* WebOxyProvider -
|
|
2
|
+
* WebOxyProvider - Lightweight provider for pure React/Next.js apps
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
4
|
+
* Use this provider for web apps that DON'T use Expo/React Native.
|
|
5
|
+
* For Expo apps (native + web), use `OxyProvider` instead - it works on all platforms.
|
|
6
|
+
*
|
|
7
|
+
* Features:
|
|
6
8
|
* - Automatic cross-domain SSO via FedCM (Chrome 108+, Safari 16.4+, Edge 108+)
|
|
9
|
+
* - No React Native dependencies
|
|
7
10
|
* - Session management
|
|
8
11
|
* - All useOxy/useAuth functionality
|
|
9
12
|
*
|
|
10
|
-
* Zero-config: Just wrap your app and SSO works automatically across domains.
|
|
11
|
-
*
|
|
12
13
|
* Usage:
|
|
13
14
|
* ```tsx
|
|
15
|
+
* // For pure React/Next.js apps (no Expo):
|
|
14
16
|
* import { WebOxyProvider, useAuth } from '@oxyhq/services';
|
|
15
17
|
*
|
|
16
18
|
* function App() {
|
|
@@ -21,11 +23,8 @@
|
|
|
21
23
|
* );
|
|
22
24
|
* }
|
|
23
25
|
*
|
|
24
|
-
*
|
|
25
|
-
*
|
|
26
|
-
* if (isAuthenticated) return <span>Welcome, {user?.username}!</span>;
|
|
27
|
-
* return <button onClick={() => signIn()}>Sign In</button>;
|
|
28
|
-
* }
|
|
26
|
+
* // For Expo apps (native + web), use OxyProvider instead:
|
|
27
|
+
* import { OxyProvider, useAuth } from '@oxyhq/services';
|
|
29
28
|
* ```
|
|
30
29
|
*/
|
|
31
30
|
import { type FC, type ReactNode } from 'react';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"WebOxyProvider.d.ts","sourceRoot":"","sources":["../../../../../src/ui/components/WebOxyProvider.tsx"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"WebOxyProvider.d.ts","sourceRoot":"","sources":["../../../../../src/ui/components/WebOxyProvider.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AAEH,OAAO,EAA+B,KAAK,EAAE,EAAE,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAG7E,OAAO,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AAGzD,MAAM,WAAW,mBAAmB;IAClC,QAAQ,EAAE,SAAS,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,iBAAiB,CAAC,EAAE,CAAC,IAAI,EAAE,GAAG,KAAK,IAAI,CAAC;IACxC,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,WAAW,CAAC,EAAE,UAAU,CAAC,OAAO,iBAAiB,CAAC,CAAC;CACpD;AAED;;;;;;;;;GASG;AACH,QAAA,MAAM,cAAc,EAAE,EAAE,CAAC,mBAAmB,CA2D3C,CAAC;AAEF,eAAe,cAAc,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@oxyhq/services",
|
|
3
|
-
"version": "5.
|
|
3
|
+
"version": "5.20.0",
|
|
4
4
|
"description": "Reusable OxyHQ module to handle authentication, user management, karma system, device-based session management and more 🚀",
|
|
5
5
|
"main": "lib/commonjs/index.js",
|
|
6
6
|
"module": "lib/module/index.js",
|
|
@@ -1,13 +1,11 @@
|
|
|
1
1
|
import { useEffect, useRef, useState, type FC } from 'react';
|
|
2
|
-
import { AppState } from 'react-native';
|
|
2
|
+
import { AppState, Platform } from 'react-native';
|
|
3
3
|
import { GestureHandlerRootView } from 'react-native-gesture-handler';
|
|
4
4
|
import { SafeAreaProvider } from 'react-native-safe-area-context';
|
|
5
|
-
import { KeyboardProvider } from 'react-native-keyboard-controller';
|
|
6
5
|
import type { OxyProviderProps } from '../types/navigation';
|
|
7
6
|
import { OxyContextProvider } from '../context/OxyContext';
|
|
8
7
|
import { QueryClientProvider, focusManager, onlineManager } from '@tanstack/react-query';
|
|
9
8
|
import { setupFonts } from './FontLoader';
|
|
10
|
-
import BottomSheetRouter from './BottomSheetRouter';
|
|
11
9
|
import { Toaster } from '../../lib/sonner';
|
|
12
10
|
import { createQueryClient } from '../hooks/queryClient';
|
|
13
11
|
import { createPlatformStorage, type StorageInterface } from '../utils/storageHelpers';
|
|
@@ -15,11 +13,51 @@ import { createPlatformStorage, type StorageInterface } from '../utils/storageHe
|
|
|
15
13
|
// Initialize fonts automatically
|
|
16
14
|
setupFonts();
|
|
17
15
|
|
|
16
|
+
// Detect if running on web
|
|
17
|
+
const isWeb = Platform.OS === 'web';
|
|
18
|
+
|
|
19
|
+
// Conditionally import native-only components
|
|
20
|
+
let KeyboardProvider: any = ({ children }: any) => children;
|
|
21
|
+
let BottomSheetRouter: any = () => null;
|
|
22
|
+
|
|
23
|
+
if (!isWeb) {
|
|
24
|
+
try {
|
|
25
|
+
// Only import on native platforms
|
|
26
|
+
KeyboardProvider = require('react-native-keyboard-controller').KeyboardProvider;
|
|
27
|
+
BottomSheetRouter = require('./BottomSheetRouter').default;
|
|
28
|
+
} catch {
|
|
29
|
+
// Fallback if imports fail
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
18
33
|
/**
|
|
19
|
-
* OxyProvider
|
|
34
|
+
* OxyProvider - Universal provider for Expo apps (native + web)
|
|
35
|
+
*
|
|
36
|
+
* Zero-config authentication and session management:
|
|
37
|
+
* - Native (iOS/Android): Keychain-based identity, bottom sheet auth UI
|
|
38
|
+
* - Web: FedCM cross-domain SSO, popup fallback
|
|
20
39
|
*
|
|
21
|
-
*
|
|
22
|
-
*
|
|
40
|
+
* Usage:
|
|
41
|
+
* ```tsx
|
|
42
|
+
* import { OxyProvider, useAuth } from '@oxyhq/services';
|
|
43
|
+
*
|
|
44
|
+
* function App() {
|
|
45
|
+
* return (
|
|
46
|
+
* <OxyProvider baseURL="https://api.oxy.so">
|
|
47
|
+
* <YourApp />
|
|
48
|
+
* </OxyProvider>
|
|
49
|
+
* );
|
|
50
|
+
* }
|
|
51
|
+
*
|
|
52
|
+
* function MyComponent() {
|
|
53
|
+
* const { isAuthenticated, user, signIn, signOut } = useAuth();
|
|
54
|
+
*
|
|
55
|
+
* if (!isAuthenticated) {
|
|
56
|
+
* return <OxySignInButton />;
|
|
57
|
+
* }
|
|
58
|
+
* return <Text>Welcome, {user?.username}!</Text>;
|
|
59
|
+
* }
|
|
60
|
+
* ```
|
|
23
61
|
*/
|
|
24
62
|
const OxyProvider: FC<OxyProviderProps> = ({
|
|
25
63
|
oxyServices,
|
|
@@ -72,14 +110,26 @@ const OxyProvider: FC<OxyProviderProps> = ({
|
|
|
72
110
|
};
|
|
73
111
|
}, [providedQueryClient]);
|
|
74
112
|
|
|
75
|
-
// Hook React Query focus manager into
|
|
113
|
+
// Hook React Query focus manager into app state (native) or visibility (web)
|
|
76
114
|
useEffect(() => {
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
115
|
+
if (isWeb) {
|
|
116
|
+
// Web: use document visibility
|
|
117
|
+
const handleVisibilityChange = () => {
|
|
118
|
+
focusManager.setFocused(document.visibilityState === 'visible');
|
|
119
|
+
};
|
|
120
|
+
document.addEventListener('visibilitychange', handleVisibilityChange);
|
|
121
|
+
return () => {
|
|
122
|
+
document.removeEventListener('visibilitychange', handleVisibilityChange);
|
|
123
|
+
};
|
|
124
|
+
} else {
|
|
125
|
+
// Native: use AppState
|
|
126
|
+
const subscription = AppState.addEventListener('change', (state) => {
|
|
127
|
+
focusManager.setFocused(state === 'active');
|
|
128
|
+
});
|
|
129
|
+
return () => {
|
|
130
|
+
subscription.remove();
|
|
131
|
+
};
|
|
132
|
+
}
|
|
83
133
|
}, []);
|
|
84
134
|
|
|
85
135
|
// Setup network status monitoring for offline detection
|
|
@@ -88,35 +138,35 @@ const OxyProvider: FC<OxyProviderProps> = ({
|
|
|
88
138
|
|
|
89
139
|
const setupNetworkMonitoring = async () => {
|
|
90
140
|
try {
|
|
91
|
-
|
|
92
|
-
|
|
141
|
+
if (isWeb) {
|
|
142
|
+
// Web: use navigator.onLine
|
|
143
|
+
onlineManager.setOnline(navigator.onLine);
|
|
144
|
+
const handleOnline = () => onlineManager.setOnline(true);
|
|
145
|
+
const handleOffline = () => onlineManager.setOnline(false);
|
|
146
|
+
|
|
147
|
+
window.addEventListener('online', handleOnline);
|
|
148
|
+
window.addEventListener('offline', handleOffline);
|
|
149
|
+
|
|
150
|
+
cleanup = () => {
|
|
151
|
+
window.removeEventListener('online', handleOnline);
|
|
152
|
+
window.removeEventListener('offline', handleOffline);
|
|
153
|
+
};
|
|
154
|
+
} else {
|
|
155
|
+
// Native: try to use NetInfo
|
|
93
156
|
try {
|
|
94
157
|
const NetInfo = await import('@react-native-community/netinfo');
|
|
95
158
|
const state = await NetInfo.default.fetch();
|
|
96
159
|
onlineManager.setOnline(state.isConnected ?? true);
|
|
97
|
-
|
|
160
|
+
|
|
98
161
|
const unsubscribe = NetInfo.default.addEventListener((state: { isConnected: boolean | null }) => {
|
|
99
162
|
onlineManager.setOnline(state.isConnected ?? true);
|
|
100
163
|
});
|
|
101
|
-
|
|
164
|
+
|
|
102
165
|
cleanup = () => unsubscribe();
|
|
103
166
|
} catch {
|
|
104
167
|
// NetInfo not available, default to online
|
|
105
168
|
onlineManager.setOnline(true);
|
|
106
169
|
}
|
|
107
|
-
} else {
|
|
108
|
-
// For web, use navigator.onLine
|
|
109
|
-
onlineManager.setOnline(navigator.onLine);
|
|
110
|
-
const handleOnline = () => onlineManager.setOnline(true);
|
|
111
|
-
const handleOffline = () => onlineManager.setOnline(false);
|
|
112
|
-
|
|
113
|
-
window.addEventListener('online', handleOnline);
|
|
114
|
-
window.addEventListener('offline', handleOffline);
|
|
115
|
-
|
|
116
|
-
cleanup = () => {
|
|
117
|
-
window.removeEventListener('online', handleOnline);
|
|
118
|
-
window.removeEventListener('offline', handleOffline);
|
|
119
|
-
};
|
|
120
170
|
}
|
|
121
171
|
} catch (error) {
|
|
122
172
|
// Default to online if detection fails
|
|
@@ -133,30 +183,45 @@ const OxyProvider: FC<OxyProviderProps> = ({
|
|
|
133
183
|
|
|
134
184
|
// Ensure we have a valid QueryClient
|
|
135
185
|
if (!queryClient) {
|
|
136
|
-
// Return loading state or fallback
|
|
137
186
|
return null;
|
|
138
187
|
}
|
|
139
188
|
|
|
189
|
+
// Core content that works on all platforms
|
|
190
|
+
const coreContent = (
|
|
191
|
+
<QueryClientProvider client={queryClient}>
|
|
192
|
+
<OxyContextProvider
|
|
193
|
+
oxyServices={oxyServices as any}
|
|
194
|
+
baseURL={baseURL}
|
|
195
|
+
authWebUrl={authWebUrl}
|
|
196
|
+
authRedirectUri={authRedirectUri}
|
|
197
|
+
storageKeyPrefix={storageKeyPrefix}
|
|
198
|
+
onAuthStateChange={onAuthStateChange as any}
|
|
199
|
+
>
|
|
200
|
+
{children}
|
|
201
|
+
{/* Only render bottom sheet router on native */}
|
|
202
|
+
{!isWeb && <BottomSheetRouter />}
|
|
203
|
+
<Toaster />
|
|
204
|
+
</OxyContextProvider>
|
|
205
|
+
</QueryClientProvider>
|
|
206
|
+
);
|
|
207
|
+
|
|
208
|
+
// On web, minimal wrappers (GestureHandler and SafeArea work via react-native-web)
|
|
209
|
+
if (isWeb) {
|
|
210
|
+
return (
|
|
211
|
+
<SafeAreaProvider>
|
|
212
|
+
<GestureHandlerRootView style={{ flex: 1 }}>
|
|
213
|
+
{coreContent}
|
|
214
|
+
</GestureHandlerRootView>
|
|
215
|
+
</SafeAreaProvider>
|
|
216
|
+
);
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
// On native, full wrappers including KeyboardProvider
|
|
140
220
|
return (
|
|
141
221
|
<SafeAreaProvider>
|
|
142
222
|
<GestureHandlerRootView style={{ flex: 1 }}>
|
|
143
223
|
<KeyboardProvider>
|
|
144
|
-
{
|
|
145
|
-
<QueryClientProvider client={queryClient}>
|
|
146
|
-
<OxyContextProvider
|
|
147
|
-
oxyServices={oxyServices as any}
|
|
148
|
-
baseURL={baseURL}
|
|
149
|
-
authWebUrl={authWebUrl}
|
|
150
|
-
authRedirectUri={authRedirectUri}
|
|
151
|
-
storageKeyPrefix={storageKeyPrefix}
|
|
152
|
-
onAuthStateChange={onAuthStateChange as any}
|
|
153
|
-
>
|
|
154
|
-
{children}
|
|
155
|
-
<BottomSheetRouter />
|
|
156
|
-
<Toaster />
|
|
157
|
-
</OxyContextProvider>
|
|
158
|
-
</QueryClientProvider>
|
|
159
|
-
)}
|
|
224
|
+
{coreContent}
|
|
160
225
|
</KeyboardProvider>
|
|
161
226
|
</GestureHandlerRootView>
|
|
162
227
|
</SafeAreaProvider>
|
|
@@ -1,16 +1,18 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* WebOxyProvider -
|
|
2
|
+
* WebOxyProvider - Lightweight provider for pure React/Next.js apps
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
4
|
+
* Use this provider for web apps that DON'T use Expo/React Native.
|
|
5
|
+
* For Expo apps (native + web), use `OxyProvider` instead - it works on all platforms.
|
|
6
|
+
*
|
|
7
|
+
* Features:
|
|
6
8
|
* - Automatic cross-domain SSO via FedCM (Chrome 108+, Safari 16.4+, Edge 108+)
|
|
9
|
+
* - No React Native dependencies
|
|
7
10
|
* - Session management
|
|
8
11
|
* - All useOxy/useAuth functionality
|
|
9
12
|
*
|
|
10
|
-
* Zero-config: Just wrap your app and SSO works automatically across domains.
|
|
11
|
-
*
|
|
12
13
|
* Usage:
|
|
13
14
|
* ```tsx
|
|
15
|
+
* // For pure React/Next.js apps (no Expo):
|
|
14
16
|
* import { WebOxyProvider, useAuth } from '@oxyhq/services';
|
|
15
17
|
*
|
|
16
18
|
* function App() {
|
|
@@ -21,11 +23,8 @@
|
|
|
21
23
|
* );
|
|
22
24
|
* }
|
|
23
25
|
*
|
|
24
|
-
*
|
|
25
|
-
*
|
|
26
|
-
* if (isAuthenticated) return <span>Welcome, {user?.username}!</span>;
|
|
27
|
-
* return <button onClick={() => signIn()}>Sign In</button>;
|
|
28
|
-
* }
|
|
26
|
+
* // For Expo apps (native + web), use OxyProvider instead:
|
|
27
|
+
* import { OxyProvider, useAuth } from '@oxyhq/services';
|
|
29
28
|
* ```
|
|
30
29
|
*/
|
|
31
30
|
|