@relia-fe/core 0.0.1 → 0.0.2
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/api/index.d.mts +317 -0
- package/dist/api/index.d.ts +317 -0
- package/dist/api/index.js +749 -0
- package/dist/api/index.js.map +1 -0
- package/dist/api/index.mjs +700 -0
- package/dist/api/index.mjs.map +1 -0
- package/dist/index.d.mts +7 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.js +723 -2
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +699 -1
- package/dist/index.mjs.map +1 -1
- package/package.json +30 -3
package/dist/index.mjs
CHANGED
|
@@ -1,3 +1,679 @@
|
|
|
1
|
+
// src/api/base/request.ts
|
|
2
|
+
import axios, {
|
|
3
|
+
AxiosHeaders
|
|
4
|
+
} from "axios";
|
|
5
|
+
var isBrowser = typeof window !== "undefined";
|
|
6
|
+
var shouldRemoveBaseURL = (url) => {
|
|
7
|
+
if (!url) return false;
|
|
8
|
+
return url.startsWith("http") || url.startsWith("/api/");
|
|
9
|
+
};
|
|
10
|
+
var setAuthorizationHeader = (headers, token) => {
|
|
11
|
+
if (headers instanceof AxiosHeaders) {
|
|
12
|
+
const newHeaders = new AxiosHeaders(headers);
|
|
13
|
+
newHeaders.set("Authorization", `TOKEN ${token}`);
|
|
14
|
+
return newHeaders;
|
|
15
|
+
} else {
|
|
16
|
+
return {
|
|
17
|
+
...headers,
|
|
18
|
+
Authorization: `TOKEN ${token}`
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
};
|
|
22
|
+
var applyAuthorizationToConfig = (requestConfig, token) => {
|
|
23
|
+
return {
|
|
24
|
+
...requestConfig,
|
|
25
|
+
headers: setAuthorizationHeader(
|
|
26
|
+
requestConfig.headers ?? {},
|
|
27
|
+
token
|
|
28
|
+
)
|
|
29
|
+
};
|
|
30
|
+
};
|
|
31
|
+
var is401Error = (error) => {
|
|
32
|
+
return !!error && typeof error === "object" && "response" in error && error.response?.status === 401;
|
|
33
|
+
};
|
|
34
|
+
var createBaseRequest = (config) => {
|
|
35
|
+
return axios.create({
|
|
36
|
+
baseURL: config.baseURL,
|
|
37
|
+
headers: {
|
|
38
|
+
"Content-Type": "application/json",
|
|
39
|
+
...config.headers
|
|
40
|
+
}
|
|
41
|
+
});
|
|
42
|
+
};
|
|
43
|
+
var _baseRequest = null;
|
|
44
|
+
var getBaseRequest = () => {
|
|
45
|
+
if (!_baseRequest) {
|
|
46
|
+
_baseRequest = createBaseRequest({ baseURL: "" });
|
|
47
|
+
}
|
|
48
|
+
return _baseRequest;
|
|
49
|
+
};
|
|
50
|
+
var configureBaseRequest = (config) => {
|
|
51
|
+
_baseRequest = createBaseRequest(config);
|
|
52
|
+
};
|
|
53
|
+
var createAuthRequest = (config) => {
|
|
54
|
+
const { authService, axiosConfig } = config;
|
|
55
|
+
const requestInterceptor = async (reqConfig) => {
|
|
56
|
+
let token = authService.getToken();
|
|
57
|
+
if (!token && isBrowser) {
|
|
58
|
+
const result = await authService.authenticate("request-init");
|
|
59
|
+
if (result.success && result.token) {
|
|
60
|
+
token = result.token;
|
|
61
|
+
} else {
|
|
62
|
+
throw new Error("Authentication required");
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
if (!token) {
|
|
66
|
+
throw new Error("Authentication required");
|
|
67
|
+
}
|
|
68
|
+
let newConfig = applyAuthorizationToConfig(reqConfig, token);
|
|
69
|
+
if (shouldRemoveBaseURL(newConfig.url)) {
|
|
70
|
+
newConfig = { ...newConfig, baseURL: void 0 };
|
|
71
|
+
}
|
|
72
|
+
return newConfig;
|
|
73
|
+
};
|
|
74
|
+
const clearAuthAndRedirect = () => {
|
|
75
|
+
authService.logout();
|
|
76
|
+
if (isBrowser) {
|
|
77
|
+
window.location.replace("/");
|
|
78
|
+
}
|
|
79
|
+
};
|
|
80
|
+
const handle401Retry = async (error, retryFn) => {
|
|
81
|
+
const originalConfig = error.config;
|
|
82
|
+
if (originalConfig._retry) {
|
|
83
|
+
console.warn("[Fetcher] Re-authentication retry failed");
|
|
84
|
+
clearAuthAndRedirect();
|
|
85
|
+
return Promise.reject(error);
|
|
86
|
+
}
|
|
87
|
+
originalConfig._retry = true;
|
|
88
|
+
const authResult = await authService.authenticate("token-refresh");
|
|
89
|
+
if (authResult.success && authResult.token) {
|
|
90
|
+
const newConfig = applyAuthorizationToConfig(
|
|
91
|
+
originalConfig,
|
|
92
|
+
authResult.token
|
|
93
|
+
);
|
|
94
|
+
console.log("[Fetcher] Re-authentication successful, retrying request");
|
|
95
|
+
return retryFn(newConfig);
|
|
96
|
+
}
|
|
97
|
+
console.warn("[Fetcher] Re-authentication failed, redirecting to home");
|
|
98
|
+
clearAuthAndRedirect();
|
|
99
|
+
return Promise.reject(error);
|
|
100
|
+
};
|
|
101
|
+
const responseErrorHandler = async (error, retryFn) => {
|
|
102
|
+
console.error(error);
|
|
103
|
+
if (!isBrowser) {
|
|
104
|
+
return Promise.reject(error);
|
|
105
|
+
}
|
|
106
|
+
if (is401Error(error)) {
|
|
107
|
+
return handle401Retry(error, retryFn);
|
|
108
|
+
}
|
|
109
|
+
return Promise.reject(error);
|
|
110
|
+
};
|
|
111
|
+
const baseReq = getBaseRequest();
|
|
112
|
+
const instance = axiosConfig ? baseReq.create(axiosConfig) : baseReq.create();
|
|
113
|
+
instance.interceptors.request.use(
|
|
114
|
+
requestInterceptor,
|
|
115
|
+
(error) => Promise.reject(error)
|
|
116
|
+
);
|
|
117
|
+
instance.interceptors.response.use(
|
|
118
|
+
(response) => response,
|
|
119
|
+
(error) => responseErrorHandler(error, (cfg) => instance.request(cfg))
|
|
120
|
+
);
|
|
121
|
+
return instance;
|
|
122
|
+
};
|
|
123
|
+
|
|
124
|
+
// src/api/base/definition.ts
|
|
125
|
+
function defineFetch(uri, method, option) {
|
|
126
|
+
return {
|
|
127
|
+
uri,
|
|
128
|
+
method,
|
|
129
|
+
host: option?.host,
|
|
130
|
+
// absoluteUri: `${option?.host ?? HOST_PREFIX}${uri}`,
|
|
131
|
+
noAuth: option?.noAuth
|
|
132
|
+
};
|
|
133
|
+
}
|
|
134
|
+
function defineResource(uri, option) {
|
|
135
|
+
return {
|
|
136
|
+
uri,
|
|
137
|
+
method: "get",
|
|
138
|
+
host: option?.host,
|
|
139
|
+
// absoluteUri: `${option?.host ?? HOST_PREFIX}${uri}`,
|
|
140
|
+
noAuth: option?.noAuth
|
|
141
|
+
};
|
|
142
|
+
}
|
|
143
|
+
function defineResourceList(uri, option) {
|
|
144
|
+
return {
|
|
145
|
+
uri,
|
|
146
|
+
method: "get",
|
|
147
|
+
host: option?.host,
|
|
148
|
+
// absoluteUri: `${option?.host ?? HOST_PREFIX}${uri}`,
|
|
149
|
+
noAuth: option?.noAuth
|
|
150
|
+
};
|
|
151
|
+
}
|
|
152
|
+
function defineMutation(uri, option) {
|
|
153
|
+
return {
|
|
154
|
+
uri,
|
|
155
|
+
method: option?.method ?? "post",
|
|
156
|
+
host: option?.host,
|
|
157
|
+
// absoluteUri: `${option?.host ?? HOST_PREFIX}${uri}`,
|
|
158
|
+
noAuth: option?.noAuth
|
|
159
|
+
};
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
// src/api/base/TokenStorageService.ts
|
|
163
|
+
var isBrowser2 = typeof window !== "undefined";
|
|
164
|
+
var STORAGE_KEY = "auth_tokens";
|
|
165
|
+
var TokenStorageService = class {
|
|
166
|
+
constructor() {
|
|
167
|
+
this.listeners = /* @__PURE__ */ new Set();
|
|
168
|
+
this.boundHandleStorage = null;
|
|
169
|
+
}
|
|
170
|
+
setToken(token, address) {
|
|
171
|
+
if (!isBrowser2) return;
|
|
172
|
+
const key = address?.toLowerCase() ?? "_default";
|
|
173
|
+
const map = this.getMap();
|
|
174
|
+
if (token === void 0) {
|
|
175
|
+
delete map[key];
|
|
176
|
+
} else {
|
|
177
|
+
map[key] = token;
|
|
178
|
+
}
|
|
179
|
+
this.saveMap(map);
|
|
180
|
+
}
|
|
181
|
+
getToken(address) {
|
|
182
|
+
const key = address?.toLowerCase() ?? "_default";
|
|
183
|
+
return this.getMap()[key] ?? null;
|
|
184
|
+
}
|
|
185
|
+
getMap() {
|
|
186
|
+
if (!isBrowser2) return {};
|
|
187
|
+
try {
|
|
188
|
+
const data = localStorage.getItem(STORAGE_KEY);
|
|
189
|
+
return data ? JSON.parse(data) : {};
|
|
190
|
+
} catch {
|
|
191
|
+
return {};
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
saveMap(map) {
|
|
195
|
+
if (!isBrowser2) return;
|
|
196
|
+
try {
|
|
197
|
+
if (Object.keys(map).length === 0) {
|
|
198
|
+
localStorage.removeItem(STORAGE_KEY);
|
|
199
|
+
} else {
|
|
200
|
+
localStorage.setItem(STORAGE_KEY, JSON.stringify(map));
|
|
201
|
+
}
|
|
202
|
+
} catch (e) {
|
|
203
|
+
console.error("Failed to persist auth tokens", e);
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
subscribe(listener) {
|
|
207
|
+
this.listeners.add(listener);
|
|
208
|
+
if (isBrowser2 && this.listeners.size === 1) {
|
|
209
|
+
this.boundHandleStorage = (e) => {
|
|
210
|
+
if (e.key === STORAGE_KEY) {
|
|
211
|
+
this.listeners.forEach((l) => l());
|
|
212
|
+
}
|
|
213
|
+
};
|
|
214
|
+
window.addEventListener("storage", this.boundHandleStorage);
|
|
215
|
+
}
|
|
216
|
+
return () => {
|
|
217
|
+
this.listeners.delete(listener);
|
|
218
|
+
if (isBrowser2 && this.listeners.size === 0 && this.boundHandleStorage) {
|
|
219
|
+
window.removeEventListener("storage", this.boundHandleStorage);
|
|
220
|
+
this.boundHandleStorage = null;
|
|
221
|
+
}
|
|
222
|
+
};
|
|
223
|
+
}
|
|
224
|
+
};
|
|
225
|
+
var defaultTokenStorageService = new TokenStorageService();
|
|
226
|
+
|
|
227
|
+
// src/api/base/AuthError.ts
|
|
228
|
+
var AuthError = class _AuthError extends Error {
|
|
229
|
+
constructor(message, errorType) {
|
|
230
|
+
super(message);
|
|
231
|
+
this.name = "AuthError";
|
|
232
|
+
this.errorType = errorType;
|
|
233
|
+
Object.setPrototypeOf(this, _AuthError.prototype);
|
|
234
|
+
}
|
|
235
|
+
};
|
|
236
|
+
|
|
237
|
+
// src/api/base/AuthService.ts
|
|
238
|
+
var AuthService = class {
|
|
239
|
+
constructor(config) {
|
|
240
|
+
this.authPromise = null;
|
|
241
|
+
// 用于并发控制
|
|
242
|
+
// 状态管理
|
|
243
|
+
this.state = { status: "idle" };
|
|
244
|
+
this.listeners = /* @__PURE__ */ new Set();
|
|
245
|
+
this.refreshToken = config.refreshToken;
|
|
246
|
+
this.tokenStorageService = config.tokenStorageService ?? defaultTokenStorageService;
|
|
247
|
+
this.tokenStorageService.subscribe(() => this.handleStorageChange());
|
|
248
|
+
}
|
|
249
|
+
/**
|
|
250
|
+
* Authenticate with concurrency control
|
|
251
|
+
* Multiple concurrent calls will share the same Promise
|
|
252
|
+
* Stores token on success
|
|
253
|
+
*/
|
|
254
|
+
async authenticate(context) {
|
|
255
|
+
if (this.state.status === "authenticating" && this.authPromise) {
|
|
256
|
+
console.log(
|
|
257
|
+
`[AuthService] Authentication already in progress, reusing Promise`
|
|
258
|
+
);
|
|
259
|
+
return this.authPromise;
|
|
260
|
+
}
|
|
261
|
+
const startAddress = this.state.address;
|
|
262
|
+
this.setState({
|
|
263
|
+
status: "authenticating",
|
|
264
|
+
address: startAddress
|
|
265
|
+
});
|
|
266
|
+
this.authPromise = this.refreshToken(context);
|
|
267
|
+
try {
|
|
268
|
+
const result = await this.authPromise;
|
|
269
|
+
const currentAddress = this.state.address;
|
|
270
|
+
if (this.state.status !== "authenticating") {
|
|
271
|
+
console.log(
|
|
272
|
+
`[AuthService] Authentication was cancelled, ignoring result`
|
|
273
|
+
);
|
|
274
|
+
throw new AuthError("Authentication was cancelled", "cancelled" /* CANCELLED */);
|
|
275
|
+
}
|
|
276
|
+
if (currentAddress !== startAddress) {
|
|
277
|
+
console.log(
|
|
278
|
+
`[AuthService] Address changed during auth, ignoring result`
|
|
279
|
+
);
|
|
280
|
+
throw new AuthError(
|
|
281
|
+
"Address changed during authentication",
|
|
282
|
+
"address_changed" /* ADDRESS_CHANGED */
|
|
283
|
+
);
|
|
284
|
+
}
|
|
285
|
+
this.tokenStorageService.setToken(
|
|
286
|
+
result.token,
|
|
287
|
+
currentAddress ?? void 0
|
|
288
|
+
);
|
|
289
|
+
this.setState({
|
|
290
|
+
status: "authenticated",
|
|
291
|
+
address: currentAddress
|
|
292
|
+
});
|
|
293
|
+
console.log(`[AuthService] Token stored successfully`);
|
|
294
|
+
return result;
|
|
295
|
+
} catch (error) {
|
|
296
|
+
const currentAddress = this.state.address;
|
|
297
|
+
if (error instanceof AuthError) {
|
|
298
|
+
this.setState({
|
|
299
|
+
status: "unauthenticated",
|
|
300
|
+
address: currentAddress,
|
|
301
|
+
error
|
|
302
|
+
});
|
|
303
|
+
throw error;
|
|
304
|
+
}
|
|
305
|
+
const authError = new AuthError(
|
|
306
|
+
error instanceof Error ? error.message : "Unknown error",
|
|
307
|
+
"unknown" /* UNKNOWN */
|
|
308
|
+
);
|
|
309
|
+
this.setState({
|
|
310
|
+
status: "unauthenticated",
|
|
311
|
+
address: currentAddress,
|
|
312
|
+
error: authError
|
|
313
|
+
});
|
|
314
|
+
throw authError;
|
|
315
|
+
} finally {
|
|
316
|
+
this.authPromise = null;
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
/**
|
|
320
|
+
* 重置内部认证状态(私有方法)
|
|
321
|
+
*/
|
|
322
|
+
reset() {
|
|
323
|
+
this.authPromise = null;
|
|
324
|
+
}
|
|
325
|
+
/**
|
|
326
|
+
* Get current token for the current wallet address
|
|
327
|
+
*/
|
|
328
|
+
getToken() {
|
|
329
|
+
return this.tokenStorageService.getToken(this.state.address ?? void 0);
|
|
330
|
+
}
|
|
331
|
+
/**
|
|
332
|
+
* 检查地址是否有有效 token(私有方法)
|
|
333
|
+
*/
|
|
334
|
+
isAddressAuthenticated(address) {
|
|
335
|
+
if (!address) return false;
|
|
336
|
+
return this.tokenStorageService.getToken(address) !== null;
|
|
337
|
+
}
|
|
338
|
+
/**
|
|
339
|
+
* Logout: clear token for current address and update state
|
|
340
|
+
*/
|
|
341
|
+
logout() {
|
|
342
|
+
const address = this.state.address;
|
|
343
|
+
this.tokenStorageService.setToken(void 0, address ?? void 0);
|
|
344
|
+
this.reset();
|
|
345
|
+
this.setState({ status: "unauthenticated", address });
|
|
346
|
+
}
|
|
347
|
+
/**
|
|
348
|
+
* Get current authentication state
|
|
349
|
+
*/
|
|
350
|
+
getState() {
|
|
351
|
+
return { ...this.state };
|
|
352
|
+
}
|
|
353
|
+
/**
|
|
354
|
+
* Subscribe to state changes
|
|
355
|
+
*/
|
|
356
|
+
subscribe(listener) {
|
|
357
|
+
this.listeners.add(listener);
|
|
358
|
+
return () => this.listeners.delete(listener);
|
|
359
|
+
}
|
|
360
|
+
/**
|
|
361
|
+
* Handle wallet address changes
|
|
362
|
+
* Note: Wallet disconnection should be handled externally by calling logout()
|
|
363
|
+
*/
|
|
364
|
+
handleWalletChange(address) {
|
|
365
|
+
const isAuthenticating = this.state.status === "authenticating";
|
|
366
|
+
if (isAuthenticating && this.state.address !== address) {
|
|
367
|
+
this.reset();
|
|
368
|
+
this.setState({ status: "idle", address });
|
|
369
|
+
}
|
|
370
|
+
if (this.isAddressAuthenticated(address)) {
|
|
371
|
+
if (this.state.status !== "authenticated" || this.state.address !== address) {
|
|
372
|
+
this.setState({ status: "authenticated", address });
|
|
373
|
+
}
|
|
374
|
+
return;
|
|
375
|
+
}
|
|
376
|
+
const isAlreadyAuthForThisAddress = this.state.status === "authenticated" && this.state.address === address;
|
|
377
|
+
if (!isAuthenticating && !isAlreadyAuthForThisAddress) {
|
|
378
|
+
this.setState({ status: "idle", address });
|
|
379
|
+
this.authenticate("wallet-connect").catch(() => {
|
|
380
|
+
});
|
|
381
|
+
}
|
|
382
|
+
}
|
|
383
|
+
/**
|
|
384
|
+
* 处理 StorageChange 事件(用于多选项卡同步)
|
|
385
|
+
* 当 localStorage 在另一个选项卡中发生更改时调用
|
|
386
|
+
*/
|
|
387
|
+
handleStorageChange() {
|
|
388
|
+
const address = this.state.address;
|
|
389
|
+
if (!address) return;
|
|
390
|
+
const hasToken = this.isAddressAuthenticated(address);
|
|
391
|
+
const currentStatus = this.state.status;
|
|
392
|
+
if (!hasToken && currentStatus === "authenticated") {
|
|
393
|
+
this.setState({ status: "unauthenticated", address });
|
|
394
|
+
} else if (hasToken && currentStatus !== "authenticated") {
|
|
395
|
+
this.setState({ status: "authenticated", address });
|
|
396
|
+
}
|
|
397
|
+
}
|
|
398
|
+
/**
|
|
399
|
+
* 更新状态并通知监听者
|
|
400
|
+
*/
|
|
401
|
+
setState(newState) {
|
|
402
|
+
this.state = newState;
|
|
403
|
+
this.listeners.forEach((listener) => listener(newState));
|
|
404
|
+
}
|
|
405
|
+
};
|
|
406
|
+
|
|
407
|
+
// src/api/provider/AuthProvider.tsx
|
|
408
|
+
import {
|
|
409
|
+
createContext,
|
|
410
|
+
useCallback,
|
|
411
|
+
useEffect,
|
|
412
|
+
useMemo,
|
|
413
|
+
useRef,
|
|
414
|
+
useState
|
|
415
|
+
} from "react";
|
|
416
|
+
import { SWRConfig, useSWRConfig } from "swr";
|
|
417
|
+
import { jsx } from "react/jsx-runtime";
|
|
418
|
+
function isInstanceConfig(config) {
|
|
419
|
+
return "authService" in config && "authRequest" in config;
|
|
420
|
+
}
|
|
421
|
+
var AuthContext = createContext(null);
|
|
422
|
+
var AuthRequestContext = createContext(null);
|
|
423
|
+
var useAuthInternal = ({
|
|
424
|
+
authService,
|
|
425
|
+
address
|
|
426
|
+
}) => {
|
|
427
|
+
const { mutate: globalMutate } = useSWRConfig();
|
|
428
|
+
const [authState, setAuthState] = useState(() => authService.getState());
|
|
429
|
+
useEffect(() => {
|
|
430
|
+
return authService.subscribe(setAuthState);
|
|
431
|
+
}, [authService]);
|
|
432
|
+
useEffect(() => {
|
|
433
|
+
authService.handleWalletChange(address);
|
|
434
|
+
}, [address, authService]);
|
|
435
|
+
const prevStatusRef = useRef(void 0);
|
|
436
|
+
const prevAddressRef = useRef(void 0);
|
|
437
|
+
useEffect(() => {
|
|
438
|
+
const prevStatus = prevStatusRef.current;
|
|
439
|
+
const prevAddress = prevAddressRef.current;
|
|
440
|
+
const currentStatus = authState.status;
|
|
441
|
+
const currentAddress = authState.address;
|
|
442
|
+
prevStatusRef.current = currentStatus;
|
|
443
|
+
prevAddressRef.current = currentAddress;
|
|
444
|
+
if (currentStatus === "authenticated" && prevStatus !== "authenticated" || currentStatus === "authenticated" && currentAddress !== prevAddress) {
|
|
445
|
+
globalMutate(() => true, void 0, { revalidate: true });
|
|
446
|
+
}
|
|
447
|
+
}, [authState.status, authState.address, globalMutate]);
|
|
448
|
+
const authenticate = useCallback(async () => {
|
|
449
|
+
if (!address) {
|
|
450
|
+
console.warn("[Auth] Cannot authenticate without address");
|
|
451
|
+
return;
|
|
452
|
+
}
|
|
453
|
+
if (authState.status === "authenticating") {
|
|
454
|
+
console.log("[Auth] Authentication already in progress");
|
|
455
|
+
return;
|
|
456
|
+
}
|
|
457
|
+
try {
|
|
458
|
+
await authService.authenticate("wallet-connect");
|
|
459
|
+
} catch (error) {
|
|
460
|
+
console.error("[Auth] Authentication failed:", error);
|
|
461
|
+
}
|
|
462
|
+
}, [authService, address, authState.status]);
|
|
463
|
+
const logout = useCallback(() => {
|
|
464
|
+
authService.logout();
|
|
465
|
+
}, [authService]);
|
|
466
|
+
return {
|
|
467
|
+
status: authState.status,
|
|
468
|
+
error: authState.error,
|
|
469
|
+
address: authState.address,
|
|
470
|
+
isAuthenticated: authState.status === "authenticated",
|
|
471
|
+
isAuthenticating: authState.status === "authenticating",
|
|
472
|
+
authenticate,
|
|
473
|
+
logout
|
|
474
|
+
};
|
|
475
|
+
};
|
|
476
|
+
var AuthProvider = ({
|
|
477
|
+
children,
|
|
478
|
+
...config
|
|
479
|
+
}) => {
|
|
480
|
+
const { authService, authRequest, address } = useMemo(() => {
|
|
481
|
+
if (isInstanceConfig(config)) {
|
|
482
|
+
return {
|
|
483
|
+
authService: config.authService,
|
|
484
|
+
authRequest: config.authRequest,
|
|
485
|
+
address: config.address
|
|
486
|
+
};
|
|
487
|
+
}
|
|
488
|
+
const { refreshTokenFn, axiosConfig, tokenStorageService, address: address2 } = config;
|
|
489
|
+
const service = new AuthService({
|
|
490
|
+
refreshToken: refreshTokenFn,
|
|
491
|
+
tokenStorageService
|
|
492
|
+
});
|
|
493
|
+
const request = createAuthRequest({
|
|
494
|
+
authService: service,
|
|
495
|
+
axiosConfig
|
|
496
|
+
});
|
|
497
|
+
return { authService: service, authRequest: request, address: address2 };
|
|
498
|
+
}, [config]);
|
|
499
|
+
const auth = useAuthInternal({ authService, address });
|
|
500
|
+
return /* @__PURE__ */ jsx(AuthContext.Provider, { value: auth, children: /* @__PURE__ */ jsx(AuthRequestContext.Provider, { value: authRequest, children: /* @__PURE__ */ jsx(
|
|
501
|
+
SWRConfig,
|
|
502
|
+
{
|
|
503
|
+
value: {
|
|
504
|
+
revalidateOnFocus: false,
|
|
505
|
+
shouldRetryOnError: false,
|
|
506
|
+
dedupingInterval: 2e3,
|
|
507
|
+
revalidateOnReconnect: false
|
|
508
|
+
},
|
|
509
|
+
children
|
|
510
|
+
}
|
|
511
|
+
) }) });
|
|
512
|
+
};
|
|
513
|
+
|
|
514
|
+
// src/api/hooks/useAuth.ts
|
|
515
|
+
import { useContext } from "react";
|
|
516
|
+
var useAuth = () => {
|
|
517
|
+
const context = useContext(AuthContext);
|
|
518
|
+
if (!context) {
|
|
519
|
+
throw new Error("useAuth must be used within AuthProvider");
|
|
520
|
+
}
|
|
521
|
+
return context;
|
|
522
|
+
};
|
|
523
|
+
|
|
524
|
+
// src/api/hooks/useAuthChange.ts
|
|
525
|
+
import { useEffect as useEffect2, useRef as useRef2 } from "react";
|
|
526
|
+
function useAuthChange(onChange) {
|
|
527
|
+
const { status, error, address } = useAuth();
|
|
528
|
+
const prevStatusRef = useRef2(void 0);
|
|
529
|
+
const prevAddressRef = useRef2(void 0);
|
|
530
|
+
useEffect2(() => {
|
|
531
|
+
const prevStatus = prevStatusRef.current;
|
|
532
|
+
const prevAddress = prevAddressRef.current;
|
|
533
|
+
prevStatusRef.current = status;
|
|
534
|
+
prevAddressRef.current = address;
|
|
535
|
+
if (status === "authenticated" && prevStatus !== "authenticated" || status === "authenticated" && address !== prevAddress) {
|
|
536
|
+
onChange({ type: "authenticated" });
|
|
537
|
+
} else if (error && status !== prevStatus) {
|
|
538
|
+
onChange({ type: "error", error });
|
|
539
|
+
} else if (status === "unauthenticated" && prevStatus && prevStatus !== "idle") {
|
|
540
|
+
onChange({ type: "unauthenticated", error });
|
|
541
|
+
}
|
|
542
|
+
}, [status, error, address, onChange]);
|
|
543
|
+
}
|
|
544
|
+
|
|
545
|
+
// src/api/hooks/useAuthRequest.ts
|
|
546
|
+
import { useContext as useContext2 } from "react";
|
|
547
|
+
var useAuthRequest = () => {
|
|
548
|
+
const context = useContext2(AuthRequestContext);
|
|
549
|
+
if (!context) {
|
|
550
|
+
throw new Error("useAuthRequest must be used within AuthProvider");
|
|
551
|
+
}
|
|
552
|
+
return context;
|
|
553
|
+
};
|
|
554
|
+
|
|
555
|
+
// src/api/hooks/useResource.ts
|
|
556
|
+
import useSWR from "swr";
|
|
557
|
+
import { useMemo as useMemo2 } from "react";
|
|
558
|
+
|
|
559
|
+
// src/api/hooks/fetcherFactory.ts
|
|
560
|
+
var createFetchFn = (authRequest) => {
|
|
561
|
+
return async (requestIdentity, payload) => {
|
|
562
|
+
const { method, uri, noAuth } = requestIdentity;
|
|
563
|
+
const instance = noAuth ? getBaseRequest() : authRequest;
|
|
564
|
+
if (!method || method === "get") {
|
|
565
|
+
const { data: data2 } = await instance.get(uri, {
|
|
566
|
+
params: payload
|
|
567
|
+
});
|
|
568
|
+
return data2;
|
|
569
|
+
}
|
|
570
|
+
if (method === "delete") {
|
|
571
|
+
const { data: data2 } = await instance.delete(uri, {
|
|
572
|
+
data: payload
|
|
573
|
+
});
|
|
574
|
+
return data2;
|
|
575
|
+
}
|
|
576
|
+
const { data } = await instance.post(uri, payload);
|
|
577
|
+
return data;
|
|
578
|
+
};
|
|
579
|
+
};
|
|
580
|
+
var createFetcherInterceptor = (authRequest) => {
|
|
581
|
+
const fetchFn = createFetchFn(authRequest);
|
|
582
|
+
async function fetcherInterceptor(params) {
|
|
583
|
+
if (Array.isArray(params[0])) {
|
|
584
|
+
const multiParams = params;
|
|
585
|
+
return await Promise.all(
|
|
586
|
+
multiParams.map(([identity2, payload2]) => fetchFn(identity2, payload2))
|
|
587
|
+
);
|
|
588
|
+
}
|
|
589
|
+
const [identity, payload] = params;
|
|
590
|
+
return await fetchFn(identity, payload);
|
|
591
|
+
}
|
|
592
|
+
return fetcherInterceptor;
|
|
593
|
+
};
|
|
594
|
+
var createFetcherMutation = (authRequest) => {
|
|
595
|
+
const fetchFn = createFetchFn(authRequest);
|
|
596
|
+
return async (requestIdentity, { arg }) => {
|
|
597
|
+
const res = await fetchFn(requestIdentity, arg);
|
|
598
|
+
if (!res.success || res.code !== 0 && res.code !== 10001) {
|
|
599
|
+
throw Error(res.message);
|
|
600
|
+
}
|
|
601
|
+
return res;
|
|
602
|
+
};
|
|
603
|
+
};
|
|
604
|
+
|
|
605
|
+
// src/api/hooks/useResource.ts
|
|
606
|
+
var useResource = (requestIdentity, params, option) => {
|
|
607
|
+
const authRequest = useAuthRequest();
|
|
608
|
+
const fetcher = useMemo2(
|
|
609
|
+
() => createFetcherInterceptor(authRequest),
|
|
610
|
+
[authRequest]
|
|
611
|
+
);
|
|
612
|
+
const { data, ...query } = useSWR(
|
|
613
|
+
requestIdentity && [requestIdentity, params],
|
|
614
|
+
fetcher,
|
|
615
|
+
option
|
|
616
|
+
);
|
|
617
|
+
return {
|
|
618
|
+
...query,
|
|
619
|
+
response: data,
|
|
620
|
+
data: data?.data
|
|
621
|
+
};
|
|
622
|
+
};
|
|
623
|
+
|
|
624
|
+
// src/api/hooks/useResourceList.ts
|
|
625
|
+
import useSWR2 from "swr";
|
|
626
|
+
import { useMemo as useMemo3, useState as useState2 } from "react";
|
|
627
|
+
var useResourceList = (requestIdentity, params, option) => {
|
|
628
|
+
const authRequest = useAuthRequest();
|
|
629
|
+
const fetcher = useMemo3(
|
|
630
|
+
() => createFetcherInterceptor(authRequest),
|
|
631
|
+
[authRequest]
|
|
632
|
+
);
|
|
633
|
+
const [page, setPage] = useState2(option?.page ?? 1);
|
|
634
|
+
const [size, setSize] = useState2(option?.size ?? 10);
|
|
635
|
+
const pageMapping = option?.pageMapping || ((pageInfo) => pageInfo);
|
|
636
|
+
const keyWithPage = requestIdentity && [
|
|
637
|
+
requestIdentity,
|
|
638
|
+
{ ...pageMapping({ page, size }), ...params }
|
|
639
|
+
];
|
|
640
|
+
const { data, ...query } = useSWR2(
|
|
641
|
+
keyWithPage,
|
|
642
|
+
fetcher,
|
|
643
|
+
option
|
|
644
|
+
);
|
|
645
|
+
return {
|
|
646
|
+
...query,
|
|
647
|
+
response: data,
|
|
648
|
+
list: data?.data?.items,
|
|
649
|
+
pagination: {
|
|
650
|
+
count: (data?.data?.total ?? 0) / size,
|
|
651
|
+
page,
|
|
652
|
+
size,
|
|
653
|
+
setPage,
|
|
654
|
+
setSize
|
|
655
|
+
}
|
|
656
|
+
};
|
|
657
|
+
};
|
|
658
|
+
|
|
659
|
+
// src/api/hooks/useMutation.ts
|
|
660
|
+
import useSWRMutation from "swr/mutation";
|
|
661
|
+
import { useMemo as useMemo4 } from "react";
|
|
662
|
+
var useMutation = (key, option) => {
|
|
663
|
+
const authRequest = useAuthRequest();
|
|
664
|
+
const fetcher = useMemo4(
|
|
665
|
+
() => createFetcherMutation(authRequest),
|
|
666
|
+
[authRequest]
|
|
667
|
+
);
|
|
668
|
+
const { data, error, ...query } = useSWRMutation(key, fetcher, option);
|
|
669
|
+
return {
|
|
670
|
+
...query,
|
|
671
|
+
error,
|
|
672
|
+
response: data,
|
|
673
|
+
data: data?.data
|
|
674
|
+
};
|
|
675
|
+
};
|
|
676
|
+
|
|
1
677
|
// src/utils/index.ts
|
|
2
678
|
import { omit, pick, debounce, throttle } from "radash";
|
|
3
679
|
import {
|
|
@@ -36,14 +712,30 @@ var copyToClipboard = async (text) => {
|
|
|
36
712
|
}
|
|
37
713
|
};
|
|
38
714
|
export {
|
|
715
|
+
AuthError,
|
|
716
|
+
AuthProvider,
|
|
717
|
+
AuthService,
|
|
718
|
+
TokenStorageService,
|
|
39
719
|
cloneDeep,
|
|
720
|
+
configureBaseRequest,
|
|
40
721
|
copyToClipboard,
|
|
722
|
+
createAuthRequest,
|
|
723
|
+
createBaseRequest,
|
|
724
|
+
createFetcherInterceptor,
|
|
725
|
+
createFetcherMutation,
|
|
41
726
|
debounce,
|
|
727
|
+
defaultTokenStorageService,
|
|
728
|
+
defineFetch,
|
|
729
|
+
defineMutation,
|
|
730
|
+
defineResource,
|
|
731
|
+
defineResourceList,
|
|
42
732
|
formatCurrency,
|
|
43
733
|
formatDate,
|
|
44
734
|
generateId,
|
|
45
735
|
get,
|
|
736
|
+
getBaseRequest,
|
|
46
737
|
groupBy,
|
|
738
|
+
isBrowser,
|
|
47
739
|
isEmpty,
|
|
48
740
|
isEqual,
|
|
49
741
|
merge,
|
|
@@ -55,6 +747,12 @@ export {
|
|
|
55
747
|
sortBy,
|
|
56
748
|
throttle,
|
|
57
749
|
uniq,
|
|
58
|
-
uniqBy
|
|
750
|
+
uniqBy,
|
|
751
|
+
useAuth,
|
|
752
|
+
useAuthChange,
|
|
753
|
+
useAuthRequest,
|
|
754
|
+
useMutation,
|
|
755
|
+
useResource,
|
|
756
|
+
useResourceList
|
|
59
757
|
};
|
|
60
758
|
//# sourceMappingURL=index.mjs.map
|