pocketbase-react 0.1.7 → 0.1.9

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.
Files changed (40) hide show
  1. package/dist/pocketbase-react.js +113 -35
  2. package/dist/pocketbase-react.min.js +4 -4
  3. package/es/context/Pocketbase.d.ts +3 -5
  4. package/es/context/Pocketbase.js +8 -10
  5. package/es/context/auth.d.ts +38 -0
  6. package/es/context/auth.js +67 -0
  7. package/es/context/client.d.ts +1 -1
  8. package/es/context/content.js +9 -8
  9. package/es/context/index.d.ts +1 -0
  10. package/es/context/index.js +1 -0
  11. package/es/hooks/index.d.ts +1 -0
  12. package/es/hooks/index.js +2 -1
  13. package/es/hooks/useAuth.d.ts +4 -0
  14. package/es/hooks/useAuth.js +8 -0
  15. package/es/hooks/useClientContext.d.ts +1 -1
  16. package/es/service/Authentication.d.ts +23 -0
  17. package/es/service/Authentication.js +32 -0
  18. package/es/service/Storage.d.ts +5 -0
  19. package/es/service/Storage.js +20 -0
  20. package/es/store/store.js +7 -19
  21. package/lib/context/Pocketbase.js +7 -9
  22. package/lib/context/auth.js +74 -0
  23. package/lib/context/content.js +9 -8
  24. package/lib/context/index.js +11 -0
  25. package/lib/hooks/index.js +11 -0
  26. package/lib/hooks/useAuth.js +12 -0
  27. package/lib/service/Authentication.js +37 -0
  28. package/lib/service/Storage.js +26 -0
  29. package/lib/store/store.js +7 -19
  30. package/package.json +3 -3
  31. package/src/context/Pocketbase.tsx +10 -15
  32. package/src/context/auth.tsx +113 -0
  33. package/src/context/client.tsx +1 -1
  34. package/src/context/content.tsx +7 -8
  35. package/src/context/index.ts +2 -1
  36. package/src/hooks/index.ts +2 -1
  37. package/src/hooks/useAuth.ts +7 -0
  38. package/src/service/Authentication.ts +50 -0
  39. package/src/service/Storage.ts +23 -0
  40. package/src/store/store.tsx +7 -21
@@ -1,40 +1,35 @@
1
1
  import * as React from 'react';
2
2
  import { createContext, useEffect } from 'react';
3
- import PocketBase from 'pocketbase';
3
+ import PocketBase from '@tobicrain/pocketbase';
4
4
  import { Provider } from 'react-redux';
5
5
  import { PersistGate } from 'redux-persist/integration/react';
6
6
  import * as store from '../store/store';
7
7
  import { ClientProvider } from './client';
8
8
  import { ContentProvider } from './content';
9
+ import { AuthProvider } from './auth';
9
10
 
10
11
  export const PocketbaseContext = createContext<PocketBase | null>(null);
11
12
 
12
13
  export type PocketbaseProviderProps = {
13
14
  children: React.ReactNode;
14
15
  serverURL: string;
15
- credentials: {
16
- username: string;
17
- password: string;
18
- };
16
+ redirectURL: string;
17
+ openURL: (url: string) => Promise<void>;
19
18
  initialCollections?: string[];
20
19
  };
21
20
 
22
21
  export const Pocketbase = (props: PocketbaseProviderProps) => {
23
- const [client, setClient] = React.useState<PocketBase | null>(null);
24
- useEffect(() => {
25
- const client = new PocketBase(props.serverURL);
26
- client.admins.authViaEmail(props.credentials.username, props.credentials.password).then(() => {
27
- setClient(client);
28
- });
29
- }, [props.serverURL]);
22
+ const client = new PocketBase(props.serverURL);
30
23
 
31
24
  return client ? (
32
25
  <ClientProvider client={client}>
33
26
  <Provider store={store.store}>
34
27
  <PersistGate persistor={store.persistor}>
35
- <ContentProvider collections={props.initialCollections}>
36
- {props.children}
37
- </ContentProvider>
28
+ <AuthProvider redirectUrl={props.redirectURL} openURL={props.openURL} >
29
+ <ContentProvider collections={props.initialCollections}>
30
+ {props.children}
31
+ </ContentProvider>
32
+ </AuthProvider>
38
33
  </PersistGate>
39
34
  </Provider>
40
35
  </ClientProvider>
@@ -0,0 +1,113 @@
1
+ import AsyncStorage from '@react-native-async-storage/async-storage';
2
+ import * as React from 'react';
3
+ import { createContext, useEffect } from 'react';
4
+ import { useClientContext } from '../hooks/useClientContext';
5
+ import { StorageService } from '../service/Storage';
6
+
7
+ export type AuthProviderInfo = {
8
+ name: string;
9
+ state: string;
10
+ codeVerifier: string;
11
+ codeChallenge: string;
12
+ codeChallengeMethod: string;
13
+ authUrl: string;
14
+ };
15
+
16
+ export type RegisterWithEmailType = (email: string, password: string) => Promise<void>;
17
+ export type SignInWithEmailType = (email: string, password: string) => Promise<void>;
18
+ export type SignInWithProviderType = (provider: string) => Promise<void>;
19
+ export type SubmitProviderResultType = (url: string) => Promise<void>;
20
+ export type SignOutType = () => void;
21
+ export type SendPasswordResetEmailType = (email: string) => Promise<void>;
22
+ export type SendEmailVerificationType = (email: string) => Promise<void>;
23
+ export type UpdateProfileType = (id: string, record: {}) => Promise<void>;
24
+ export type UpdateEmailType = (email: string) => Promise<void>;
25
+ export type DeleteUserType = (id: string) => Promise<void>;
26
+
27
+ export interface AuthActions {
28
+ registerWithEmail: RegisterWithEmailType
29
+ signInWithEmail: SignInWithEmailType;
30
+ signInWithProvider: SignInWithProviderType;
31
+ submitProviderResult: SubmitProviderResultType;
32
+ signOut: SignOutType;
33
+ sendPasswordResetEmail: SendPasswordResetEmailType;
34
+ sendEmailVerification: SendEmailVerificationType;
35
+ updateProfile: UpdateProfileType;
36
+ updateEmail: UpdateEmailType;
37
+ deleteUser: DeleteUserType;
38
+ }
39
+
40
+ export const AuthContext = createContext<AuthActions | null>(null);
41
+
42
+ export type AuthProviderProps = {
43
+ children: React.ReactNode;
44
+ redirectUrl: string;
45
+ openURL: (url: string) => Promise<void>;
46
+ };
47
+
48
+
49
+ export const AuthProvider = (props: AuthProviderProps) => {
50
+ const client = useClientContext();
51
+ const [authProviders, setAuthProviders] = React.useState<AuthProviderInfo[]>();
52
+
53
+ const actions: AuthActions = {
54
+ registerWithEmail: async (email, password) => {
55
+ await client?.users.create({
56
+ email: email,
57
+ password: password,
58
+ passwordConfirm: password,
59
+ });
60
+ },
61
+ signInWithEmail: async (email: string, password: string) => {
62
+ await client?.users.authViaEmail(email, password);
63
+ },
64
+ signInWithProvider: async (provider: string) => {
65
+ const authProvider = authProviders?.find((p) => p.name === provider);
66
+ const url = authProvider?.authUrl + props.redirectUrl;
67
+ await props.openURL(url);
68
+ await StorageService.set('provider', JSON.stringify(authProviders));
69
+ },
70
+ submitProviderResult: async (url: string) => {
71
+ const params = new URLSearchParams(url.split('?')[1]);
72
+ const code = params.get('code');
73
+ const state = params.get('state');
74
+ const providersString = await StorageService.get('provider');
75
+ if (providersString) {
76
+ const providers = JSON.parse(providersString) as AuthProviderInfo[];
77
+ const authProvider = providers?.find((p) => p.state === state);
78
+ if (authProvider && code) {
79
+ await client?.users.authViaOAuth2(authProvider.name, code, authProvider.codeVerifier, props.redirectUrl);
80
+ }
81
+ }
82
+ },
83
+ signOut: () => {
84
+ client?.authStore.clear();
85
+ },
86
+ sendPasswordResetEmail: async (email: string) => {
87
+ await client?.users.requestPasswordReset(email);
88
+ },
89
+ sendEmailVerification: async (email: string) => {
90
+ await client?.users.requestVerification(email);
91
+ },
92
+ updateProfile: async (id: string, record: {}) => {
93
+ await client?.records.update('profiles', id, record);
94
+ },
95
+ updateEmail: async (email: string) => {
96
+ await client?.users.requestEmailChange(email);
97
+ },
98
+ deleteUser: async (id: string) => {
99
+ await client?.users.delete(id)
100
+ }
101
+ };
102
+
103
+ React.useEffect(() => {
104
+ (async () => {
105
+ const methods = await client?.users.listAuthMethods();
106
+ setAuthProviders(methods?.authProviders);
107
+ })();
108
+ }, [props.redirectUrl]);
109
+
110
+ return (
111
+ <AuthContext.Provider value={actions}>{props.children}</AuthContext.Provider>
112
+ );
113
+ };
@@ -1,6 +1,6 @@
1
1
  import * as React from 'react';
2
2
  import { createContext } from 'react';
3
- import PocketBase from 'pocketbase';
3
+ import PocketBase from '@tobicrain/pocketbase';
4
4
 
5
5
  export const ClientContext = createContext<PocketBase | null>(null);
6
6
 
@@ -40,7 +40,6 @@ export const ContentProvider = (props: ContentProviderProps) => {
40
40
 
41
41
  const actions: ContentActions = {
42
42
  subscribe: async (collectionName: string) => {
43
- // save local that collectionName should be subscribed
44
43
  await client?.realtime.subscribe(collectionName, (event: MessageData) => {
45
44
  switch (event.action) {
46
45
  case 'create':
@@ -55,27 +54,27 @@ export const ContentProvider = (props: ContentProviderProps) => {
55
54
  default:
56
55
  break;
57
56
  }
58
- });
57
+ }).catch((_error) => {});
59
58
  },
60
59
  unsubscribe: (collectionName?: string) => {
61
60
  if (collectionName) {
62
- client?.realtime.unsubscribe(collectionName);
61
+ client?.realtime.unsubscribe(collectionName).catch((_error) => {});;
63
62
  } else {
64
- client?.realtime.unsubscribe();
63
+ client?.realtime.unsubscribe().catch((_error) => {});;
65
64
  }
66
65
  },
67
66
  fetch: async (collectionName: string) => {
68
- const records = await client?.records.getFullList(collectionName, 200);
67
+ const records = await client?.records.getFullList(collectionName, 200).catch((_error) => {});
69
68
  dispatch(recordsAction.setRecords(collectionName, records as Record[]));
70
69
  },
71
70
  create: async (collectionName: string, record: {}) => {
72
- await client?.records.create(collectionName, record);
71
+ await client?.records.create(collectionName, record).catch((_error) => {});
73
72
  },
74
73
  update: async (collectionName: string, recordId: string, record: {}) => {
75
- await client?.records.update(collectionName, recordId, record);
74
+ await client?.records.update(collectionName, recordId, record).catch((_error) => {});
76
75
  },
77
76
  delete: async (collectionName: string, recordId: string) => {
78
- await client?.records.delete(collectionName, recordId);
77
+ await client?.records.delete(collectionName, recordId).catch((_error) => {});
79
78
  },
80
79
  };
81
80
 
@@ -1,3 +1,4 @@
1
1
  export * from './content';
2
2
  export * from './client';
3
- export * from './Pocketbase';
3
+ export * from './auth';
4
+ export * from './Pocketbase';
@@ -1,2 +1,3 @@
1
1
  export * from './useAppContent';
2
- export * from './useClientContext';
2
+ export * from './useClientContext';
3
+ export * from './useAuth';
@@ -0,0 +1,7 @@
1
+ import { useContext } from 'react';
2
+ import { AuthActions, AuthContext } from '../context/auth';
3
+
4
+ export function useAuth(): { actions: AuthActions | null } {
5
+ const actions = useContext(AuthContext);
6
+ return { actions };
7
+ }
@@ -0,0 +1,50 @@
1
+ import PocketBase from "@tobicrain/pocketbase";
2
+
3
+ export class AuthenticationService {
4
+ private client: PocketBase;
5
+ public redirect_url: string;
6
+
7
+ constructor(client: PocketBase) {
8
+ this.client = client;
9
+ this.redirect_url = '';
10
+ }
11
+
12
+ async getListAuthMethods() {
13
+ return await this.client.users.listAuthMethods();
14
+ }
15
+
16
+ async getDataAuth() {
17
+ await this.client.users.authViaOAuth2(
18
+ 'google',
19
+ 'CODE',
20
+ 'VERIFIER',
21
+ 'REDIRECT_URL'
22
+ );
23
+ }
24
+ async AuthWithOauth(provider: string, code: string, verifier: string) {
25
+ await this.client.users.authViaOAuth2(
26
+ provider,
27
+ code,
28
+ verifier,
29
+ this.redirect_url
30
+ );
31
+ }
32
+
33
+ async AuthWithEmail(email: string, password: string){
34
+ await this.client.users.authViaEmail(email, password);
35
+ }
36
+
37
+ async RegisterWithEmail(email: string, password: string){
38
+ await this.client.users.create({
39
+ email: email,
40
+ password: password,
41
+ passwordConfirm: password,
42
+ });
43
+ }
44
+
45
+ async getUserData(id:string, token:string) {
46
+ const headers = new Headers()
47
+ headers.append("Authorization","user "+token)
48
+ return await this.client.users.getOne(id)
49
+ }
50
+ }
@@ -0,0 +1,23 @@
1
+ import AsyncStorage from "@react-native-async-storage/async-storage";
2
+
3
+ export class StorageService {
4
+ static async get(key: string): Promise<string | null> {
5
+ return typeof document !== 'undefined' ? localStorage.getItem(key) : await AsyncStorage.getItem(key);
6
+ }
7
+
8
+ static async set(key: string, value: string): Promise<void> {
9
+ if (typeof document !== 'undefined') {
10
+ return localStorage.setItem(key, value);
11
+ } else {
12
+ return await AsyncStorage.setItem(key, value);
13
+ }
14
+ }
15
+
16
+ static async remove(key: string): Promise<void> {
17
+ if (typeof document !== 'undefined') {
18
+ return localStorage.removeItem(key);
19
+ } else {
20
+ return await AsyncStorage.removeItem(key);
21
+ }
22
+ }
23
+ }
@@ -5,6 +5,7 @@ import { appReducer } from './reducers';
5
5
  import thunk from 'redux-thunk';
6
6
  import { RecordAction } from './reducers/records';
7
7
  import AsyncStorage from '@react-native-async-storage/async-storage';
8
+ import { StorageService } from '../service/Storage';
8
9
 
9
10
  interface Storage {
10
11
  getItem(key: string, ...args: Array<any>): any;
@@ -14,29 +15,14 @@ interface Storage {
14
15
 
15
16
 
16
17
  const CustomStorage: Storage = {
17
- getItem: async (_key: string, ..._args: Array<any>) => {
18
- if (typeof document !== 'undefined') {
19
- return localStorage.getItem(_key);
20
- }
21
- else if (typeof navigator !== 'undefined' && navigator.product === 'ReactNative') {
22
- return await AsyncStorage.getItem(_key);
23
- }
18
+ getItem: async (key: string, ..._args: Array<any>) => {
19
+ return await StorageService.get(key);
24
20
  },
25
- setItem: async (_key: string, _value: any, ..._args: Array<any>) => {
26
- if (typeof document !== 'undefined') {
27
- return localStorage.setItem(_key, _value);
28
- }
29
- else if (typeof navigator !== 'undefined' && navigator.product === 'ReactNative') {
30
- return await AsyncStorage.setItem(_key, _value);
31
- }
21
+ setItem: async (key: string, value: any, ..._args: Array<any>) => {
22
+ return StorageService.set(key, value);
32
23
  },
33
- removeItem: async (_key: string, ..._args: Array<any>) => {
34
- if (typeof document !== 'undefined') {
35
- return localStorage.removeItem(_key);
36
- }
37
- else if (typeof navigator !== 'undefined' && navigator.product === 'ReactNative') {
38
- return await AsyncStorage.removeItem(_key);
39
- }
24
+ removeItem: async (key: string, ..._args: Array<any>) => {
25
+ return StorageService.remove(key);
40
26
  },
41
27
  };
42
28