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