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.
- package/dist/index.cjs.js +23 -0
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.d.cts +2 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.esm.js +23 -0
- package/dist/index.esm.js.map +1 -1
- package/package.json +36 -36
- package/src/context/AuthContext.tsx +161 -161
- package/src/context/InviteContext.tsx +74 -74
- package/src/context/ProductContext.tsx +131 -121
- package/src/context/RunningLowContext.tsx +100 -100
- package/src/context/ShoppingListContext.tsx +76 -76
- package/src/context/StorageContext.tsx +105 -105
- package/src/context/StorageItemContext.tsx +157 -157
- package/src/context/StorageMemberContext.tsx +84 -84
- package/src/context/UserContext.tsx +109 -109
- package/src/context/__tests__/contexts.test.tsx +370 -370
- package/src/context/api/authApi.ts +155 -155
- package/src/context/api/inviteApi.ts +65 -65
- package/src/context/api/productApi.ts +223 -201
- package/src/context/api/requestState.ts +24 -24
- package/src/context/api/runningLowApi.ts +141 -141
- package/src/context/api/shoppingListApi.ts +161 -159
- package/src/context/api/storageApi.ts +166 -166
- package/src/context/api/storageItemApi.ts +260 -260
- package/src/context/api/storageMemberApi.ts +84 -84
- package/src/context/api/userApi.ts +161 -161
- package/src/context/http.ts +22 -22
- package/src/index.ts +21 -21
- package/src/type/PaginatedResponse.ts +8 -8
- package/src/type/auth.ts +79 -79
- package/src/type/base.ts +21 -21
- package/src/type/item.ts +12 -12
- package/src/type/member.ts +6 -6
- package/src/type/models.ts +56 -56
- package/src/type/product.ts +11 -11
- package/src/type/requests.ts +60 -60
- package/src/type/runninglow.ts +13 -13
- package/src/type/shoppingList.ts +13 -13
- package/src/type/storage.ts +7 -7
- package/src/type/user.ts +11 -11
- package/tsconfig.json +46 -46
- package/tsup.config.ts +10 -10
- 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
|
+
});
|