@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/dist/index.d.ts 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
- interface StorageAdapter {
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.js';
5
+ export { g as ArticleStatus, h as EntryData, i as PaginationLinks, j as PaginationMeta, k as PaginationParams, l as TriviaAnswer } from './types-CKpYrzCw.js';
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
- 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 };
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 };
package/dist/index.js CHANGED
@@ -28,8 +28,8 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
28
28
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
29
 
30
30
  // src/index.ts
31
- var index_exports = {};
32
- __export(index_exports, {
31
+ var src_exports = {};
32
+ __export(src_exports, {
33
33
  FanappsAuthError: () => FanappsAuthError,
34
34
  FanappsClient: () => FanappsClient,
35
35
  FanappsError: () => FanappsError,
@@ -40,13 +40,11 @@ __export(index_exports, {
40
40
  useEntries: () => useEntries,
41
41
  useEntry: () => useEntry,
42
42
  useFanappsClient: () => useFanappsClient,
43
- useRegisterDevice: () => useRegisterDevice,
44
43
  useSubmitTriviaResponse: () => useSubmitTriviaResponse,
45
- useTopicSubscription: () => useTopicSubscription,
46
44
  useTrivia: () => useTrivia,
47
45
  useTrivias: () => useTrivias
48
46
  });
49
- module.exports = __toCommonJS(index_exports);
47
+ module.exports = __toCommonJS(src_exports);
50
48
 
51
49
  // src/provider.tsx
52
50
  var import_react_query = require("@tanstack/react-query");
@@ -241,12 +239,6 @@ function useFanapps() {
241
239
  return ctx;
242
240
  }
243
241
 
244
- // src/push/storage.ts
245
- var import_async_storage = __toESM(require("@react-native-async-storage/async-storage"));
246
- function resolveStorage(explicit) {
247
- return explicit ?? import_async_storage.default;
248
- }
249
-
250
242
  // src/provider.tsx
251
243
  var import_jsx_runtime = require("react/jsx-runtime");
252
244
  var DEFAULT_BASE_URL = "https://fanapps.app";
@@ -268,7 +260,6 @@ function FanappsProvider({
268
260
  authStore.start();
269
261
  return () => authStore.stop();
270
262
  }, [authStore]);
271
- const resolvedStorage = (0, import_react2.useMemo)(() => resolveStorage(storage), [storage]);
272
263
  const client = (0, import_react2.useMemo)(
273
264
  () => new FanappsClient({
274
265
  apiKey,
@@ -283,8 +274,8 @@ function FanappsProvider({
283
274
  [queryClient]
284
275
  );
285
276
  const value = (0, import_react2.useMemo)(
286
- () => ({ client, authStore, storage: resolvedStorage, locale }),
287
- [client, authStore, resolvedStorage, locale]
277
+ () => ({ client, authStore, storage, locale }),
278
+ [client, authStore, storage, locale]
288
279
  );
289
280
  return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_query.QueryClientProvider, { client: resolvedQueryClient, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(FanappsContext.Provider, { value, children }) });
290
281
  }
@@ -305,56 +296,6 @@ function useFanappsClient() {
305
296
 
306
297
  // src/hooks/useAuth.ts
307
298
  var import_react3 = require("react");
308
-
309
- // src/auth/providers/google.ts
310
- var import_auth2 = __toESM(require("@react-native-firebase/auth"));
311
- var import_google_signin = require("@react-native-google-signin/google-signin");
312
- async function signInWithGoogle() {
313
- await import_google_signin.GoogleSignin.hasPlayServices({ showPlayServicesUpdateDialog: true });
314
- const result = await import_google_signin.GoogleSignin.signIn();
315
- const idToken = "data" in result ? result.data?.idToken ?? null : result.idToken;
316
- if (!idToken) {
317
- throw new Error("Google sign-in returned no ID token.");
318
- }
319
- const credential = import_auth2.default.GoogleAuthProvider.credential(idToken);
320
- return firebaseAuth().signInWithCredential(credential);
321
- }
322
-
323
- // src/auth/providers/apple.ts
324
- var import_auth3 = __toESM(require("@react-native-firebase/auth"));
325
- var import_react_native_apple_authentication = require("@invertase/react-native-apple-authentication");
326
- var import_react_native = require("react-native");
327
- async function signInWithApple() {
328
- if (import_react_native.Platform.OS !== "ios") {
329
- throw new FanappsAuthError(
330
- "Apple sign-in is only supported on iOS in v1. Use web OAuth on Android.",
331
- "auth/platform-not-supported"
332
- );
333
- }
334
- if (!import_react_native_apple_authentication.appleAuth.isSupported) {
335
- throw new FanappsAuthError(
336
- "Apple sign-in not supported on this device.",
337
- "auth/not-supported"
338
- );
339
- }
340
- const result = await import_react_native_apple_authentication.appleAuth.performRequest({
341
- requestedOperation: import_react_native_apple_authentication.appleAuth.Operation.LOGIN,
342
- requestedScopes: [import_react_native_apple_authentication.appleAuth.Scope.EMAIL, import_react_native_apple_authentication.appleAuth.Scope.FULL_NAME]
343
- });
344
- if (!result.identityToken) {
345
- throw new FanappsAuthError(
346
- "Apple did not return an identity token.",
347
- "auth/no-token"
348
- );
349
- }
350
- const credential = import_auth3.default.AppleAuthProvider.credential(
351
- result.identityToken,
352
- result.nonce ?? void 0
353
- );
354
- return firebaseAuth().signInWithCredential(credential);
355
- }
356
-
357
- // src/hooks/useAuth.ts
358
299
  function useAuth() {
359
300
  const { authStore } = useFanapps();
360
301
  const snapshot = (0, import_react3.useSyncExternalStore)(
@@ -362,14 +303,20 @@ function useAuth() {
362
303
  () => authStore.getSnapshot(),
363
304
  () => authStore.getSnapshot()
364
305
  );
365
- const signInWithEmail = (0, import_react3.useCallback)(async (email, password) => {
366
- const cred = await firebaseAuth().signInWithEmailAndPassword(email, password);
367
- return authStore.getSnapshot().user ?? mapMinimal(cred.user);
368
- }, [authStore]);
369
- const signUpWithEmail = (0, import_react3.useCallback)(async (email, password) => {
370
- const cred = await firebaseAuth().createUserWithEmailAndPassword(email, password);
371
- return authStore.getSnapshot().user ?? mapMinimal(cred.user);
372
- }, [authStore]);
306
+ const signInWithEmail = (0, import_react3.useCallback)(
307
+ async (email, password) => {
308
+ const cred = await firebaseAuth().signInWithEmailAndPassword(email, password);
309
+ return authStore.getSnapshot().user ?? mapMinimal(cred.user);
310
+ },
311
+ [authStore]
312
+ );
313
+ const signUpWithEmail = (0, import_react3.useCallback)(
314
+ async (email, password) => {
315
+ const cred = await firebaseAuth().createUserWithEmailAndPassword(email, password);
316
+ return authStore.getSnapshot().user ?? mapMinimal(cred.user);
317
+ },
318
+ [authStore]
319
+ );
373
320
  const sendPasswordResetEmail = (0, import_react3.useCallback)(async (email) => {
374
321
  await firebaseAuth().sendPasswordResetEmail(email);
375
322
  }, []);
@@ -378,14 +325,6 @@ function useAuth() {
378
325
  if (!current) throw new Error("No signed-in user to verify.");
379
326
  await current.sendEmailVerification();
380
327
  }, []);
381
- const signInWithGoogle2 = (0, import_react3.useCallback)(async () => {
382
- const cred = await signInWithGoogle();
383
- return authStore.getSnapshot().user ?? mapMinimal(cred.user);
384
- }, [authStore]);
385
- const signInWithApple2 = (0, import_react3.useCallback)(async () => {
386
- const cred = await signInWithApple();
387
- return authStore.getSnapshot().user ?? mapMinimal(cred.user);
388
- }, [authStore]);
389
328
  const signOut = (0, import_react3.useCallback)(async () => {
390
329
  await firebaseAuth().signOut();
391
330
  }, []);
@@ -396,8 +335,6 @@ function useAuth() {
396
335
  signUpWithEmail,
397
336
  sendPasswordResetEmail,
398
337
  sendEmailVerification,
399
- signInWithGoogle: signInWithGoogle2,
400
- signInWithApple: signInWithApple2,
401
338
  signOut
402
339
  };
403
340
  }
@@ -475,144 +412,6 @@ function useArticle(id, options = {}) {
475
412
  });
476
413
  }
477
414
 
478
- // src/hooks/useRegisterDevice.ts
479
- var import_react4 = require("react");
480
- var import_react_native2 = require("react-native");
481
-
482
- // src/push/messaging.ts
483
- var import_messaging = __toESM(require("@react-native-firebase/messaging"));
484
- var cached2 = null;
485
- function firebaseMessaging() {
486
- if (cached2) return cached2;
487
- cached2 = (0, import_messaging.default)();
488
- return cached2;
489
- }
490
-
491
- // src/push/targetIdStore.ts
492
- var KEY = "fanapps.pushTargetId";
493
- var TargetIdStore = class {
494
- constructor(storage) {
495
- this.storage = storage;
496
- }
497
- get() {
498
- return this.storage.getItem(KEY);
499
- }
500
- async set(id) {
501
- await this.storage.setItem(KEY, id);
502
- }
503
- async clear() {
504
- await this.storage.removeItem(KEY);
505
- }
506
- };
507
- function generateTargetId() {
508
- const bytes = new Uint8Array(16);
509
- if (typeof globalThis.crypto?.getRandomValues === "function") {
510
- globalThis.crypto.getRandomValues(bytes);
511
- } else {
512
- for (let i = 0; i < bytes.length; i++) bytes[i] = Math.floor(Math.random() * 256);
513
- }
514
- return Array.from(bytes, (b) => b.toString(16).padStart(2, "0")).join("");
515
- }
516
-
517
- // src/hooks/useRegisterDevice.ts
518
- function useRegisterDevice() {
519
- const { client, storage } = useFanapps();
520
- const [targetId, setTargetId] = (0, import_react4.useState)(null);
521
- const [token, setToken] = (0, import_react4.useState)(null);
522
- const [target, setTarget] = (0, import_react4.useState)(null);
523
- const [isRegistering, setIsRegistering] = (0, import_react4.useState)(false);
524
- const [error, setError] = (0, import_react4.useState)(null);
525
- const targetStoreRef = (0, import_react4.useRef)(null);
526
- if (!targetStoreRef.current) {
527
- targetStoreRef.current = new TargetIdStore(storage);
528
- }
529
- const targetStore = targetStoreRef.current;
530
- const tokenRefreshUnsubRef = (0, import_react4.useRef)(null);
531
- (0, import_react4.useEffect)(() => {
532
- return () => {
533
- tokenRefreshUnsubRef.current?.();
534
- tokenRefreshUnsubRef.current = null;
535
- };
536
- }, []);
537
- const register = (0, import_react4.useCallback)(async () => {
538
- setIsRegistering(true);
539
- setError(null);
540
- try {
541
- const messaging = firebaseMessaging();
542
- await messaging.requestPermission();
543
- const fcmToken = await messaging.getToken();
544
- setToken(fcmToken);
545
- const existingId = await targetStore.get();
546
- let result;
547
- if (existingId) {
548
- try {
549
- result = await client.updatePushTarget(existingId, fcmToken);
550
- } catch {
551
- result = await client.createPushTarget({
552
- targetId: existingId,
553
- identifier: fcmToken,
554
- osName: import_react_native2.Platform.OS === "ios" ? "iOS" : "Android"
555
- });
556
- }
557
- } else {
558
- const newId = generateTargetId();
559
- result = await client.createPushTarget({
560
- targetId: newId,
561
- identifier: fcmToken,
562
- osName: import_react_native2.Platform.OS === "ios" ? "iOS" : "Android"
563
- });
564
- await targetStore.set(result.id);
565
- }
566
- setTargetId(result.id);
567
- setTarget(result);
568
- if (!tokenRefreshUnsubRef.current) {
569
- tokenRefreshUnsubRef.current = messaging.onTokenRefresh(async (newToken) => {
570
- try {
571
- const id = await targetStore.get();
572
- if (!id) return;
573
- const updated = await client.updatePushTarget(id, newToken);
574
- setToken(newToken);
575
- setTarget(updated);
576
- } catch (e) {
577
- setError(e instanceof Error ? e : new Error(String(e)));
578
- }
579
- });
580
- }
581
- return result;
582
- } catch (e) {
583
- const err = e instanceof Error ? e : new Error(String(e));
584
- setError(err);
585
- throw err;
586
- } finally {
587
- setIsRegistering(false);
588
- }
589
- }, [client, targetStore]);
590
- const unregister = (0, import_react4.useCallback)(async () => {
591
- const id = await targetStore.get();
592
- if (id) {
593
- try {
594
- await client.deletePushTarget(id);
595
- } catch {
596
- }
597
- await targetStore.clear();
598
- }
599
- tokenRefreshUnsubRef.current?.();
600
- tokenRefreshUnsubRef.current = null;
601
- setTargetId(null);
602
- setToken(null);
603
- setTarget(null);
604
- }, [client, targetStore]);
605
- return {
606
- targetId,
607
- token,
608
- target,
609
- isRegistering,
610
- error,
611
- register,
612
- unregister
613
- };
614
- }
615
-
616
415
  // src/hooks/useTrivias.ts
617
416
  var import_react_query6 = require("@tanstack/react-query");
618
417
  function useTrivias(options = {}) {
@@ -668,18 +467,6 @@ function useSubmitTriviaResponse() {
668
467
  }
669
468
  });
670
469
  }
671
-
672
- // src/hooks/useTopicSubscription.ts
673
- var import_react5 = require("react");
674
- function useTopicSubscription() {
675
- const subscribe = (0, import_react5.useCallback)(async (topic) => {
676
- await firebaseMessaging().subscribeToTopic(topic);
677
- }, []);
678
- const unsubscribe = (0, import_react5.useCallback)(async (topic) => {
679
- await firebaseMessaging().unsubscribeFromTopic(topic);
680
- }, []);
681
- return { subscribe, unsubscribe };
682
- }
683
470
  // Annotate the CommonJS export names for ESM import in node:
684
471
  0 && (module.exports = {
685
472
  FanappsAuthError,
@@ -692,9 +479,7 @@ function useTopicSubscription() {
692
479
  useEntries,
693
480
  useEntry,
694
481
  useFanappsClient,
695
- useRegisterDevice,
696
482
  useSubmitTriviaResponse,
697
- useTopicSubscription,
698
483
  useTrivia,
699
484
  useTrivias
700
485
  });