@fanapps/react-native 0.3.1 → 0.4.1

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 CHANGED
@@ -4,33 +4,42 @@ React Native SDK for the Fanapps API — Firebase-powered auth, paginated conten
4
4
 
5
5
  ## Install
6
6
 
7
+ All native modules are **peer dependencies** — install only what you use. Required for every consumer:
8
+
7
9
  ```sh
8
10
  pnpm add @fanapps/react-native \
9
11
  @tanstack/react-query \
10
- @react-native-firebase/app
12
+ @react-native-firebase/app \
13
+ @react-native-firebase/auth
11
14
  ```
12
15
 
16
+ Optional (install only if you import the matching subpath):
17
+
18
+ | Feature | Subpath | Peer dependency |
19
+ | ------------------------------ | ------------------------------ | -------------------------------------------------------------------------------- |
20
+ | Push registration / FCM topics | `@fanapps/react-native/push` | `@react-native-firebase/messaging` + `@react-native-async-storage/async-storage` |
21
+ | Google sign-in | `@fanapps/react-native/google` | `@react-native-google-signin/google-signin` |
22
+ | Apple sign-in (iOS) | `@fanapps/react-native/apple` | `@invertase/react-native-apple-authentication` |
23
+
13
24
  iOS:
14
25
 
15
26
  ```sh
16
27
  cd ios && pod install
17
28
  ```
18
29
 
19
- The SDK auto-installs all required native modules (`@react-native-firebase/auth`, `/messaging`, Google sign-in, Apple sign-in, AsyncStorage) — autolinking handles native registration.
30
+ Firebase native config:
20
31
 
21
- You still need Firebase's native config:
22
32
  - `google-services.json` (Android) → `android/app/`
23
33
  - `GoogleService-Info.plist` (iOS) → `ios/<AppName>/`
24
34
 
25
35
  See the [React Native Firebase setup docs](https://rnfirebase.io/#installation).
26
36
 
27
- If you use Google sign-in, configure OAuth client IDs per the [google-signin docs](https://github.com/react-native-google-signin/google-signin). For Apple sign-in, enable the "Sign in with Apple" capability in Xcode.
37
+ For Google sign-in, configure OAuth client IDs per the [google-signin docs](https://github.com/react-native-google-signin/google-signin). For Apple sign-in, enable the "Sign in with Apple" capability in Xcode.
28
38
 
29
39
  ## Quick start
30
40
 
31
41
  ```tsx
32
42
  import { FanappsProvider, useAuth, useEntries } from '@fanapps/react-native';
33
- import AsyncStorage from '@react-native-async-storage/async-storage';
34
43
 
35
44
  export default function App() {
36
45
  return (
@@ -38,7 +47,6 @@ export default function App() {
38
47
  apiKey={process.env.EXPO_PUBLIC_FANAPPS_TOKEN!}
39
48
  project={process.env.EXPO_PUBLIC_FANAPPS_PROJECT!}
40
49
  locale="en"
41
- storage={AsyncStorage}
42
50
  >
43
51
  <Feed />
44
52
  </FanappsProvider>
@@ -59,14 +67,14 @@ function Feed() {
59
67
 
60
68
  ## Provider props
61
69
 
62
- | Prop | Type | Required | Description |
63
- | ------------- | ---------------- | -------- | --------------------------------------------------------------------------------------------------------------- |
64
- | `apiKey` | `string` | yes | App-level bearer token. Sent as `Authorization: Bearer <apiKey>`. |
65
- | `project` | `string` | yes | Tenant UUID. Sent as `X-Tenant` header. |
66
- | `locale` | `string` | no | Default locale (e.g. `"en"`). Reactive — changing it refetches all queries. |
67
- | `baseUrl` | `string` | no | API base URL. Defaults to production. |
68
- | `queryClient` | `QueryClient` | no | Reuse an existing React Query client. Otherwise one is created internally. |
69
- | `storage` | `StorageAdapter` | no | Storage for persisted state (e.g. push target IDs). Defaults to AsyncStorage if installed; otherwise in-memory. |
70
+ | Prop | Type | Required | Description |
71
+ | ------------- | ---------------- | -------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
72
+ | `apiKey` | `string` | yes | App-level bearer token. Sent as `Authorization: Bearer <apiKey>`. |
73
+ | `project` | `string` | yes | Tenant UUID. Sent as `X-Tenant` header. |
74
+ | `locale` | `string` | no | Default locale (e.g. `"en"`). Reactive — changing it refetches all queries. |
75
+ | `baseUrl` | `string` | no | API base URL. Defaults to production. |
76
+ | `queryClient` | `QueryClient` | no | Reuse an existing React Query client. Otherwise one is created internally. |
77
+ | `storage` | `StorageAdapter` | no | Override storage backend for persisted state (e.g. push target IDs). When unset, the `/push` subpath defaults to `@react-native-async-storage/async-storage`. Ignored if you don't use the push subpath. |
70
78
 
71
79
  ## Auth
72
80
 
@@ -83,8 +91,6 @@ function Screen() {
83
91
  signUpWithEmail,
84
92
  sendPasswordResetEmail,
85
93
  sendEmailVerification,
86
- signInWithGoogle,
87
- signInWithApple,
88
94
  signOut,
89
95
  } = useAuth();
90
96
 
@@ -92,11 +98,47 @@ function Screen() {
92
98
  }
93
99
  ```
94
100
 
101
+ ### Email / password
102
+
103
+ ```tsx
104
+ const { signInWithEmail, signUpWithEmail, sendPasswordResetEmail, sendEmailVerification, signOut } = useAuth();
105
+
106
+ // Sign in
107
+ const user = await signInWithEmail('a@b.com', 's3cret');
108
+
109
+ // Sign up (creates Firebase user, signs them in)
110
+ const newUser = await signUpWithEmail('new@b.com', 's3cret');
111
+
112
+ // Password reset email
113
+ await sendPasswordResetEmail('a@b.com');
114
+
115
+ // Send verification email to currently signed-in user
116
+ await sendEmailVerification();
117
+
118
+ // Sign out
119
+ await signOut();
120
+ ```
121
+
122
+ All return promises; failures throw Firebase errors (e.g. `auth/wrong-password`, `auth/email-already-in-use`).
123
+
124
+ ### Google and Apple
125
+
126
+ Imported from subpaths (peer-isolated):
127
+
128
+ ```tsx
129
+ import { signInWithGoogle } from '@fanapps/react-native/google';
130
+ import { signInWithApple } from '@fanapps/react-native/apple';
131
+
132
+ await signInWithGoogle(); // returns FirebaseAuthTypes.UserCredential
133
+ await signInWithApple();
134
+ ```
135
+
136
+ State propagates through `useAuth().user` automatically via Firebase's `onAuthStateChanged`.
137
+
95
138
  **Notes**
96
139
 
97
140
  - `user` is sourced entirely from Firebase (`onAuthStateChanged`) — no backend round-trip on auth state change.
98
- - `signInWithGoogle` throws a `FanappsAuthError` with code `peer/missing` if `@react-native-google-signin/google-signin` isn't installed. Same for `signInWithApple`.
99
- - `signInWithApple` is iOS-only in v1. On Android it throws `auth/platform-not-supported`.
141
+ - `signInWithApple` is iOS-only in v1. On Android it throws `FanappsAuthError` with code `auth/platform-not-supported`.
100
142
  - Token refresh is handled by Firebase; the SDK calls `currentUser.getIdToken()` before each request, which returns a cached token and only refreshes when close to expiry.
101
143
 
102
144
  ## Push notifications
@@ -106,7 +148,8 @@ The SDK registers the device's FCM token as a _push target_ on the backend, usin
106
148
  ### Register a device
107
149
 
108
150
  ```tsx
109
- import { useAuth, useRegisterDevice } from '@fanapps/react-native';
151
+ import { useAuth } from '@fanapps/react-native';
152
+ import { useRegisterDevice } from '@fanapps/react-native/push';
110
153
  import { useEffect } from 'react';
111
154
 
112
155
  function PushSetup() {
@@ -137,7 +180,7 @@ function PushSetup() {
137
180
  FCM topics are the cheapest way to broadcast — no backend round-trip, no storage needed.
138
181
 
139
182
  ```tsx
140
- import { useTopicSubscription } from '@fanapps/react-native';
183
+ import { useTopicSubscription } from '@fanapps/react-native/push';
141
184
 
142
185
  const topics = useTopicSubscription();
143
186
  await topics.subscribe('news');
@@ -238,6 +281,7 @@ if (error instanceof FanappsError && error.status === 401) {
238
281
  }
239
282
 
240
283
  try {
284
+ // import { signInWithGoogle } from '@fanapps/react-native/google';
241
285
  await signInWithGoogle();
242
286
  } catch (e) {
243
287
  if (e instanceof FanappsAuthError && e.code === 'auth/platform-not-supported') {
@@ -258,7 +302,7 @@ interface StorageAdapter {
258
302
  }
259
303
  ```
260
304
 
261
- Defaults to `@react-native-async-storage/async-storage` (which the SDK auto-installs). To use `expo-secure-store` or a custom backend, pass it via the `storage` prop wrapped in an adapter.
305
+ When you import `@fanapps/react-native/push`, AsyncStorage is the default — install `@react-native-async-storage/async-storage` as a peer. To swap in `expo-secure-store` or a custom backend, pass it via the `storage` prop wrapped in an adapter.
262
306
 
263
307
  ## Build
264
308
 
@@ -0,0 +1,5 @@
1
+ import { FirebaseAuthTypes } from '@react-native-firebase/auth';
2
+
3
+ declare function signInWithApple(): Promise<FirebaseAuthTypes.UserCredential>;
4
+
5
+ export { signInWithApple };
@@ -0,0 +1,5 @@
1
+ import { FirebaseAuthTypes } from '@react-native-firebase/auth';
2
+
3
+ declare function signInWithApple(): Promise<FirebaseAuthTypes.UserCredential>;
4
+
5
+ export { signInWithApple };
package/dist/apple.js ADDED
@@ -0,0 +1,73 @@
1
+ "use strict";
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __export = (target, all) => {
9
+ for (var name in all)
10
+ __defProp(target, name, { get: all[name], enumerable: true });
11
+ };
12
+ var __copyProps = (to, from, except, desc) => {
13
+ if (from && typeof from === "object" || typeof from === "function") {
14
+ for (let key of __getOwnPropNames(from))
15
+ if (!__hasOwnProp.call(to, key) && key !== except)
16
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
+ }
18
+ return to;
19
+ };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ // If the importer is in node compatibility mode or this is not an ESM
22
+ // file that has been converted to a CommonJS file using a Babel-
23
+ // compatible transform (i.e. "__esModule" has not been set), then set
24
+ // "default" to the CommonJS "module.exports" for node compatibility.
25
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
+ mod
27
+ ));
28
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
+
30
+ // src/apple/index.ts
31
+ var apple_exports = {};
32
+ __export(apple_exports, {
33
+ signInWithApple: () => signInWithApple
34
+ });
35
+ module.exports = __toCommonJS(apple_exports);
36
+ var import_auth = __toESM(require("@react-native-firebase/auth"));
37
+ var import_react_native_apple_authentication = require("@invertase/react-native-apple-authentication");
38
+ var import_react_native = require("react-native");
39
+ var import_react_native2 = require("@fanapps/react-native");
40
+ async function signInWithApple() {
41
+ if (import_react_native.Platform.OS !== "ios") {
42
+ throw new import_react_native2.FanappsAuthError(
43
+ "Apple sign-in is only supported on iOS in v1.",
44
+ "auth/platform-not-supported"
45
+ );
46
+ }
47
+ if (!import_react_native_apple_authentication.appleAuth.isSupported) {
48
+ throw new import_react_native2.FanappsAuthError(
49
+ "Apple sign-in not supported on this device.",
50
+ "auth/not-supported"
51
+ );
52
+ }
53
+ const result = await import_react_native_apple_authentication.appleAuth.performRequest({
54
+ requestedOperation: import_react_native_apple_authentication.appleAuth.Operation.LOGIN,
55
+ requestedScopes: [import_react_native_apple_authentication.appleAuth.Scope.EMAIL, import_react_native_apple_authentication.appleAuth.Scope.FULL_NAME]
56
+ });
57
+ if (!result.identityToken) {
58
+ throw new import_react_native2.FanappsAuthError(
59
+ "Apple did not return an identity token.",
60
+ "auth/no-token"
61
+ );
62
+ }
63
+ const credential = import_auth.default.AppleAuthProvider.credential(
64
+ result.identityToken,
65
+ result.nonce ?? void 0
66
+ );
67
+ return (0, import_auth.default)().signInWithCredential(credential);
68
+ }
69
+ // Annotate the CommonJS export names for ESM import in node:
70
+ 0 && (module.exports = {
71
+ signInWithApple
72
+ });
73
+ //# sourceMappingURL=apple.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/apple/index.ts"],"sourcesContent":["import auth, { type FirebaseAuthTypes } from '@react-native-firebase/auth';\nimport { appleAuth } from '@invertase/react-native-apple-authentication';\nimport { Platform } from 'react-native';\nimport { FanappsAuthError } from '@fanapps/react-native';\n\nexport async function signInWithApple(): Promise<FirebaseAuthTypes.UserCredential> {\n if (Platform.OS !== 'ios') {\n throw new FanappsAuthError(\n 'Apple sign-in is only supported on iOS in v1.',\n 'auth/platform-not-supported',\n );\n }\n\n if (!appleAuth.isSupported) {\n throw new FanappsAuthError(\n 'Apple sign-in not supported on this device.',\n 'auth/not-supported',\n );\n }\n\n const result = await appleAuth.performRequest({\n requestedOperation: appleAuth.Operation.LOGIN,\n requestedScopes: [appleAuth.Scope.EMAIL, appleAuth.Scope.FULL_NAME],\n });\n\n if (!result.identityToken) {\n throw new FanappsAuthError(\n 'Apple did not return an identity token.',\n 'auth/no-token',\n );\n }\n\n const credential = auth.AppleAuthProvider.credential(\n result.identityToken,\n result.nonce ?? undefined,\n );\n\n return auth().signInWithCredential(credential);\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,kBAA6C;AAC7C,+CAA0B;AAC1B,0BAAyB;AACzB,IAAAA,uBAAiC;AAEjC,eAAsB,kBAA6D;AACjF,MAAI,6BAAS,OAAO,OAAO;AACzB,UAAM,IAAI;AAAA,MACR;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAEA,MAAI,CAAC,mDAAU,aAAa;AAC1B,UAAM,IAAI;AAAA,MACR;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAEA,QAAM,SAAS,MAAM,mDAAU,eAAe;AAAA,IAC5C,oBAAoB,mDAAU,UAAU;AAAA,IACxC,iBAAiB,CAAC,mDAAU,MAAM,OAAO,mDAAU,MAAM,SAAS;AAAA,EACpE,CAAC;AAED,MAAI,CAAC,OAAO,eAAe;AACzB,UAAM,IAAI;AAAA,MACR;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAEA,QAAM,aAAa,YAAAC,QAAK,kBAAkB;AAAA,IACxC,OAAO;AAAA,IACP,OAAO,SAAS;AAAA,EAClB;AAEA,aAAO,YAAAA,SAAK,EAAE,qBAAqB,UAAU;AAC/C;","names":["import_react_native","auth"]}
package/dist/apple.mjs ADDED
@@ -0,0 +1,38 @@
1
+ // src/apple/index.ts
2
+ import auth from "@react-native-firebase/auth";
3
+ import { appleAuth } from "@invertase/react-native-apple-authentication";
4
+ import { Platform } from "react-native";
5
+ import { FanappsAuthError } from "@fanapps/react-native";
6
+ async function signInWithApple() {
7
+ if (Platform.OS !== "ios") {
8
+ throw new FanappsAuthError(
9
+ "Apple sign-in is only supported on iOS in v1.",
10
+ "auth/platform-not-supported"
11
+ );
12
+ }
13
+ if (!appleAuth.isSupported) {
14
+ throw new FanappsAuthError(
15
+ "Apple sign-in not supported on this device.",
16
+ "auth/not-supported"
17
+ );
18
+ }
19
+ const result = await appleAuth.performRequest({
20
+ requestedOperation: appleAuth.Operation.LOGIN,
21
+ requestedScopes: [appleAuth.Scope.EMAIL, appleAuth.Scope.FULL_NAME]
22
+ });
23
+ if (!result.identityToken) {
24
+ throw new FanappsAuthError(
25
+ "Apple did not return an identity token.",
26
+ "auth/no-token"
27
+ );
28
+ }
29
+ const credential = auth.AppleAuthProvider.credential(
30
+ result.identityToken,
31
+ result.nonce ?? void 0
32
+ );
33
+ return auth().signInWithCredential(credential);
34
+ }
35
+ export {
36
+ signInWithApple
37
+ };
38
+ //# sourceMappingURL=apple.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/apple/index.ts"],"sourcesContent":["import auth, { type FirebaseAuthTypes } from '@react-native-firebase/auth';\nimport { appleAuth } from '@invertase/react-native-apple-authentication';\nimport { Platform } from 'react-native';\nimport { FanappsAuthError } from '@fanapps/react-native';\n\nexport async function signInWithApple(): Promise<FirebaseAuthTypes.UserCredential> {\n if (Platform.OS !== 'ios') {\n throw new FanappsAuthError(\n 'Apple sign-in is only supported on iOS in v1.',\n 'auth/platform-not-supported',\n );\n }\n\n if (!appleAuth.isSupported) {\n throw new FanappsAuthError(\n 'Apple sign-in not supported on this device.',\n 'auth/not-supported',\n );\n }\n\n const result = await appleAuth.performRequest({\n requestedOperation: appleAuth.Operation.LOGIN,\n requestedScopes: [appleAuth.Scope.EMAIL, appleAuth.Scope.FULL_NAME],\n });\n\n if (!result.identityToken) {\n throw new FanappsAuthError(\n 'Apple did not return an identity token.',\n 'auth/no-token',\n );\n }\n\n const credential = auth.AppleAuthProvider.credential(\n result.identityToken,\n result.nonce ?? undefined,\n );\n\n return auth().signInWithCredential(credential);\n}\n"],"mappings":";AAAA,OAAO,UAAsC;AAC7C,SAAS,iBAAiB;AAC1B,SAAS,gBAAgB;AACzB,SAAS,wBAAwB;AAEjC,eAAsB,kBAA6D;AACjF,MAAI,SAAS,OAAO,OAAO;AACzB,UAAM,IAAI;AAAA,MACR;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAEA,MAAI,CAAC,UAAU,aAAa;AAC1B,UAAM,IAAI;AAAA,MACR;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAEA,QAAM,SAAS,MAAM,UAAU,eAAe;AAAA,IAC5C,oBAAoB,UAAU,UAAU;AAAA,IACxC,iBAAiB,CAAC,UAAU,MAAM,OAAO,UAAU,MAAM,SAAS;AAAA,EACpE,CAAC;AAED,MAAI,CAAC,OAAO,eAAe;AACzB,UAAM,IAAI;AAAA,MACR;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAEA,QAAM,aAAa,KAAK,kBAAkB;AAAA,IACxC,OAAO;AAAA,IACP,OAAO,SAAS;AAAA,EAClB;AAEA,SAAO,KAAK,EAAE,qBAAqB,UAAU;AAC/C;","names":[]}
@@ -0,0 +1,5 @@
1
+ import { FirebaseAuthTypes } from '@react-native-firebase/auth';
2
+
3
+ declare function signInWithGoogle(): Promise<FirebaseAuthTypes.UserCredential>;
4
+
5
+ export { signInWithGoogle };
@@ -0,0 +1,5 @@
1
+ import { FirebaseAuthTypes } from '@react-native-firebase/auth';
2
+
3
+ declare function signInWithGoogle(): Promise<FirebaseAuthTypes.UserCredential>;
4
+
5
+ export { signInWithGoogle };
package/dist/google.js ADDED
@@ -0,0 +1,52 @@
1
+ "use strict";
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __export = (target, all) => {
9
+ for (var name in all)
10
+ __defProp(target, name, { get: all[name], enumerable: true });
11
+ };
12
+ var __copyProps = (to, from, except, desc) => {
13
+ if (from && typeof from === "object" || typeof from === "function") {
14
+ for (let key of __getOwnPropNames(from))
15
+ if (!__hasOwnProp.call(to, key) && key !== except)
16
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
+ }
18
+ return to;
19
+ };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ // If the importer is in node compatibility mode or this is not an ESM
22
+ // file that has been converted to a CommonJS file using a Babel-
23
+ // compatible transform (i.e. "__esModule" has not been set), then set
24
+ // "default" to the CommonJS "module.exports" for node compatibility.
25
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
+ mod
27
+ ));
28
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
+
30
+ // src/google/index.ts
31
+ var google_exports = {};
32
+ __export(google_exports, {
33
+ signInWithGoogle: () => signInWithGoogle
34
+ });
35
+ module.exports = __toCommonJS(google_exports);
36
+ var import_auth = __toESM(require("@react-native-firebase/auth"));
37
+ var import_google_signin = require("@react-native-google-signin/google-signin");
38
+ async function signInWithGoogle() {
39
+ await import_google_signin.GoogleSignin.hasPlayServices({ showPlayServicesUpdateDialog: true });
40
+ const result = await import_google_signin.GoogleSignin.signIn();
41
+ const idToken = "data" in result ? result.data?.idToken ?? null : result.idToken;
42
+ if (!idToken) {
43
+ throw new Error("Google sign-in returned no ID token.");
44
+ }
45
+ const credential = import_auth.default.GoogleAuthProvider.credential(idToken);
46
+ return (0, import_auth.default)().signInWithCredential(credential);
47
+ }
48
+ // Annotate the CommonJS export names for ESM import in node:
49
+ 0 && (module.exports = {
50
+ signInWithGoogle
51
+ });
52
+ //# sourceMappingURL=google.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/google/index.ts"],"sourcesContent":["import auth, { type FirebaseAuthTypes } from '@react-native-firebase/auth';\nimport { GoogleSignin } from '@react-native-google-signin/google-signin';\n\nexport async function signInWithGoogle(): Promise<FirebaseAuthTypes.UserCredential> {\n await GoogleSignin.hasPlayServices({ showPlayServicesUpdateDialog: true });\n const result = await GoogleSignin.signIn();\n const idToken =\n 'data' in result\n ? result.data?.idToken ?? null\n : (result as { idToken: string | null }).idToken;\n\n if (!idToken) {\n throw new Error('Google sign-in returned no ID token.');\n }\n\n const credential = auth.GoogleAuthProvider.credential(idToken);\n return auth().signInWithCredential(credential);\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,kBAA6C;AAC7C,2BAA6B;AAE7B,eAAsB,mBAA8D;AAClF,QAAM,kCAAa,gBAAgB,EAAE,8BAA8B,KAAK,CAAC;AACzE,QAAM,SAAS,MAAM,kCAAa,OAAO;AACzC,QAAM,UACJ,UAAU,SACN,OAAO,MAAM,WAAW,OACvB,OAAsC;AAE7C,MAAI,CAAC,SAAS;AACZ,UAAM,IAAI,MAAM,sCAAsC;AAAA,EACxD;AAEA,QAAM,aAAa,YAAAA,QAAK,mBAAmB,WAAW,OAAO;AAC7D,aAAO,YAAAA,SAAK,EAAE,qBAAqB,UAAU;AAC/C;","names":["auth"]}
@@ -0,0 +1,17 @@
1
+ // src/google/index.ts
2
+ import auth from "@react-native-firebase/auth";
3
+ import { GoogleSignin } from "@react-native-google-signin/google-signin";
4
+ async function signInWithGoogle() {
5
+ await GoogleSignin.hasPlayServices({ showPlayServicesUpdateDialog: true });
6
+ const result = await GoogleSignin.signIn();
7
+ const idToken = "data" in result ? result.data?.idToken ?? null : result.idToken;
8
+ if (!idToken) {
9
+ throw new Error("Google sign-in returned no ID token.");
10
+ }
11
+ const credential = auth.GoogleAuthProvider.credential(idToken);
12
+ return auth().signInWithCredential(credential);
13
+ }
14
+ export {
15
+ signInWithGoogle
16
+ };
17
+ //# sourceMappingURL=google.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/google/index.ts"],"sourcesContent":["import auth, { type FirebaseAuthTypes } from '@react-native-firebase/auth';\nimport { GoogleSignin } from '@react-native-google-signin/google-signin';\n\nexport async function signInWithGoogle(): Promise<FirebaseAuthTypes.UserCredential> {\n await GoogleSignin.hasPlayServices({ showPlayServicesUpdateDialog: true });\n const result = await GoogleSignin.signIn();\n const idToken =\n 'data' in result\n ? result.data?.idToken ?? null\n : (result as { idToken: string | null }).idToken;\n\n if (!idToken) {\n throw new Error('Google sign-in returned no ID token.');\n }\n\n const credential = auth.GoogleAuthProvider.credential(idToken);\n return auth().signInWithCredential(credential);\n}\n"],"mappings":";AAAA,OAAO,UAAsC;AAC7C,SAAS,oBAAoB;AAE7B,eAAsB,mBAA8D;AAClF,QAAM,aAAa,gBAAgB,EAAE,8BAA8B,KAAK,CAAC;AACzE,QAAM,SAAS,MAAM,aAAa,OAAO;AACzC,QAAM,UACJ,UAAU,SACN,OAAO,MAAM,WAAW,OACvB,OAAsC;AAE7C,MAAI,CAAC,SAAS;AACZ,UAAM,IAAI,MAAM,sCAAsC;AAAA,EACxD;AAEA,QAAM,aAAa,KAAK,mBAAmB,WAAW,OAAO;AAC7D,SAAO,KAAK,EAAE,qBAAqB,UAAU;AAC/C;","names":[]}
package/dist/index.d.mts CHANGED
@@ -1,12 +1,8 @@
1
1
  import * as react_jsx_runtime from 'react/jsx-runtime';
2
2
  import { QueryClient, UseQueryResult, UseMutationResult } from '@tanstack/react-query';
3
3
  import { ReactNode } from 'react';
4
-
5
- interface StorageAdapter {
6
- getItem(key: string): Promise<string | null>;
7
- setItem(key: string, value: string): Promise<void>;
8
- removeItem(key: string): Promise<void>;
9
- }
4
+ import { S as StorageAdapter } from './storage-D6z5ScLn.mjs';
5
+ import { FirebaseAuthTypes } from '@react-native-firebase/auth';
10
6
 
11
7
  type Locale = string;
12
8
  type EntryData = Record<string, unknown>;
@@ -187,6 +183,32 @@ declare class FanappsAuthError extends Error {
187
183
  constructor(message: string, code: string);
188
184
  }
189
185
 
186
+ type AuthListener = (snapshot: AuthStoreSnapshot) => void;
187
+ interface AuthStoreSnapshot {
188
+ user: AuthUser | null;
189
+ firebaseUser: FirebaseAuthTypes.User | null;
190
+ status: AuthStatus;
191
+ }
192
+ declare class AuthStore {
193
+ private snapshot;
194
+ private listeners;
195
+ private unsubscribe;
196
+ start(): void;
197
+ stop(): void;
198
+ subscribe(listener: AuthListener): () => void;
199
+ getSnapshot(): AuthStoreSnapshot;
200
+ getCurrentIdToken(): Promise<string | null>;
201
+ private emit;
202
+ }
203
+
204
+ interface FanappsContextValue {
205
+ client: FanappsClient;
206
+ authStore: AuthStore;
207
+ storage: StorageAdapter | undefined;
208
+ locale?: Locale;
209
+ }
210
+ declare function useFanapps(): FanappsContextValue;
211
+
190
212
  declare function useFanappsClient(): FanappsClient;
191
213
 
192
214
  interface UseAuthResult {
@@ -196,8 +218,6 @@ interface UseAuthResult {
196
218
  signUpWithEmail(email: string, password: string): Promise<AuthUser>;
197
219
  sendPasswordResetEmail(email: string): Promise<void>;
198
220
  sendEmailVerification(): Promise<void>;
199
- signInWithGoogle(): Promise<AuthUser>;
200
- signInWithApple(): Promise<AuthUser>;
201
221
  signOut(): Promise<void>;
202
222
  }
203
223
  declare function useAuth(): UseAuthResult;
@@ -210,17 +230,6 @@ declare function useArticles(filters?: ArticleFilters, options?: HookOptions): U
210
230
 
211
231
  declare function useArticle(id: string | number | null | undefined, options?: HookOptions): UseQueryResult<Article>;
212
232
 
213
- interface UseRegisterDeviceResult {
214
- targetId: string | null;
215
- token: string | null;
216
- target: PushTarget | null;
217
- isRegistering: boolean;
218
- error: Error | null;
219
- register(): Promise<PushTarget>;
220
- unregister(): Promise<void>;
221
- }
222
- declare function useRegisterDevice(): UseRegisterDeviceResult;
223
-
224
233
  declare function useTrivias(options?: HookOptions): UseQueryResult<Trivia[]>;
225
234
 
226
235
  declare function useTrivia(id: string | number | null | undefined, options?: HookOptions): UseQueryResult<Trivia>;
@@ -231,10 +240,4 @@ interface SubmitTriviaResponseInput {
231
240
  }
232
241
  declare function useSubmitTriviaResponse(): UseMutationResult<TriviaResponseResult, FanappsError, SubmitTriviaResponseInput>;
233
242
 
234
- interface UseTopicSubscriptionResult {
235
- subscribe(topic: string): Promise<void>;
236
- unsubscribe(topic: string): Promise<void>;
237
- }
238
- declare function useTopicSubscription(): UseTopicSubscriptionResult;
239
-
240
- export { type Article, type ArticleFilters, type AuthStatus, type AuthUser, type CreatePushTargetInput, type Entry, type EntryData, type EntryFilters, FanappsAuthError, FanappsClient, type FanappsClientOptions, FanappsError, FanappsProvider, type FanappsProviderProps, type HookOptions, type Locale, type Paginated, type PaginationLinks, type PaginationMeta, type PaginationParams, type PushTarget, type StorageAdapter, type SubmitTriviaResponseInput, type Trivia, type TriviaAnswer, type TriviaResponseResult, type UseAuthResult, type UseRegisterDeviceResult, type UseTopicSubscriptionResult, useArticle, useArticles, useAuth, useEntries, useEntry, useFanappsClient, useRegisterDevice, useSubmitTriviaResponse, useTopicSubscription, useTrivia, useTrivias };
243
+ export { type Article, type ArticleFilters, type ArticleStatus, type AuthStatus, type AuthUser, type CreatePushTargetInput, type Entry, type EntryData, type EntryFilters, FanappsAuthError, FanappsClient, type FanappsClientOptions, type FanappsContextValue, FanappsError, FanappsProvider, type FanappsProviderProps, type HookOptions, type Locale, type Paginated, type PaginationLinks, type PaginationMeta, type PaginationParams, type PushTarget, StorageAdapter, type SubmitTriviaResponseInput, type Trivia, type TriviaAnswer, type TriviaResponseResult, type UseAuthResult, useArticle, useArticles, useAuth, useEntries, useEntry, useFanapps, useFanappsClient, useSubmitTriviaResponse, useTrivia, useTrivias };
package/dist/index.d.ts CHANGED
@@ -1,12 +1,8 @@
1
1
  import * as react_jsx_runtime from 'react/jsx-runtime';
2
2
  import { QueryClient, UseQueryResult, UseMutationResult } from '@tanstack/react-query';
3
3
  import { ReactNode } from 'react';
4
-
5
- interface StorageAdapter {
6
- getItem(key: string): Promise<string | null>;
7
- setItem(key: string, value: string): Promise<void>;
8
- removeItem(key: string): Promise<void>;
9
- }
4
+ import { S as StorageAdapter } from './storage-D6z5ScLn.js';
5
+ import { FirebaseAuthTypes } from '@react-native-firebase/auth';
10
6
 
11
7
  type Locale = string;
12
8
  type EntryData = Record<string, unknown>;
@@ -187,6 +183,32 @@ declare class FanappsAuthError extends Error {
187
183
  constructor(message: string, code: string);
188
184
  }
189
185
 
186
+ type AuthListener = (snapshot: AuthStoreSnapshot) => void;
187
+ interface AuthStoreSnapshot {
188
+ user: AuthUser | null;
189
+ firebaseUser: FirebaseAuthTypes.User | null;
190
+ status: AuthStatus;
191
+ }
192
+ declare class AuthStore {
193
+ private snapshot;
194
+ private listeners;
195
+ private unsubscribe;
196
+ start(): void;
197
+ stop(): void;
198
+ subscribe(listener: AuthListener): () => void;
199
+ getSnapshot(): AuthStoreSnapshot;
200
+ getCurrentIdToken(): Promise<string | null>;
201
+ private emit;
202
+ }
203
+
204
+ interface FanappsContextValue {
205
+ client: FanappsClient;
206
+ authStore: AuthStore;
207
+ storage: StorageAdapter | undefined;
208
+ locale?: Locale;
209
+ }
210
+ declare function useFanapps(): FanappsContextValue;
211
+
190
212
  declare function useFanappsClient(): FanappsClient;
191
213
 
192
214
  interface UseAuthResult {
@@ -196,8 +218,6 @@ interface UseAuthResult {
196
218
  signUpWithEmail(email: string, password: string): Promise<AuthUser>;
197
219
  sendPasswordResetEmail(email: string): Promise<void>;
198
220
  sendEmailVerification(): Promise<void>;
199
- signInWithGoogle(): Promise<AuthUser>;
200
- signInWithApple(): Promise<AuthUser>;
201
221
  signOut(): Promise<void>;
202
222
  }
203
223
  declare function useAuth(): UseAuthResult;
@@ -210,17 +230,6 @@ declare function useArticles(filters?: ArticleFilters, options?: HookOptions): U
210
230
 
211
231
  declare function useArticle(id: string | number | null | undefined, options?: HookOptions): UseQueryResult<Article>;
212
232
 
213
- interface UseRegisterDeviceResult {
214
- targetId: string | null;
215
- token: string | null;
216
- target: PushTarget | null;
217
- isRegistering: boolean;
218
- error: Error | null;
219
- register(): Promise<PushTarget>;
220
- unregister(): Promise<void>;
221
- }
222
- declare function useRegisterDevice(): UseRegisterDeviceResult;
223
-
224
233
  declare function useTrivias(options?: HookOptions): UseQueryResult<Trivia[]>;
225
234
 
226
235
  declare function useTrivia(id: string | number | null | undefined, options?: HookOptions): UseQueryResult<Trivia>;
@@ -231,10 +240,4 @@ interface SubmitTriviaResponseInput {
231
240
  }
232
241
  declare function useSubmitTriviaResponse(): UseMutationResult<TriviaResponseResult, FanappsError, SubmitTriviaResponseInput>;
233
242
 
234
- interface UseTopicSubscriptionResult {
235
- subscribe(topic: string): Promise<void>;
236
- unsubscribe(topic: string): Promise<void>;
237
- }
238
- declare function useTopicSubscription(): UseTopicSubscriptionResult;
239
-
240
- export { type Article, type ArticleFilters, type AuthStatus, type AuthUser, type CreatePushTargetInput, type Entry, type EntryData, type EntryFilters, FanappsAuthError, FanappsClient, type FanappsClientOptions, FanappsError, FanappsProvider, type FanappsProviderProps, type HookOptions, type Locale, type Paginated, type PaginationLinks, type PaginationMeta, type PaginationParams, type PushTarget, type StorageAdapter, type SubmitTriviaResponseInput, type Trivia, type TriviaAnswer, type TriviaResponseResult, type UseAuthResult, type UseRegisterDeviceResult, type UseTopicSubscriptionResult, useArticle, useArticles, useAuth, useEntries, useEntry, useFanappsClient, useRegisterDevice, useSubmitTriviaResponse, useTopicSubscription, useTrivia, useTrivias };
243
+ export { type Article, type ArticleFilters, type ArticleStatus, type AuthStatus, type AuthUser, type CreatePushTargetInput, type Entry, type EntryData, type EntryFilters, FanappsAuthError, FanappsClient, type FanappsClientOptions, type FanappsContextValue, FanappsError, FanappsProvider, type FanappsProviderProps, type HookOptions, type Locale, type Paginated, type PaginationLinks, type PaginationMeta, type PaginationParams, type PushTarget, StorageAdapter, type SubmitTriviaResponseInput, type Trivia, type TriviaAnswer, type TriviaResponseResult, type UseAuthResult, useArticle, useArticles, useAuth, useEntries, useEntry, useFanapps, useFanappsClient, useSubmitTriviaResponse, useTrivia, useTrivias };