shelflife-react-hooks 1.0.19 → 1.0.20

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 (44) hide show
  1. package/dist/index.cjs.js +22 -0
  2. package/dist/index.cjs.js.map +1 -1
  3. package/dist/index.d.cts +2 -0
  4. package/dist/index.d.ts +2 -0
  5. package/dist/index.esm.js +22 -0
  6. package/dist/index.esm.js.map +1 -1
  7. package/package.json +36 -36
  8. package/src/context/AuthContext.tsx +161 -161
  9. package/src/context/InviteContext.tsx +74 -74
  10. package/src/context/ProductContext.tsx +131 -121
  11. package/src/context/RunningLowContext.tsx +100 -100
  12. package/src/context/ShoppingListContext.tsx +76 -76
  13. package/src/context/StorageContext.tsx +105 -105
  14. package/src/context/StorageItemContext.tsx +157 -157
  15. package/src/context/StorageMemberContext.tsx +84 -84
  16. package/src/context/UserContext.tsx +109 -109
  17. package/src/context/__tests__/contexts.test.tsx +370 -370
  18. package/src/context/api/authApi.ts +155 -155
  19. package/src/context/api/inviteApi.ts +65 -65
  20. package/src/context/api/productApi.ts +223 -201
  21. package/src/context/api/requestState.ts +24 -24
  22. package/src/context/api/runningLowApi.ts +141 -141
  23. package/src/context/api/shoppingListApi.ts +161 -161
  24. package/src/context/api/storageApi.ts +166 -166
  25. package/src/context/api/storageItemApi.ts +260 -260
  26. package/src/context/api/storageMemberApi.ts +84 -84
  27. package/src/context/api/userApi.ts +161 -161
  28. package/src/context/http.ts +22 -22
  29. package/src/index.ts +21 -21
  30. package/src/type/PaginatedResponse.ts +8 -8
  31. package/src/type/auth.ts +79 -79
  32. package/src/type/base.ts +21 -21
  33. package/src/type/item.ts +12 -12
  34. package/src/type/member.ts +6 -6
  35. package/src/type/models.ts +56 -56
  36. package/src/type/product.ts +11 -11
  37. package/src/type/requests.ts +60 -60
  38. package/src/type/runninglow.ts +13 -13
  39. package/src/type/shoppingList.ts +13 -13
  40. package/src/type/storage.ts +7 -7
  41. package/src/type/user.ts +11 -11
  42. package/tsconfig.json +46 -46
  43. package/tsup.config.ts +10 -10
  44. package/vitest.config.ts +8 -8
package/package.json CHANGED
@@ -1,36 +1,36 @@
1
- {
2
- "name": "shelflife-react-hooks",
3
- "version": "1.0.19",
4
- "description": "",
5
- "license": "ISC",
6
- "author": "Preisler25",
7
- "type": "module",
8
- "main": "dist/index.cjs.js",
9
- "module": "dist/index.esm.js",
10
- "types": "dist/index.d.ts",
11
- "scripts": {
12
- "build": "tsup",
13
- "test": "vitest run"
14
- },
15
- "exports": {
16
- ".": {
17
- "types": "./dist/index.d.ts",
18
- "import": "./dist/index.esm.js",
19
- "require": "./dist/index.cjs.js"
20
- }
21
- },
22
- "devDependencies": {
23
- "@testing-library/dom": "^10.4.1",
24
- "@testing-library/react": "^16.3.2",
25
- "@types/node": "^25.2.3",
26
- "@types/react": "^19.0.0",
27
- "jsdom": "^28.1.0",
28
- "ts-node": "^10.9.2",
29
- "tsup": "^8.5.1",
30
- "typescript": "^5.9.3",
31
- "vitest": "^2.1.9"
32
- },
33
- "peerDependencies": {
34
- "react": "^19.0.0"
35
- }
36
- }
1
+ {
2
+ "name": "shelflife-react-hooks",
3
+ "version": "1.0.20",
4
+ "description": "",
5
+ "license": "ISC",
6
+ "author": "Preisler25",
7
+ "type": "module",
8
+ "main": "dist/index.cjs.js",
9
+ "module": "dist/index.esm.js",
10
+ "types": "dist/index.d.ts",
11
+ "scripts": {
12
+ "build": "tsup",
13
+ "test": "vitest run"
14
+ },
15
+ "exports": {
16
+ ".": {
17
+ "types": "./dist/index.d.ts",
18
+ "import": "./dist/index.esm.js",
19
+ "require": "./dist/index.cjs.js"
20
+ }
21
+ },
22
+ "devDependencies": {
23
+ "@testing-library/dom": "^10.4.1",
24
+ "@testing-library/react": "^16.3.2",
25
+ "@types/node": "^25.2.3",
26
+ "@types/react": "^19.0.0",
27
+ "jsdom": "^28.1.0",
28
+ "ts-node": "^10.9.2",
29
+ "tsup": "^8.5.1",
30
+ "typescript": "^5.9.3",
31
+ "vitest": "^2.1.9"
32
+ },
33
+ "peerDependencies": {
34
+ "react": "^19.0.0"
35
+ }
36
+ }
@@ -1,161 +1,161 @@
1
- import React, {
2
- createContext,
3
- useCallback,
4
- useContext,
5
- useEffect,
6
- useMemo,
7
- useState
8
- } from 'react';
9
-
10
- import type {
11
- ChangePasswordRequest,
12
- LoginRequest,
13
- SignupRequest,
14
- TokenStorage,
15
- User
16
- } from '../type/auth.js';
17
- import {
18
- changePasswordRequest,
19
- getMeRequest,
20
- loginRequest,
21
- logoutRequest,
22
- signupRequest
23
- } from './api/authApi.js';
24
- import type { ChangeUserDataRequest } from '../type/requests.js';
25
- import { updateUserRequest } from './api/userApi.js';
26
-
27
- export type AuthContextValue = {
28
- token: string | null;
29
- user: User | null;
30
- isLoading: boolean;
31
- isError: boolean;
32
- error: Error | null;
33
- login: (dto: LoginRequest) => Promise<void>;
34
- signup: (dto: SignupRequest) => Promise<User>;
35
- changeMe: (dto: ChangeUserDataRequest) => Promise<User>;
36
- changePassword: (dto: ChangePasswordRequest) => Promise<void>;
37
- getMe: () => Promise<User | null>;
38
- logout: () => Promise<void>;
39
- getToken: () => string | null;
40
- };
41
-
42
- type AuthProviderProps = {
43
- baseUrl: string;
44
- children: React.ReactNode;
45
- initialToken?: string | null;
46
- tokenStorage?: TokenStorage;
47
- storageKey?: string;
48
- };
49
-
50
- const AuthContext = createContext<AuthContextValue | undefined>(undefined);
51
-
52
- export const AuthProvider = ({
53
- baseUrl,
54
- children,
55
- initialToken = null,
56
- tokenStorage,
57
- storageKey = 'auth_token'
58
- }: AuthProviderProps) => {
59
- const [token, setTokenState] = useState<string | null>(initialToken);
60
- const [user, setUser] = useState<User | null>(null);
61
- const [isLoading, setIsLoading] = useState(true);
62
- const [isError, setIsError] = useState(false);
63
- const [error, setError] = useState<Error | null>(null);
64
-
65
- // Load token from storage on mount
66
- useEffect(() => {
67
- if (tokenStorage && !initialToken) {
68
- const loadToken = async () => {
69
- try {
70
- const storedToken = await tokenStorage.getItem(storageKey);
71
- if (storedToken) {
72
- setTokenState(storedToken);
73
- }
74
- } catch (err) {
75
- console.error('Failed to load token from storage:', err);
76
- }
77
- };
78
- loadToken();
79
- }
80
- }, [tokenStorage, storageKey, initialToken]);
81
-
82
- // Wrap setToken to persist to storage
83
- const setToken = useCallback(async (newToken: string | null) => {
84
- setTokenState(newToken);
85
- if (tokenStorage) {
86
- try {
87
- if (newToken) {
88
- await tokenStorage.setItem(storageKey, newToken);
89
- } else {
90
- await tokenStorage.removeItem(storageKey);
91
- }
92
- } catch (err) {
93
- console.error('Failed to persist token to storage:', err);
94
- }
95
- }
96
- }, [tokenStorage, storageKey]);
97
-
98
- const getToken = useCallback(() => token, [token]);
99
-
100
- const apiConfig = useMemo(() => ({
101
- baseUrl,
102
- token,
103
- setToken,
104
- setUser,
105
- setIsLoading,
106
- setIsError,
107
- setError
108
- }), [baseUrl, token]);
109
-
110
- const login = useCallback((dto: LoginRequest) => loginRequest(apiConfig, dto), [apiConfig]);
111
- const signup = useCallback((dto: SignupRequest) => signupRequest(apiConfig, dto), [apiConfig]);
112
- const changeMe = useCallback(
113
- (dto: ChangeUserDataRequest) => updateUserRequest({ ...apiConfig, setUsers: () => { }, setUser }, user!.id, dto),
114
- [apiConfig, user]
115
- )
116
- const changePassword = useCallback(
117
- (dto: ChangePasswordRequest) => changePasswordRequest(apiConfig, dto),
118
- [apiConfig]
119
- );
120
- const getMe = useCallback(() => getMeRequest(apiConfig), [apiConfig]);
121
- const logout = useCallback(() => logoutRequest(apiConfig), [apiConfig]);
122
-
123
- const value = useMemo<AuthContextValue>(() => ({
124
- token,
125
- user,
126
- isLoading,
127
- isError,
128
- error,
129
- login,
130
- signup,
131
- changeMe,
132
- changePassword,
133
- getMe,
134
- logout,
135
- getToken
136
- }), [
137
- changeMe,
138
- changePassword,
139
- error,
140
- getMe,
141
- getToken,
142
- isError,
143
- isLoading,
144
- login,
145
- logout,
146
- signup,
147
- token,
148
- user
149
- ]);
150
-
151
- return <AuthContext.Provider value={value}>{children}</AuthContext.Provider>;
152
- };
153
-
154
- export const useAuth = (): AuthContextValue => {
155
- const context = useContext(AuthContext);
156
- if (!context) {
157
- throw new Error('useAuth must be used within an AuthProvider');
158
- }
159
-
160
- return context;
161
- };
1
+ import React, {
2
+ createContext,
3
+ useCallback,
4
+ useContext,
5
+ useEffect,
6
+ useMemo,
7
+ useState
8
+ } from 'react';
9
+
10
+ import type {
11
+ ChangePasswordRequest,
12
+ LoginRequest,
13
+ SignupRequest,
14
+ TokenStorage,
15
+ User
16
+ } from '../type/auth.js';
17
+ import {
18
+ changePasswordRequest,
19
+ getMeRequest,
20
+ loginRequest,
21
+ logoutRequest,
22
+ signupRequest
23
+ } from './api/authApi.js';
24
+ import type { ChangeUserDataRequest } from '../type/requests.js';
25
+ import { updateUserRequest } from './api/userApi.js';
26
+
27
+ export type AuthContextValue = {
28
+ token: string | null;
29
+ user: User | null;
30
+ isLoading: boolean;
31
+ isError: boolean;
32
+ error: Error | null;
33
+ login: (dto: LoginRequest) => Promise<void>;
34
+ signup: (dto: SignupRequest) => Promise<User>;
35
+ changeMe: (dto: ChangeUserDataRequest) => Promise<User>;
36
+ changePassword: (dto: ChangePasswordRequest) => Promise<void>;
37
+ getMe: () => Promise<User | null>;
38
+ logout: () => Promise<void>;
39
+ getToken: () => string | null;
40
+ };
41
+
42
+ type AuthProviderProps = {
43
+ baseUrl: string;
44
+ children: React.ReactNode;
45
+ initialToken?: string | null;
46
+ tokenStorage?: TokenStorage;
47
+ storageKey?: string;
48
+ };
49
+
50
+ const AuthContext = createContext<AuthContextValue | undefined>(undefined);
51
+
52
+ export const AuthProvider = ({
53
+ baseUrl,
54
+ children,
55
+ initialToken = null,
56
+ tokenStorage,
57
+ storageKey = 'auth_token'
58
+ }: AuthProviderProps) => {
59
+ const [token, setTokenState] = useState<string | null>(initialToken);
60
+ const [user, setUser] = useState<User | null>(null);
61
+ const [isLoading, setIsLoading] = useState(true);
62
+ const [isError, setIsError] = useState(false);
63
+ const [error, setError] = useState<Error | null>(null);
64
+
65
+ // Load token from storage on mount
66
+ useEffect(() => {
67
+ if (tokenStorage && !initialToken) {
68
+ const loadToken = async () => {
69
+ try {
70
+ const storedToken = await tokenStorage.getItem(storageKey);
71
+ if (storedToken) {
72
+ setTokenState(storedToken);
73
+ }
74
+ } catch (err) {
75
+ console.error('Failed to load token from storage:', err);
76
+ }
77
+ };
78
+ loadToken();
79
+ }
80
+ }, [tokenStorage, storageKey, initialToken]);
81
+
82
+ // Wrap setToken to persist to storage
83
+ const setToken = useCallback(async (newToken: string | null) => {
84
+ setTokenState(newToken);
85
+ if (tokenStorage) {
86
+ try {
87
+ if (newToken) {
88
+ await tokenStorage.setItem(storageKey, newToken);
89
+ } else {
90
+ await tokenStorage.removeItem(storageKey);
91
+ }
92
+ } catch (err) {
93
+ console.error('Failed to persist token to storage:', err);
94
+ }
95
+ }
96
+ }, [tokenStorage, storageKey]);
97
+
98
+ const getToken = useCallback(() => token, [token]);
99
+
100
+ const apiConfig = useMemo(() => ({
101
+ baseUrl,
102
+ token,
103
+ setToken,
104
+ setUser,
105
+ setIsLoading,
106
+ setIsError,
107
+ setError
108
+ }), [baseUrl, token]);
109
+
110
+ const login = useCallback((dto: LoginRequest) => loginRequest(apiConfig, dto), [apiConfig]);
111
+ const signup = useCallback((dto: SignupRequest) => signupRequest(apiConfig, dto), [apiConfig]);
112
+ const changeMe = useCallback(
113
+ (dto: ChangeUserDataRequest) => updateUserRequest({ ...apiConfig, setUsers: () => { }, setUser }, user!.id, dto),
114
+ [apiConfig, user]
115
+ )
116
+ const changePassword = useCallback(
117
+ (dto: ChangePasswordRequest) => changePasswordRequest(apiConfig, dto),
118
+ [apiConfig]
119
+ );
120
+ const getMe = useCallback(() => getMeRequest(apiConfig), [apiConfig]);
121
+ const logout = useCallback(() => logoutRequest(apiConfig), [apiConfig]);
122
+
123
+ const value = useMemo<AuthContextValue>(() => ({
124
+ token,
125
+ user,
126
+ isLoading,
127
+ isError,
128
+ error,
129
+ login,
130
+ signup,
131
+ changeMe,
132
+ changePassword,
133
+ getMe,
134
+ logout,
135
+ getToken
136
+ }), [
137
+ changeMe,
138
+ changePassword,
139
+ error,
140
+ getMe,
141
+ getToken,
142
+ isError,
143
+ isLoading,
144
+ login,
145
+ logout,
146
+ signup,
147
+ token,
148
+ user
149
+ ]);
150
+
151
+ return <AuthContext.Provider value={value}>{children}</AuthContext.Provider>;
152
+ };
153
+
154
+ export const useAuth = (): AuthContextValue => {
155
+ const context = useContext(AuthContext);
156
+ if (!context) {
157
+ throw new Error('useAuth must be used within an AuthProvider');
158
+ }
159
+
160
+ return context;
161
+ };
@@ -1,74 +1,74 @@
1
- import React, {
2
- createContext,
3
- useCallback,
4
- useContext,
5
- useMemo,
6
- useState
7
- } from 'react';
8
-
9
- import type { StorageMember } from '../type/models.js';
10
- import { useAuth } from './AuthContext.js';
11
- import {
12
- acceptInviteRequest,
13
- declineInviteRequest,
14
- fetchInvitesRequest
15
- } from './api/inviteApi.js';
16
-
17
- type InviteContextValue = {
18
- invites: StorageMember[];
19
- isLoading: boolean;
20
- isError: boolean;
21
- error: Error | null;
22
- fetchInvites: () => Promise<StorageMember[]>;
23
- acceptInvite: (id: number) => Promise<void>;
24
- declineInvite: (id: number) => Promise<void>;
25
- };
26
-
27
- type InviteProviderProps = {
28
- baseUrl: string;
29
- children: React.ReactNode;
30
- };
31
-
32
- const InviteContext = createContext<InviteContextValue | undefined>(undefined);
33
-
34
- export const InviteProvider = ({ baseUrl, children }: InviteProviderProps) => {
35
- const { token } = useAuth();
36
- const [invites, setInvites] = useState<StorageMember[]>([]);
37
- const [isLoading, setIsLoading] = useState(false);
38
- const [isError, setIsError] = useState(false);
39
- const [error, setError] = useState<Error | null>(null);
40
-
41
- const apiConfig = useMemo(() => ({
42
- baseUrl,
43
- token,
44
- setInvites,
45
- setIsLoading,
46
- setIsError,
47
- setError
48
- }), [baseUrl, token]);
49
-
50
- const fetchInvites = useCallback(() => fetchInvitesRequest(apiConfig), [apiConfig]);
51
- const acceptInvite = useCallback((id: number) => acceptInviteRequest(apiConfig, id), [apiConfig]);
52
- const declineInvite = useCallback((id: number) => declineInviteRequest(apiConfig, id), [apiConfig]);
53
-
54
- const value = useMemo<InviteContextValue>(() => ({
55
- invites,
56
- isLoading,
57
- isError,
58
- error,
59
- fetchInvites,
60
- acceptInvite,
61
- declineInvite
62
- }), [acceptInvite, declineInvite, error, fetchInvites, isError, isLoading, invites]);
63
-
64
- return <InviteContext.Provider value={value}>{children}</InviteContext.Provider>;
65
- };
66
-
67
- export const useInvites = (): InviteContextValue => {
68
- const context = useContext(InviteContext);
69
- if (!context) {
70
- throw new Error('useInvites must be used within an InviteProvider');
71
- }
72
-
73
- return context;
74
- };
1
+ import React, {
2
+ createContext,
3
+ useCallback,
4
+ useContext,
5
+ useMemo,
6
+ useState
7
+ } from 'react';
8
+
9
+ import type { StorageMember } from '../type/models.js';
10
+ import { useAuth } from './AuthContext.js';
11
+ import {
12
+ acceptInviteRequest,
13
+ declineInviteRequest,
14
+ fetchInvitesRequest
15
+ } from './api/inviteApi.js';
16
+
17
+ type InviteContextValue = {
18
+ invites: StorageMember[];
19
+ isLoading: boolean;
20
+ isError: boolean;
21
+ error: Error | null;
22
+ fetchInvites: () => Promise<StorageMember[]>;
23
+ acceptInvite: (id: number) => Promise<void>;
24
+ declineInvite: (id: number) => Promise<void>;
25
+ };
26
+
27
+ type InviteProviderProps = {
28
+ baseUrl: string;
29
+ children: React.ReactNode;
30
+ };
31
+
32
+ const InviteContext = createContext<InviteContextValue | undefined>(undefined);
33
+
34
+ export const InviteProvider = ({ baseUrl, children }: InviteProviderProps) => {
35
+ const { token } = useAuth();
36
+ const [invites, setInvites] = useState<StorageMember[]>([]);
37
+ const [isLoading, setIsLoading] = useState(false);
38
+ const [isError, setIsError] = useState(false);
39
+ const [error, setError] = useState<Error | null>(null);
40
+
41
+ const apiConfig = useMemo(() => ({
42
+ baseUrl,
43
+ token,
44
+ setInvites,
45
+ setIsLoading,
46
+ setIsError,
47
+ setError
48
+ }), [baseUrl, token]);
49
+
50
+ const fetchInvites = useCallback(() => fetchInvitesRequest(apiConfig), [apiConfig]);
51
+ const acceptInvite = useCallback((id: number) => acceptInviteRequest(apiConfig, id), [apiConfig]);
52
+ const declineInvite = useCallback((id: number) => declineInviteRequest(apiConfig, id), [apiConfig]);
53
+
54
+ const value = useMemo<InviteContextValue>(() => ({
55
+ invites,
56
+ isLoading,
57
+ isError,
58
+ error,
59
+ fetchInvites,
60
+ acceptInvite,
61
+ declineInvite
62
+ }), [acceptInvite, declineInvite, error, fetchInvites, isError, isLoading, invites]);
63
+
64
+ return <InviteContext.Provider value={value}>{children}</InviteContext.Provider>;
65
+ };
66
+
67
+ export const useInvites = (): InviteContextValue => {
68
+ const context = useContext(InviteContext);
69
+ if (!context) {
70
+ throw new Error('useInvites must be used within an InviteProvider');
71
+ }
72
+
73
+ return context;
74
+ };