shelflife-react-hooks 1.0.18 → 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 +23 -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 +23 -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 -159
  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
@@ -1,166 +1,166 @@
1
- import type { Storage } from '../../type/models.js';
2
- import type { PaginatedResponse } from '../../type/PaginatedResponse.js';
3
- import type { ChangeStorageNameRequest, CreateStorageRequest } from '../../type/requests.js';
4
- import type { CreateStorageError } from '../../type/storage.js';
5
- import { buildAuthHeaders, normalizeBaseUrl, readJson } from '../http.js';
6
- import { runWithRequestState, type RequestStateHandlers } from './requestState.js';
7
-
8
- type StorageApiConfig = RequestStateHandlers & {
9
- baseUrl: string;
10
- token: string | null;
11
- setStorages: (value: Storage[] | ((items: Storage[]) => Storage[])) => void;
12
- setStorage: (value: Storage | null | ((prev: Storage | null) => Storage | null)) => void;
13
- };
14
-
15
- const updateById = (items: Storage[], updated: Storage): Storage[] => {
16
- const index = items.findIndex((item) => item.id === updated.id);
17
- if (index === -1) {
18
- return [updated, ...items];
19
- }
20
-
21
- const next = [...items];
22
- next[index] = updated;
23
- return next;
24
- };
25
-
26
- export const fetchStoragesRequest = async (
27
- config: StorageApiConfig,
28
- search: string,
29
- size: number,
30
- page: number
31
- ): Promise<PaginatedResponse<Storage>> => runWithRequestState(
32
- config,
33
- async () => {
34
- const normalizedBaseUrl = normalizeBaseUrl(config.baseUrl);
35
- let url = `${normalizedBaseUrl}/api/storages?search=${search}`;
36
- if (size > 0)
37
- url += `&page=${page}&size=${size}`;
38
-
39
- const response = await fetch(url, {
40
- headers: buildAuthHeaders(config.token)
41
- });
42
-
43
- if (!response.ok) {
44
- throw new Error('Failed to fetch storages');
45
- }
46
-
47
- const payload = await readJson<PaginatedResponse<Storage>>(response);
48
- if (payload) {
49
- config.setStorages(payload.data);
50
- return payload;
51
- }
52
-
53
- return { data: [], currentPage: 0, hasNext: false, hasPrevious: false, pageSize: 0, totalItems: 0, totalPages: 0 };
54
- }
55
- );
56
-
57
- export const fetchStorageRequest = async (
58
- config: StorageApiConfig,
59
- id: number
60
- ): Promise<Storage | null> => runWithRequestState(config, async () => {
61
- const normalizedBaseUrl = normalizeBaseUrl(config.baseUrl);
62
- const response = await fetch(`${normalizedBaseUrl}/api/storages/${id}`, {
63
- headers: buildAuthHeaders(config.token)
64
- });
65
-
66
- if (response.status === 404) {
67
- config.setStorage(null);
68
- return null;
69
- }
70
-
71
- if (!response.ok) {
72
- throw new Error('Failed to fetch storage');
73
- }
74
-
75
- const payload = await readJson<Storage>(response);
76
- if (!payload) {
77
- throw new Error('Storage response missing data');
78
- }
79
-
80
- config.setStorage(payload);
81
- config.setStorages((previous) => updateById(previous, payload));
82
- return payload;
83
- });
84
-
85
- export const createStorageRequest = async (
86
- config: StorageApiConfig,
87
- dto: CreateStorageRequest
88
- ): Promise<Storage> => runWithRequestState(config, async () => {
89
- const normalizedBaseUrl = normalizeBaseUrl(config.baseUrl);
90
- const response = await fetch(`${normalizedBaseUrl}/api/storages`, {
91
- method: 'POST',
92
- headers: {
93
- ...buildAuthHeaders(config.token),
94
- 'Content-Type': 'application/json'
95
- },
96
- body: JSON.stringify(dto)
97
- });
98
-
99
- if (!response.ok) {
100
- const payload = await readJson<CreateStorageError>(response);
101
- if (payload?.name)
102
- throw payload;
103
-
104
- throw new Error('Failed to create storage');
105
- }
106
-
107
- const payload = await readJson<Storage>(response);
108
- if (!payload) {
109
- throw new Error('Create storage response missing data');
110
- }
111
-
112
- config.setStorages((previous) => [payload, ...previous]);
113
- config.setStorage(payload);
114
- return payload;
115
- });
116
-
117
- export const changeStorageNameRequest = async (
118
- config: StorageApiConfig,
119
- id: number,
120
- dto: ChangeStorageNameRequest
121
- ): Promise<Storage> => runWithRequestState(config, async () => {
122
- const normalizedBaseUrl = normalizeBaseUrl(config.baseUrl);
123
- const response = await fetch(`${normalizedBaseUrl}/api/storages/${id}`, {
124
- method: 'PATCH',
125
- headers: {
126
- ...buildAuthHeaders(config.token),
127
- 'Content-Type': 'application/json'
128
- },
129
- body: JSON.stringify(dto)
130
- });
131
-
132
- if (!response.ok) {
133
- const payload = await readJson<CreateStorageError>(response);
134
- if (payload?.name)
135
- throw payload;
136
-
137
- throw new Error('Failed to update storage');
138
- }
139
-
140
- const payload = await readJson<Storage>(response);
141
- if (!payload) {
142
- throw new Error('Update storage response missing data');
143
- }
144
-
145
- config.setStorages((previous) => updateById(previous, payload));
146
- config.setStorage(payload);
147
- return payload;
148
- });
149
-
150
- export const deleteStorageRequest = async (
151
- config: StorageApiConfig,
152
- id: number
153
- ): Promise<void> => runWithRequestState(config, async () => {
154
- const normalizedBaseUrl = normalizeBaseUrl(config.baseUrl);
155
- const response = await fetch(`${normalizedBaseUrl}/api/storages/${id}`, {
156
- method: 'DELETE',
157
- headers: buildAuthHeaders(config.token)
158
- });
159
-
160
- if (!response.ok) {
161
- throw new Error('Failed to delete storage');
162
- }
163
-
164
- config.setStorages((previous) => previous.filter((item) => item.id !== id));
165
- config.setStorage((current) => (current?.id === id ? null : current));
166
- });
1
+ import type { Storage } from '../../type/models.js';
2
+ import type { PaginatedResponse } from '../../type/PaginatedResponse.js';
3
+ import type { ChangeStorageNameRequest, CreateStorageRequest } from '../../type/requests.js';
4
+ import type { CreateStorageError } from '../../type/storage.js';
5
+ import { buildAuthHeaders, normalizeBaseUrl, readJson } from '../http.js';
6
+ import { runWithRequestState, type RequestStateHandlers } from './requestState.js';
7
+
8
+ type StorageApiConfig = RequestStateHandlers & {
9
+ baseUrl: string;
10
+ token: string | null;
11
+ setStorages: (value: Storage[] | ((items: Storage[]) => Storage[])) => void;
12
+ setStorage: (value: Storage | null | ((prev: Storage | null) => Storage | null)) => void;
13
+ };
14
+
15
+ const updateById = (items: Storage[], updated: Storage): Storage[] => {
16
+ const index = items.findIndex((item) => item.id === updated.id);
17
+ if (index === -1) {
18
+ return [updated, ...items];
19
+ }
20
+
21
+ const next = [...items];
22
+ next[index] = updated;
23
+ return next;
24
+ };
25
+
26
+ export const fetchStoragesRequest = async (
27
+ config: StorageApiConfig,
28
+ search: string,
29
+ size: number,
30
+ page: number
31
+ ): Promise<PaginatedResponse<Storage>> => runWithRequestState(
32
+ config,
33
+ async () => {
34
+ const normalizedBaseUrl = normalizeBaseUrl(config.baseUrl);
35
+ let url = `${normalizedBaseUrl}/api/storages?search=${search}`;
36
+ if (size > 0)
37
+ url += `&page=${page}&size=${size}`;
38
+
39
+ const response = await fetch(url, {
40
+ headers: buildAuthHeaders(config.token)
41
+ });
42
+
43
+ if (!response.ok) {
44
+ throw new Error('Failed to fetch storages');
45
+ }
46
+
47
+ const payload = await readJson<PaginatedResponse<Storage>>(response);
48
+ if (payload) {
49
+ config.setStorages(payload.data);
50
+ return payload;
51
+ }
52
+
53
+ return { data: [], currentPage: 0, hasNext: false, hasPrevious: false, pageSize: 0, totalItems: 0, totalPages: 0 };
54
+ }
55
+ );
56
+
57
+ export const fetchStorageRequest = async (
58
+ config: StorageApiConfig,
59
+ id: number
60
+ ): Promise<Storage | null> => runWithRequestState(config, async () => {
61
+ const normalizedBaseUrl = normalizeBaseUrl(config.baseUrl);
62
+ const response = await fetch(`${normalizedBaseUrl}/api/storages/${id}`, {
63
+ headers: buildAuthHeaders(config.token)
64
+ });
65
+
66
+ if (response.status === 404) {
67
+ config.setStorage(null);
68
+ return null;
69
+ }
70
+
71
+ if (!response.ok) {
72
+ throw new Error('Failed to fetch storage');
73
+ }
74
+
75
+ const payload = await readJson<Storage>(response);
76
+ if (!payload) {
77
+ throw new Error('Storage response missing data');
78
+ }
79
+
80
+ config.setStorage(payload);
81
+ config.setStorages((previous) => updateById(previous, payload));
82
+ return payload;
83
+ });
84
+
85
+ export const createStorageRequest = async (
86
+ config: StorageApiConfig,
87
+ dto: CreateStorageRequest
88
+ ): Promise<Storage> => runWithRequestState(config, async () => {
89
+ const normalizedBaseUrl = normalizeBaseUrl(config.baseUrl);
90
+ const response = await fetch(`${normalizedBaseUrl}/api/storages`, {
91
+ method: 'POST',
92
+ headers: {
93
+ ...buildAuthHeaders(config.token),
94
+ 'Content-Type': 'application/json'
95
+ },
96
+ body: JSON.stringify(dto)
97
+ });
98
+
99
+ if (!response.ok) {
100
+ const payload = await readJson<CreateStorageError>(response);
101
+ if (payload?.name)
102
+ throw payload;
103
+
104
+ throw new Error('Failed to create storage');
105
+ }
106
+
107
+ const payload = await readJson<Storage>(response);
108
+ if (!payload) {
109
+ throw new Error('Create storage response missing data');
110
+ }
111
+
112
+ config.setStorages((previous) => [payload, ...previous]);
113
+ config.setStorage(payload);
114
+ return payload;
115
+ });
116
+
117
+ export const changeStorageNameRequest = async (
118
+ config: StorageApiConfig,
119
+ id: number,
120
+ dto: ChangeStorageNameRequest
121
+ ): Promise<Storage> => runWithRequestState(config, async () => {
122
+ const normalizedBaseUrl = normalizeBaseUrl(config.baseUrl);
123
+ const response = await fetch(`${normalizedBaseUrl}/api/storages/${id}`, {
124
+ method: 'PATCH',
125
+ headers: {
126
+ ...buildAuthHeaders(config.token),
127
+ 'Content-Type': 'application/json'
128
+ },
129
+ body: JSON.stringify(dto)
130
+ });
131
+
132
+ if (!response.ok) {
133
+ const payload = await readJson<CreateStorageError>(response);
134
+ if (payload?.name)
135
+ throw payload;
136
+
137
+ throw new Error('Failed to update storage');
138
+ }
139
+
140
+ const payload = await readJson<Storage>(response);
141
+ if (!payload) {
142
+ throw new Error('Update storage response missing data');
143
+ }
144
+
145
+ config.setStorages((previous) => updateById(previous, payload));
146
+ config.setStorage(payload);
147
+ return payload;
148
+ });
149
+
150
+ export const deleteStorageRequest = async (
151
+ config: StorageApiConfig,
152
+ id: number
153
+ ): Promise<void> => runWithRequestState(config, async () => {
154
+ const normalizedBaseUrl = normalizeBaseUrl(config.baseUrl);
155
+ const response = await fetch(`${normalizedBaseUrl}/api/storages/${id}`, {
156
+ method: 'DELETE',
157
+ headers: buildAuthHeaders(config.token)
158
+ });
159
+
160
+ if (!response.ok) {
161
+ throw new Error('Failed to delete storage');
162
+ }
163
+
164
+ config.setStorages((previous) => previous.filter((item) => item.id !== id));
165
+ config.setStorage((current) => (current?.id === id ? null : current));
166
+ });