@fanapps/react-native 0.3.1 → 0.4.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 +40 -21
- package/dist/apple.d.mts +5 -0
- package/dist/apple.d.ts +5 -0
- package/dist/apple.js +83 -0
- package/dist/apple.js.map +1 -0
- package/dist/apple.mjs +41 -0
- package/dist/apple.mjs.map +1 -0
- package/dist/chunk-SWOKCWWX.mjs +13 -0
- package/dist/chunk-SWOKCWWX.mjs.map +1 -0
- package/dist/chunk-YZINATR6.mjs +18 -0
- package/dist/chunk-YZINATR6.mjs.map +1 -0
- package/dist/google.d.mts +5 -0
- package/dist/google.d.ts +5 -0
- package/dist/google.js +52 -0
- package/dist/google.js.map +1 -0
- package/dist/google.mjs +17 -0
- package/dist/google.mjs.map +1 -0
- package/dist/index.d.mts +3 -159
- package/dist/index.d.ts +3 -159
- package/dist/index.js +19 -234
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +24 -251
- package/dist/index.mjs.map +1 -1
- package/dist/push.d.mts +21 -0
- package/dist/push.d.ts +21 -0
- package/dist/push.js +211 -0
- package/dist/push.js.map +1 -0
- package/dist/push.mjs +164 -0
- package/dist/push.mjs.map +1 -0
- package/dist/types-CKpYrzCw.d.mts +147 -0
- package/dist/types-CKpYrzCw.d.ts +147 -0
- package/package.json +43 -8
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
|
-
|
|
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
|
-
|
|
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 |
|
|
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,22 @@ function Screen() {
|
|
|
92
98
|
}
|
|
93
99
|
```
|
|
94
100
|
|
|
101
|
+
Google and Apple sign-in are imported from subpaths (peer-isolated):
|
|
102
|
+
|
|
103
|
+
```tsx
|
|
104
|
+
import { signInWithGoogle } from '@fanapps/react-native/google';
|
|
105
|
+
import { signInWithApple } from '@fanapps/react-native/apple';
|
|
106
|
+
|
|
107
|
+
await signInWithGoogle(); // returns FirebaseAuthTypes.UserCredential
|
|
108
|
+
await signInWithApple();
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
State propagates through `useAuth().user` automatically via Firebase's `onAuthStateChanged`.
|
|
112
|
+
|
|
95
113
|
**Notes**
|
|
96
114
|
|
|
97
115
|
- `user` is sourced entirely from Firebase (`onAuthStateChanged`) — no backend round-trip on auth state change.
|
|
98
|
-
- `
|
|
99
|
-
- `signInWithApple` is iOS-only in v1. On Android it throws `auth/platform-not-supported`.
|
|
116
|
+
- `signInWithApple` is iOS-only in v1. On Android it throws `FanappsAuthError` with code `auth/platform-not-supported`.
|
|
100
117
|
- 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
118
|
|
|
102
119
|
## Push notifications
|
|
@@ -106,7 +123,8 @@ The SDK registers the device's FCM token as a _push target_ on the backend, usin
|
|
|
106
123
|
### Register a device
|
|
107
124
|
|
|
108
125
|
```tsx
|
|
109
|
-
import { useAuth
|
|
126
|
+
import { useAuth } from '@fanapps/react-native';
|
|
127
|
+
import { useRegisterDevice } from '@fanapps/react-native/push';
|
|
110
128
|
import { useEffect } from 'react';
|
|
111
129
|
|
|
112
130
|
function PushSetup() {
|
|
@@ -137,7 +155,7 @@ function PushSetup() {
|
|
|
137
155
|
FCM topics are the cheapest way to broadcast — no backend round-trip, no storage needed.
|
|
138
156
|
|
|
139
157
|
```tsx
|
|
140
|
-
import { useTopicSubscription } from '@fanapps/react-native';
|
|
158
|
+
import { useTopicSubscription } from '@fanapps/react-native/push';
|
|
141
159
|
|
|
142
160
|
const topics = useTopicSubscription();
|
|
143
161
|
await topics.subscribe('news');
|
|
@@ -238,6 +256,7 @@ if (error instanceof FanappsError && error.status === 401) {
|
|
|
238
256
|
}
|
|
239
257
|
|
|
240
258
|
try {
|
|
259
|
+
// import { signInWithGoogle } from '@fanapps/react-native/google';
|
|
241
260
|
await signInWithGoogle();
|
|
242
261
|
} catch (e) {
|
|
243
262
|
if (e instanceof FanappsAuthError && e.code === 'auth/platform-not-supported') {
|
|
@@ -258,7 +277,7 @@ interface StorageAdapter {
|
|
|
258
277
|
}
|
|
259
278
|
```
|
|
260
279
|
|
|
261
|
-
|
|
280
|
+
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
281
|
|
|
263
282
|
## Build
|
|
264
283
|
|
package/dist/apple.d.mts
ADDED
package/dist/apple.d.ts
ADDED
package/dist/apple.js
ADDED
|
@@ -0,0 +1,83 @@
|
|
|
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
|
+
|
|
40
|
+
// src/auth/errors.ts
|
|
41
|
+
var FanappsAuthError = class extends Error {
|
|
42
|
+
constructor(message, code) {
|
|
43
|
+
super(message);
|
|
44
|
+
this.name = "FanappsAuthError";
|
|
45
|
+
this.code = code;
|
|
46
|
+
}
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
// src/apple/index.ts
|
|
50
|
+
async function signInWithApple() {
|
|
51
|
+
if (import_react_native.Platform.OS !== "ios") {
|
|
52
|
+
throw new FanappsAuthError(
|
|
53
|
+
"Apple sign-in is only supported on iOS in v1.",
|
|
54
|
+
"auth/platform-not-supported"
|
|
55
|
+
);
|
|
56
|
+
}
|
|
57
|
+
if (!import_react_native_apple_authentication.appleAuth.isSupported) {
|
|
58
|
+
throw new FanappsAuthError(
|
|
59
|
+
"Apple sign-in not supported on this device.",
|
|
60
|
+
"auth/not-supported"
|
|
61
|
+
);
|
|
62
|
+
}
|
|
63
|
+
const result = await import_react_native_apple_authentication.appleAuth.performRequest({
|
|
64
|
+
requestedOperation: import_react_native_apple_authentication.appleAuth.Operation.LOGIN,
|
|
65
|
+
requestedScopes: [import_react_native_apple_authentication.appleAuth.Scope.EMAIL, import_react_native_apple_authentication.appleAuth.Scope.FULL_NAME]
|
|
66
|
+
});
|
|
67
|
+
if (!result.identityToken) {
|
|
68
|
+
throw new FanappsAuthError(
|
|
69
|
+
"Apple did not return an identity token.",
|
|
70
|
+
"auth/no-token"
|
|
71
|
+
);
|
|
72
|
+
}
|
|
73
|
+
const credential = import_auth.default.AppleAuthProvider.credential(
|
|
74
|
+
result.identityToken,
|
|
75
|
+
result.nonce ?? void 0
|
|
76
|
+
);
|
|
77
|
+
return (0, import_auth.default)().signInWithCredential(credential);
|
|
78
|
+
}
|
|
79
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
80
|
+
0 && (module.exports = {
|
|
81
|
+
signInWithApple
|
|
82
|
+
});
|
|
83
|
+
//# sourceMappingURL=apple.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/apple/index.ts","../src/auth/errors.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 '../auth/errors';\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","export class FanappsAuthError extends Error {\n readonly code: string;\n\n constructor(message: string, code: string) {\n super(message);\n this.name = 'FanappsAuthError';\n this.code = code;\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,kBAA6C;AAC7C,+CAA0B;AAC1B,0BAAyB;;;ACFlB,IAAM,mBAAN,cAA+B,MAAM;AAAA,EAG1C,YAAY,SAAiB,MAAc;AACzC,UAAM,OAAO;AACb,SAAK,OAAO;AACZ,SAAK,OAAO;AAAA,EACd;AACF;;;ADHA,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,YAAAA,QAAK,kBAAkB;AAAA,IACxC,OAAO;AAAA,IACP,OAAO,SAAS;AAAA,EAClB;AAEA,aAAO,YAAAA,SAAK,EAAE,qBAAqB,UAAU;AAC/C;","names":["auth"]}
|
package/dist/apple.mjs
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import {
|
|
2
|
+
FanappsAuthError
|
|
3
|
+
} from "./chunk-SWOKCWWX.mjs";
|
|
4
|
+
|
|
5
|
+
// src/apple/index.ts
|
|
6
|
+
import auth from "@react-native-firebase/auth";
|
|
7
|
+
import { appleAuth } from "@invertase/react-native-apple-authentication";
|
|
8
|
+
import { Platform } from "react-native";
|
|
9
|
+
async function signInWithApple() {
|
|
10
|
+
if (Platform.OS !== "ios") {
|
|
11
|
+
throw new FanappsAuthError(
|
|
12
|
+
"Apple sign-in is only supported on iOS in v1.",
|
|
13
|
+
"auth/platform-not-supported"
|
|
14
|
+
);
|
|
15
|
+
}
|
|
16
|
+
if (!appleAuth.isSupported) {
|
|
17
|
+
throw new FanappsAuthError(
|
|
18
|
+
"Apple sign-in not supported on this device.",
|
|
19
|
+
"auth/not-supported"
|
|
20
|
+
);
|
|
21
|
+
}
|
|
22
|
+
const result = await appleAuth.performRequest({
|
|
23
|
+
requestedOperation: appleAuth.Operation.LOGIN,
|
|
24
|
+
requestedScopes: [appleAuth.Scope.EMAIL, appleAuth.Scope.FULL_NAME]
|
|
25
|
+
});
|
|
26
|
+
if (!result.identityToken) {
|
|
27
|
+
throw new FanappsAuthError(
|
|
28
|
+
"Apple did not return an identity token.",
|
|
29
|
+
"auth/no-token"
|
|
30
|
+
);
|
|
31
|
+
}
|
|
32
|
+
const credential = auth.AppleAuthProvider.credential(
|
|
33
|
+
result.identityToken,
|
|
34
|
+
result.nonce ?? void 0
|
|
35
|
+
);
|
|
36
|
+
return auth().signInWithCredential(credential);
|
|
37
|
+
}
|
|
38
|
+
export {
|
|
39
|
+
signInWithApple
|
|
40
|
+
};
|
|
41
|
+
//# 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 '../auth/errors';\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;AAGzB,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,13 @@
|
|
|
1
|
+
// src/auth/errors.ts
|
|
2
|
+
var FanappsAuthError = class extends Error {
|
|
3
|
+
constructor(message, code) {
|
|
4
|
+
super(message);
|
|
5
|
+
this.name = "FanappsAuthError";
|
|
6
|
+
this.code = code;
|
|
7
|
+
}
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
export {
|
|
11
|
+
FanappsAuthError
|
|
12
|
+
};
|
|
13
|
+
//# sourceMappingURL=chunk-SWOKCWWX.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/auth/errors.ts"],"sourcesContent":["export class FanappsAuthError extends Error {\n readonly code: string;\n\n constructor(message: string, code: string) {\n super(message);\n this.name = 'FanappsAuthError';\n this.code = code;\n }\n}\n"],"mappings":";AAAO,IAAM,mBAAN,cAA+B,MAAM;AAAA,EAG1C,YAAY,SAAiB,MAAc;AACzC,UAAM,OAAO;AACb,SAAK,OAAO;AACZ,SAAK,OAAO;AAAA,EACd;AACF;","names":[]}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
// src/context.ts
|
|
2
|
+
import { createContext, useContext } from "react";
|
|
3
|
+
var FanappsContext = createContext(null);
|
|
4
|
+
function useFanapps() {
|
|
5
|
+
const ctx = useContext(FanappsContext);
|
|
6
|
+
if (!ctx) {
|
|
7
|
+
throw new Error(
|
|
8
|
+
"@fanapps/react-native: useFanapps must be used inside <FanappsProvider>."
|
|
9
|
+
);
|
|
10
|
+
}
|
|
11
|
+
return ctx;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export {
|
|
15
|
+
FanappsContext,
|
|
16
|
+
useFanapps
|
|
17
|
+
};
|
|
18
|
+
//# sourceMappingURL=chunk-YZINATR6.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/context.ts"],"sourcesContent":["import { createContext, useContext } from 'react';\nimport type { AuthStore } from './auth/authStore';\nimport type { FanappsClient } from './client';\nimport type { StorageAdapter } from './storage';\nimport type { Locale } from './types';\n\nexport interface FanappsContextValue {\n client: FanappsClient;\n authStore: AuthStore;\n storage: StorageAdapter | undefined;\n locale?: Locale;\n}\n\nexport const FanappsContext = createContext<FanappsContextValue | null>(null);\n\nexport function useFanapps(): FanappsContextValue {\n const ctx = useContext(FanappsContext);\n if (!ctx) {\n throw new Error(\n '@fanapps/react-native: useFanapps must be used inside <FanappsProvider>.',\n );\n }\n return ctx;\n}\n"],"mappings":";AAAA,SAAS,eAAe,kBAAkB;AAanC,IAAM,iBAAiB,cAA0C,IAAI;AAErE,SAAS,aAAkC;AAChD,QAAM,MAAM,WAAW,cAAc;AACrC,MAAI,CAAC,KAAK;AACR,UAAM,IAAI;AAAA,MACR;AAAA,IACF;AAAA,EACF;AACA,SAAO;AACT;","names":[]}
|
package/dist/google.d.ts
ADDED
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"]}
|
package/dist/google.mjs
ADDED
|
@@ -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,145 +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
|
-
|
|
6
|
-
getItem(key: string): Promise<string | null>;
|
|
7
|
-
setItem(key: string, value: string): Promise<void>;
|
|
8
|
-
removeItem(key: string): Promise<void>;
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
type Locale = string;
|
|
12
|
-
type EntryData = Record<string, unknown>;
|
|
13
|
-
interface Entry {
|
|
14
|
-
id: string | number;
|
|
15
|
-
slug: string;
|
|
16
|
-
published: boolean;
|
|
17
|
-
date: string | null;
|
|
18
|
-
order: number | null;
|
|
19
|
-
collection: string | null;
|
|
20
|
-
blueprint: string;
|
|
21
|
-
data: EntryData;
|
|
22
|
-
created_at: string;
|
|
23
|
-
updated_at: string;
|
|
24
|
-
locale: Locale;
|
|
25
|
-
available_locales?: Locale[];
|
|
26
|
-
}
|
|
27
|
-
type ArticleStatus = 'draft' | 'scheduled' | 'published';
|
|
28
|
-
interface Article {
|
|
29
|
-
id: string | number;
|
|
30
|
-
title: string;
|
|
31
|
-
content: string;
|
|
32
|
-
status: ArticleStatus;
|
|
33
|
-
published_at: string | null;
|
|
34
|
-
featured_image_url: string | null;
|
|
35
|
-
created_at: string;
|
|
36
|
-
updated_at: string;
|
|
37
|
-
locale: Locale;
|
|
38
|
-
available_locales?: Locale[];
|
|
39
|
-
}
|
|
40
|
-
interface TriviaAnswer {
|
|
41
|
-
id: string | number;
|
|
42
|
-
text: string;
|
|
43
|
-
is_correct: boolean;
|
|
44
|
-
sort_order: number;
|
|
45
|
-
}
|
|
46
|
-
interface Trivia {
|
|
47
|
-
id: string | number;
|
|
48
|
-
title: string;
|
|
49
|
-
description: string | null;
|
|
50
|
-
featured_image_id: string | number | null;
|
|
51
|
-
featured_image?: {
|
|
52
|
-
id: string | number;
|
|
53
|
-
url: string;
|
|
54
|
-
[key: string]: unknown;
|
|
55
|
-
} | null;
|
|
56
|
-
awards_points: boolean;
|
|
57
|
-
points_amount: number;
|
|
58
|
-
max_time_seconds: number | null;
|
|
59
|
-
show_correct_after: boolean;
|
|
60
|
-
starts_at: string | null;
|
|
61
|
-
ends_at: string | null;
|
|
62
|
-
answers: TriviaAnswer[];
|
|
63
|
-
responses_count?: number;
|
|
64
|
-
created_at: string;
|
|
65
|
-
updated_at: string;
|
|
66
|
-
}
|
|
67
|
-
interface TriviaResponseResult {
|
|
68
|
-
is_correct: boolean;
|
|
69
|
-
points_awarded: number;
|
|
70
|
-
correct_answer?: TriviaAnswer;
|
|
71
|
-
}
|
|
72
|
-
interface PaginationMeta {
|
|
73
|
-
current_page: number;
|
|
74
|
-
last_page: number;
|
|
75
|
-
per_page: number;
|
|
76
|
-
total: number;
|
|
77
|
-
from: number | null;
|
|
78
|
-
to: number | null;
|
|
79
|
-
path?: string;
|
|
80
|
-
}
|
|
81
|
-
interface PaginationLinks {
|
|
82
|
-
first: string | null;
|
|
83
|
-
last: string | null;
|
|
84
|
-
prev: string | null;
|
|
85
|
-
next: string | null;
|
|
86
|
-
}
|
|
87
|
-
interface Paginated<T> {
|
|
88
|
-
data: T[];
|
|
89
|
-
meta: PaginationMeta;
|
|
90
|
-
links: PaginationLinks;
|
|
91
|
-
}
|
|
92
|
-
interface PaginationParams {
|
|
93
|
-
page?: number;
|
|
94
|
-
perPage?: number;
|
|
95
|
-
sort?: string;
|
|
96
|
-
}
|
|
97
|
-
interface EntryFilters extends PaginationParams {
|
|
98
|
-
blueprint?: string;
|
|
99
|
-
collection?: string;
|
|
100
|
-
slug?: string;
|
|
101
|
-
published?: boolean;
|
|
102
|
-
}
|
|
103
|
-
interface ArticleFilters extends PaginationParams {
|
|
104
|
-
status?: ArticleStatus;
|
|
105
|
-
}
|
|
106
|
-
interface HookOptions {
|
|
107
|
-
locale?: Locale;
|
|
108
|
-
enabled?: boolean;
|
|
109
|
-
}
|
|
110
|
-
type AuthStatus = 'loading' | 'signed-in' | 'signed-out';
|
|
111
|
-
interface AuthUser {
|
|
112
|
-
uid: string;
|
|
113
|
-
email: string | null;
|
|
114
|
-
displayName: string | null;
|
|
115
|
-
photoURL: string | null;
|
|
116
|
-
phoneNumber: string | null;
|
|
117
|
-
isAnonymous: boolean;
|
|
118
|
-
providerId: string | null;
|
|
119
|
-
}
|
|
120
|
-
interface PushTarget {
|
|
121
|
-
id: string;
|
|
122
|
-
app_user_id: number | string | null;
|
|
123
|
-
identifier: string;
|
|
124
|
-
provider: 'fcm' | 'apns';
|
|
125
|
-
provider_id: string | null;
|
|
126
|
-
device_brand: string | null;
|
|
127
|
-
device_model: string | null;
|
|
128
|
-
os_name: string | null;
|
|
129
|
-
os_version: string | null;
|
|
130
|
-
last_seen_at: string | null;
|
|
131
|
-
created_at: string;
|
|
132
|
-
updated_at: string;
|
|
133
|
-
}
|
|
134
|
-
interface CreatePushTargetInput {
|
|
135
|
-
targetId: string;
|
|
136
|
-
identifier: string;
|
|
137
|
-
providerId?: string;
|
|
138
|
-
deviceBrand?: string;
|
|
139
|
-
deviceModel?: string;
|
|
140
|
-
osName?: string;
|
|
141
|
-
osVersion?: string;
|
|
142
|
-
}
|
|
4
|
+
import { L as Locale, S as StorageAdapter, C as CreatePushTargetInput, P as PushTarget, A as AuthUser, a as AuthStatus, E as EntryFilters, H as HookOptions, b as Paginated, c as Entry, d as ArticleFilters, e as Article, T as Trivia, f as TriviaResponseResult } from './types-CKpYrzCw.mjs';
|
|
5
|
+
export { g as ArticleStatus, h as EntryData, i as PaginationLinks, j as PaginationMeta, k as PaginationParams, l as TriviaAnswer } from './types-CKpYrzCw.mjs';
|
|
143
6
|
|
|
144
7
|
interface FanappsProviderProps {
|
|
145
8
|
apiKey: string;
|
|
@@ -196,8 +59,6 @@ interface UseAuthResult {
|
|
|
196
59
|
signUpWithEmail(email: string, password: string): Promise<AuthUser>;
|
|
197
60
|
sendPasswordResetEmail(email: string): Promise<void>;
|
|
198
61
|
sendEmailVerification(): Promise<void>;
|
|
199
|
-
signInWithGoogle(): Promise<AuthUser>;
|
|
200
|
-
signInWithApple(): Promise<AuthUser>;
|
|
201
62
|
signOut(): Promise<void>;
|
|
202
63
|
}
|
|
203
64
|
declare function useAuth(): UseAuthResult;
|
|
@@ -210,17 +71,6 @@ declare function useArticles(filters?: ArticleFilters, options?: HookOptions): U
|
|
|
210
71
|
|
|
211
72
|
declare function useArticle(id: string | number | null | undefined, options?: HookOptions): UseQueryResult<Article>;
|
|
212
73
|
|
|
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
74
|
declare function useTrivias(options?: HookOptions): UseQueryResult<Trivia[]>;
|
|
225
75
|
|
|
226
76
|
declare function useTrivia(id: string | number | null | undefined, options?: HookOptions): UseQueryResult<Trivia>;
|
|
@@ -231,10 +81,4 @@ interface SubmitTriviaResponseInput {
|
|
|
231
81
|
}
|
|
232
82
|
declare function useSubmitTriviaResponse(): UseMutationResult<TriviaResponseResult, FanappsError, SubmitTriviaResponseInput>;
|
|
233
83
|
|
|
234
|
-
|
|
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 };
|
|
84
|
+
export { Article, ArticleFilters, AuthStatus, AuthUser, CreatePushTargetInput, Entry, EntryFilters, FanappsAuthError, FanappsClient, type FanappsClientOptions, FanappsError, FanappsProvider, type FanappsProviderProps, HookOptions, Locale, Paginated, PushTarget, StorageAdapter, type SubmitTriviaResponseInput, Trivia, TriviaResponseResult, type UseAuthResult, useArticle, useArticles, useAuth, useEntries, useEntry, useFanappsClient, useSubmitTriviaResponse, useTrivia, useTrivias };
|