astrogators-shared-ui 0.7.0 → 0.8.0
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.js +127 -123
- package/dist/src/index.d.ts +2 -0
- package/dist/src/services/api.d.ts +7 -5
- package/dist/src/services/tokenRefresh.d.ts +25 -0
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -200,61 +200,65 @@ var x = "astrogators_access_token", S = "astrogators_refresh_token", C = () => l
|
|
|
200
200
|
w(e), D(t);
|
|
201
201
|
}, A = () => {
|
|
202
202
|
T(), O();
|
|
203
|
-
},
|
|
203
|
+
}, ee = () => !!C(), j = "", M, N = null, P = (e) => {
|
|
204
|
+
j = e.baseURL, M = e.onUnauthorized;
|
|
205
|
+
}, F = () => N || (N = (async () => {
|
|
206
|
+
let e = E();
|
|
207
|
+
if (!e) throw Error("No refresh token available");
|
|
208
|
+
let t = await fetch(`${j}/api/v1/auth/refresh`, {
|
|
209
|
+
method: "POST",
|
|
210
|
+
headers: { "Content-Type": "application/json" },
|
|
211
|
+
body: JSON.stringify({ refresh_token: e })
|
|
212
|
+
});
|
|
213
|
+
if (!t.ok) throw A(), M?.(), Error("Token refresh failed");
|
|
214
|
+
let n = await t.json();
|
|
215
|
+
return k(n.access_token, n.refresh_token), n.access_token;
|
|
216
|
+
})().finally(() => {
|
|
217
|
+
N = null;
|
|
218
|
+
}), N), I = async (e, t = {}) => {
|
|
219
|
+
let n = C(), r = { ...t.headers };
|
|
220
|
+
n && (r.Authorization = `Bearer ${n}`);
|
|
221
|
+
let i = await fetch(e, {
|
|
222
|
+
...t,
|
|
223
|
+
headers: r
|
|
224
|
+
});
|
|
225
|
+
if (i.status !== 401 || !n) return i;
|
|
226
|
+
try {
|
|
227
|
+
return r.Authorization = `Bearer ${await F()}`, await fetch(e, {
|
|
228
|
+
...t,
|
|
229
|
+
headers: r
|
|
230
|
+
});
|
|
231
|
+
} catch {
|
|
232
|
+
return i;
|
|
233
|
+
}
|
|
234
|
+
}, L = class {
|
|
204
235
|
baseURL;
|
|
205
|
-
onUnauthorized;
|
|
206
|
-
isRefreshing = !1;
|
|
207
|
-
refreshPromise = null;
|
|
208
236
|
constructor(e) {
|
|
209
|
-
this.baseURL = e.baseURL,
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
let e = E();
|
|
213
|
-
if (!e) throw Error("No refresh token available");
|
|
214
|
-
let t = await fetch(`${this.baseURL}/api/v1/auth/refresh`, {
|
|
215
|
-
method: "POST",
|
|
216
|
-
headers: { "Content-Type": "application/json" },
|
|
217
|
-
body: JSON.stringify({ refresh_token: e })
|
|
237
|
+
this.baseURL = e.baseURL, P({
|
|
238
|
+
baseURL: e.baseURL,
|
|
239
|
+
onUnauthorized: e.onUnauthorized
|
|
218
240
|
});
|
|
219
|
-
if (!t.ok) throw A(), this.onUnauthorized?.(), Error("Token refresh failed");
|
|
220
|
-
let n = await t.json();
|
|
221
|
-
return k(n.access_token, n.refresh_token), n.access_token;
|
|
222
241
|
}
|
|
223
242
|
async request(e, t = {}) {
|
|
224
|
-
let n =
|
|
243
|
+
let n = {
|
|
225
244
|
"Content-Type": "application/json",
|
|
226
245
|
...t.headers
|
|
227
|
-
}
|
|
228
|
-
n && (r.Authorization = `Bearer ${n}`);
|
|
229
|
-
let i = `${this.baseURL}${e}`, a = await fetch(i, {
|
|
246
|
+
}, r = await I(`${this.baseURL}${e}`, {
|
|
230
247
|
...t,
|
|
231
|
-
headers:
|
|
248
|
+
headers: n
|
|
232
249
|
});
|
|
233
|
-
if (
|
|
234
|
-
this.isRefreshing || (this.isRefreshing = !0, this.refreshPromise = this.refreshAccessToken().finally(() => {
|
|
235
|
-
this.isRefreshing = !1, this.refreshPromise = null;
|
|
236
|
-
}));
|
|
237
|
-
try {
|
|
238
|
-
r.Authorization = `Bearer ${await this.refreshPromise}`, a = await fetch(i, {
|
|
239
|
-
...t,
|
|
240
|
-
headers: r
|
|
241
|
-
});
|
|
242
|
-
} catch {
|
|
243
|
-
throw Error("Authentication failed");
|
|
244
|
-
}
|
|
245
|
-
}
|
|
246
|
-
if (!a.ok) {
|
|
250
|
+
if (!r.ok) {
|
|
247
251
|
let e = {
|
|
248
|
-
message:
|
|
249
|
-
status:
|
|
252
|
+
message: r.statusText,
|
|
253
|
+
status: r.status
|
|
250
254
|
};
|
|
251
255
|
try {
|
|
252
|
-
let t = await
|
|
253
|
-
|
|
256
|
+
let t = await r.json();
|
|
257
|
+
r.status === 422 && Array.isArray(t.detail) ? e.message = t.detail.map((e) => e.msg || "Validation error").join(", ") : typeof t.detail == "string" ? e.message = t.detail : t.message && (e.message = t.message), e.detail = t.detail;
|
|
254
258
|
} catch {}
|
|
255
259
|
throw e;
|
|
256
260
|
}
|
|
257
|
-
return
|
|
261
|
+
return r.status === 204 ? {} : r.json();
|
|
258
262
|
}
|
|
259
263
|
async get(e, t) {
|
|
260
264
|
return this.request(e, {
|
|
@@ -289,55 +293,55 @@ var x = "astrogators_access_token", S = "astrogators_refresh_token", C = () => l
|
|
|
289
293
|
method: "DELETE"
|
|
290
294
|
});
|
|
291
295
|
}
|
|
292
|
-
},
|
|
293
|
-
|
|
294
|
-
},
|
|
296
|
+
}, R, z = (e) => {
|
|
297
|
+
R = new L(e);
|
|
298
|
+
}, B = "astrogators_ally_codes", V = "astrogators_selected_ally_code", H = () => {
|
|
295
299
|
try {
|
|
296
|
-
let e = localStorage.getItem(
|
|
300
|
+
let e = localStorage.getItem(B);
|
|
297
301
|
return e ? JSON.parse(e) : [];
|
|
298
302
|
} catch (e) {
|
|
299
303
|
return console.error("Failed to read ally codes from localStorage:", e), [];
|
|
300
304
|
}
|
|
301
|
-
},
|
|
305
|
+
}, te = (e) => {
|
|
302
306
|
try {
|
|
303
|
-
let t =
|
|
307
|
+
let t = H();
|
|
304
308
|
if (t.some((t) => t.ally_code === e.ally_code)) return;
|
|
305
|
-
t.push(e), localStorage.setItem(
|
|
309
|
+
t.push(e), localStorage.setItem(B, JSON.stringify(t));
|
|
306
310
|
} catch (e) {
|
|
307
311
|
console.error("Failed to save ally code to localStorage:", e);
|
|
308
312
|
}
|
|
309
|
-
},
|
|
313
|
+
}, U = (e) => {
|
|
310
314
|
try {
|
|
311
|
-
let t =
|
|
312
|
-
localStorage.setItem(
|
|
315
|
+
let t = H().filter((t) => t.ally_code !== e);
|
|
316
|
+
localStorage.setItem(B, JSON.stringify(t));
|
|
313
317
|
} catch (e) {
|
|
314
318
|
console.error("Failed to remove ally code from localStorage:", e);
|
|
315
319
|
}
|
|
316
|
-
},
|
|
320
|
+
}, W = (e) => {
|
|
317
321
|
try {
|
|
318
|
-
let t =
|
|
322
|
+
let t = H().map((t) => t.ally_code === e ? {
|
|
319
323
|
...t,
|
|
320
324
|
last_used_at: (/* @__PURE__ */ new Date()).toISOString()
|
|
321
325
|
} : t);
|
|
322
|
-
localStorage.setItem(
|
|
326
|
+
localStorage.setItem(B, JSON.stringify(t));
|
|
323
327
|
} catch (e) {
|
|
324
328
|
console.error("Failed to update ally code last used:", e);
|
|
325
329
|
}
|
|
326
|
-
},
|
|
327
|
-
e ? localStorage.setItem(
|
|
328
|
-
},
|
|
329
|
-
localStorage.removeItem(
|
|
330
|
-
},
|
|
330
|
+
}, ne = () => localStorage.getItem(V), G = (e) => {
|
|
331
|
+
e ? localStorage.setItem(V, e) : localStorage.removeItem(V);
|
|
332
|
+
}, re = () => {
|
|
333
|
+
localStorage.removeItem(B), localStorage.removeItem(V);
|
|
334
|
+
}, K = t(void 0), ie = ({ children: e, apiBaseUrl: t }) => {
|
|
331
335
|
let [r, o] = a(null), [c, l] = a(!0), [u, d] = a(!0), [f, p] = a(!0), [m, h] = a([]), [g, _] = a(null), [v, y] = a(!1), [b, x] = a({
|
|
332
336
|
show: !1,
|
|
333
337
|
localStorageCodes: []
|
|
334
338
|
});
|
|
335
339
|
i(() => {
|
|
336
|
-
|
|
340
|
+
z({ baseURL: t });
|
|
337
341
|
}, [t]), i(() => {
|
|
338
342
|
(async () => {
|
|
339
343
|
try {
|
|
340
|
-
d((await
|
|
344
|
+
d((await R.get("/api/v1/config/features")).auth_enabled);
|
|
341
345
|
} catch (e) {
|
|
342
346
|
console.error("Failed to fetch features:", e), d(!0);
|
|
343
347
|
} finally {
|
|
@@ -346,12 +350,12 @@ var x = "astrogators_access_token", S = "astrogators_refresh_token", C = () => l
|
|
|
346
350
|
})();
|
|
347
351
|
}, [t]);
|
|
348
352
|
let S = n(async () => {
|
|
349
|
-
if (!
|
|
353
|
+
if (!ee()) {
|
|
350
354
|
o(null), l(!1);
|
|
351
355
|
return;
|
|
352
356
|
}
|
|
353
357
|
try {
|
|
354
|
-
o(await
|
|
358
|
+
o(await R.get("/api/v1/users/me"));
|
|
355
359
|
} catch (e) {
|
|
356
360
|
console.error("Failed to fetch user:", e), o(null), A();
|
|
357
361
|
} finally {
|
|
@@ -363,14 +367,14 @@ var x = "astrogators_access_token", S = "astrogators_refresh_token", C = () => l
|
|
|
363
367
|
}, [S]);
|
|
364
368
|
let C = async (e) => {
|
|
365
369
|
try {
|
|
366
|
-
let t = await
|
|
367
|
-
k(t.access_token, t.refresh_token), o(await
|
|
370
|
+
let t = await R.post("/api/v1/auth/login", e);
|
|
371
|
+
k(t.access_token, t.refresh_token), o(await R.get("/api/v1/users/me"));
|
|
368
372
|
} catch (e) {
|
|
369
373
|
throw console.error("Login failed:", e), e;
|
|
370
374
|
}
|
|
371
375
|
}, w = async (e) => {
|
|
372
376
|
try {
|
|
373
|
-
await
|
|
377
|
+
await R.post("/api/v1/auth/register", e);
|
|
374
378
|
} catch (e) {
|
|
375
379
|
throw console.error("Registration failed:", e), e;
|
|
376
380
|
}
|
|
@@ -383,97 +387,97 @@ var x = "astrogators_access_token", S = "astrogators_refresh_token", C = () => l
|
|
|
383
387
|
await S();
|
|
384
388
|
}, D = async (e) => {
|
|
385
389
|
try {
|
|
386
|
-
return (await
|
|
390
|
+
return (await R.post("/api/v1/auth/forgot-password", e)).message;
|
|
387
391
|
} catch (e) {
|
|
388
392
|
throw console.error("Forgot password failed:", e), e;
|
|
389
393
|
}
|
|
390
394
|
}, O = async (e) => {
|
|
391
395
|
try {
|
|
392
|
-
return (await
|
|
396
|
+
return (await R.post("/api/v1/auth/reset-password", e)).message;
|
|
393
397
|
} catch (e) {
|
|
394
398
|
throw console.error("Reset password failed:", e), e;
|
|
395
399
|
}
|
|
396
|
-
},
|
|
400
|
+
}, j = async (e) => {
|
|
397
401
|
try {
|
|
398
|
-
return (await
|
|
402
|
+
return (await R.post("/api/v1/auth/resend-verification", e)).message;
|
|
399
403
|
} catch (e) {
|
|
400
404
|
throw console.error("Resend verification failed:", e), e;
|
|
401
405
|
}
|
|
402
|
-
},
|
|
406
|
+
}, M = n(async () => {
|
|
403
407
|
y(!0);
|
|
404
408
|
try {
|
|
405
409
|
if (r) {
|
|
406
|
-
h((await
|
|
407
|
-
let e =
|
|
410
|
+
h((await R.get("/api/v1/users/me/ally-codes")).ally_codes);
|
|
411
|
+
let e = H();
|
|
408
412
|
e.length > 0 && x({
|
|
409
413
|
show: !0,
|
|
410
414
|
localStorageCodes: e.map((e) => e.ally_code)
|
|
411
415
|
});
|
|
412
|
-
} else h(
|
|
413
|
-
_(
|
|
416
|
+
} else h(H());
|
|
417
|
+
_(ne());
|
|
414
418
|
} catch (e) {
|
|
415
419
|
console.error("Failed to fetch ally codes:", e), h([]);
|
|
416
420
|
} finally {
|
|
417
421
|
y(!1);
|
|
418
422
|
}
|
|
419
|
-
}, [r]),
|
|
420
|
-
r && typeof e == "number" ? (await
|
|
421
|
-
}, [r,
|
|
422
|
-
if (_(e),
|
|
423
|
+
}, [r]), N = n(async (e) => {
|
|
424
|
+
r && typeof e == "number" ? (await R.put(`/api/v1/users/me/ally-codes/${e}/use`, {}), await M()) : !r && typeof e == "string" && (W(e), h(H()));
|
|
425
|
+
}, [r, M]), P = n((e) => {
|
|
426
|
+
if (_(e), G(e), e && r) {
|
|
423
427
|
let t = m.find((t) => "ally_code" in t && t.ally_code === e);
|
|
424
|
-
t && "id" in t &&
|
|
425
|
-
} else e && !r &&
|
|
428
|
+
t && "id" in t && N(t.id);
|
|
429
|
+
} else e && !r && W(e);
|
|
426
430
|
}, [
|
|
427
431
|
r,
|
|
428
432
|
m,
|
|
429
|
-
|
|
430
|
-
]),
|
|
433
|
+
N
|
|
434
|
+
]), F = n(async (e) => {
|
|
431
435
|
if (!/^\d{9}$/.test(e)) throw Error("Ally code must be exactly 9 digits");
|
|
432
436
|
if (r) {
|
|
433
|
-
let t = await
|
|
434
|
-
h((e) => [t, ...e]), m.length === 0 &&
|
|
437
|
+
let t = await R.post("/api/v1/users/me/ally-codes", { ally_code: e });
|
|
438
|
+
h((e) => [t, ...e]), m.length === 0 && P(e);
|
|
435
439
|
} else {
|
|
436
|
-
let t = await
|
|
440
|
+
let t = await R.get(`/api/v1/player-data/player/${e}`);
|
|
437
441
|
if (!t) throw Error("Invalid ally code - player not found");
|
|
438
|
-
|
|
442
|
+
te({
|
|
439
443
|
ally_code: e,
|
|
440
444
|
player_name: t.data?.name ?? null,
|
|
441
445
|
last_used_at: (/* @__PURE__ */ new Date()).toISOString()
|
|
442
|
-
}), h(
|
|
446
|
+
}), h(H()), m.length === 0 && P(e);
|
|
443
447
|
}
|
|
444
448
|
}, [
|
|
445
449
|
r,
|
|
446
450
|
m.length,
|
|
447
|
-
|
|
448
|
-
]),
|
|
449
|
-
r && typeof e == "number" ? (await
|
|
451
|
+
P
|
|
452
|
+
]), I = n(async (e) => {
|
|
453
|
+
r && typeof e == "number" ? (await R.delete(`/api/v1/users/me/ally-codes/${e}`), h((t) => t.filter((t) => "id" in t && t.id !== e))) : !r && typeof e == "string" && (U(e), h(H()), g === e && P(null));
|
|
450
454
|
}, [
|
|
451
455
|
r,
|
|
452
456
|
g,
|
|
453
|
-
|
|
454
|
-
]),
|
|
457
|
+
P
|
|
458
|
+
]), L = n(() => {
|
|
455
459
|
x({
|
|
456
460
|
show: !1,
|
|
457
461
|
localStorageCodes: []
|
|
458
462
|
});
|
|
459
|
-
}, []),
|
|
463
|
+
}, []), B = n(async () => {
|
|
460
464
|
if (!r) return;
|
|
461
|
-
let e =
|
|
465
|
+
let e = H();
|
|
462
466
|
for (let t of e) try {
|
|
463
|
-
await
|
|
467
|
+
await F(t.ally_code);
|
|
464
468
|
} catch (e) {
|
|
465
469
|
console.error(`Failed to migrate ally code ${t.ally_code}:`, e);
|
|
466
470
|
}
|
|
467
|
-
|
|
471
|
+
re(), L();
|
|
468
472
|
}, [
|
|
469
473
|
r,
|
|
470
|
-
|
|
471
|
-
|
|
474
|
+
F,
|
|
475
|
+
L
|
|
472
476
|
]);
|
|
473
477
|
i(() => {
|
|
474
|
-
|
|
475
|
-
}, [
|
|
476
|
-
let
|
|
478
|
+
M();
|
|
479
|
+
}, [M]);
|
|
480
|
+
let V = {
|
|
477
481
|
user: r,
|
|
478
482
|
isAuthenticated: !!r,
|
|
479
483
|
isLoading: c,
|
|
@@ -483,30 +487,30 @@ var x = "astrogators_access_token", S = "astrogators_refresh_token", C = () => l
|
|
|
483
487
|
refreshUser: E,
|
|
484
488
|
forgotPassword: D,
|
|
485
489
|
resetPassword: O,
|
|
486
|
-
resendVerification:
|
|
490
|
+
resendVerification: j,
|
|
487
491
|
authEnabled: u,
|
|
488
492
|
isLoadingFeatures: f,
|
|
489
493
|
allyCodes: m,
|
|
490
494
|
selectedAllyCode: g,
|
|
491
495
|
isLoadingAllyCodes: v,
|
|
492
|
-
fetchAllyCodes:
|
|
493
|
-
addAllyCode:
|
|
494
|
-
removeAllyCode:
|
|
495
|
-
selectAllyCode:
|
|
496
|
-
updateAllyCodeLastUsed:
|
|
496
|
+
fetchAllyCodes: M,
|
|
497
|
+
addAllyCode: F,
|
|
498
|
+
removeAllyCode: I,
|
|
499
|
+
selectAllyCode: P,
|
|
500
|
+
updateAllyCodeLastUsed: N,
|
|
497
501
|
migrationPrompt: b,
|
|
498
|
-
dismissMigrationPrompt:
|
|
499
|
-
migrateLocalStorageCodes:
|
|
502
|
+
dismissMigrationPrompt: L,
|
|
503
|
+
migrateLocalStorageCodes: B
|
|
500
504
|
};
|
|
501
|
-
return /* @__PURE__ */ s(
|
|
502
|
-
value:
|
|
505
|
+
return /* @__PURE__ */ s(K.Provider, {
|
|
506
|
+
value: V,
|
|
503
507
|
children: e
|
|
504
508
|
});
|
|
505
|
-
},
|
|
506
|
-
let e = r(
|
|
509
|
+
}, q = () => {
|
|
510
|
+
let e = r(K);
|
|
507
511
|
if (e === void 0) throw Error("useAuth must be used within an AuthProvider");
|
|
508
512
|
return e;
|
|
509
|
-
},
|
|
513
|
+
}, J = (e) => !e || e.length !== 9 ? e : `${e.slice(0, 3)}-${e.slice(3, 6)}-${e.slice(6, 9)}`, ae = (e) => e.replace(/-/g, ""), Y = {
|
|
510
514
|
allyCodeDropdown: "_allyCodeDropdown_1m0tw_1",
|
|
511
515
|
select: "_select_1m0tw_8",
|
|
512
516
|
manageButton: "_manageButton_1m0tw_12",
|
|
@@ -518,10 +522,10 @@ var x = "astrogators_access_token", S = "astrogators_refresh_token", C = () => l
|
|
|
518
522
|
codesList: "_codesList_1m0tw_67",
|
|
519
523
|
codeItem: "_codeItem_1m0tw_71",
|
|
520
524
|
doneButton: "_doneButton_1m0tw_88"
|
|
521
|
-
},
|
|
522
|
-
let { allyCodes: n, selectedAllyCode: r, selectAllyCode: i, removeAllyCode: o, addAllyCode: l, isLoadingAllyCodes: u } =
|
|
525
|
+
}, oe = ({ onAllyCodeSelected: e, className: t = "" }) => {
|
|
526
|
+
let { allyCodes: n, selectedAllyCode: r, selectAllyCode: i, removeAllyCode: o, addAllyCode: l, isLoadingAllyCodes: u } = q(), [d, f] = a(!1), [p, m] = a(""), [h, _] = a(""), [y, x] = a(""), [S, C] = a(!1), w = n.map((e) => ({
|
|
523
527
|
value: e.ally_code,
|
|
524
|
-
label: e.player_name ? `${e.player_name} (${
|
|
528
|
+
label: e.player_name ? `${e.player_name} (${J(e.ally_code)})` : J(e.ally_code)
|
|
525
529
|
})), T = (t) => {
|
|
526
530
|
let n = t.target.value || null;
|
|
527
531
|
i(n), e?.(n);
|
|
@@ -591,7 +595,7 @@ var x = "astrogators_access_token", S = "astrogators_refresh_token", C = () => l
|
|
|
591
595
|
className: Y.codesList,
|
|
592
596
|
children: n.map((e) => /* @__PURE__ */ c("div", {
|
|
593
597
|
className: Y.codeItem,
|
|
594
|
-
children: [/* @__PURE__ */ s("span", { children: e.player_name ? `${e.player_name} (${
|
|
598
|
+
children: [/* @__PURE__ */ s("span", { children: e.player_name ? `${e.player_name} (${J(e.ally_code)})` : J(e.ally_code) }), /* @__PURE__ */ s(g, {
|
|
595
599
|
variant: "ghost",
|
|
596
600
|
size: "sm",
|
|
597
601
|
onClick: () => E(e.ally_code),
|
|
@@ -628,7 +632,7 @@ var x = "astrogators_access_token", S = "astrogators_refresh_token", C = () => l
|
|
|
628
632
|
"padding-md": "_padding-md_b4471_36",
|
|
629
633
|
"padding-lg": "_padding-lg_b4471_40",
|
|
630
634
|
hoverable: "_hoverable_b4471_45"
|
|
631
|
-
},
|
|
635
|
+
}, se = ({ children: e, variant: t = "default", chamfered: n = !1, chamferSize: r = "md", padding: i = "md", hoverable: a = !1, showDiagonalBorders: l = !1, diagonalBorderColor: u, className: d = "", onClick: f, style: p }) => {
|
|
632
636
|
let m = n ? r === "asymmetric" ? "chamfered-box-asymmetric" : r === "sm" ? "chamfered-box-sm" : r === "lg" ? "chamfered-box-lg" : "chamfered-box" : "", h = u ? { color: u } : void 0;
|
|
633
637
|
return /* @__PURE__ */ c("div", {
|
|
634
638
|
className: `${X.card} ${n ? X.chamfered : ""} ${X[t]} ${X[`padding-${i}`]} ${m} ${a ? X.hoverable : ""} ${d}`,
|
|
@@ -667,7 +671,7 @@ var x = "astrogators_access_token", S = "astrogators_refresh_token", C = () => l
|
|
|
667
671
|
warning: "_warning_rk7t5_47",
|
|
668
672
|
error: "_error_rk7t5_52",
|
|
669
673
|
info: "_info_rk7t5_57"
|
|
670
|
-
},
|
|
674
|
+
}, ce = ({ children: e, variant: t = "default", size: n = "md", className: r = "" }) => /* @__PURE__ */ s("span", {
|
|
671
675
|
className: `${Z.badge} ${Z[t]} ${Z[n]} ${r}`,
|
|
672
676
|
children: e
|
|
673
677
|
}), Q = {
|
|
@@ -683,7 +687,7 @@ var x = "astrogators_access_token", S = "astrogators_refresh_token", C = () => l
|
|
|
683
687
|
title: "_title_1b3yt_53",
|
|
684
688
|
closeButton: "_closeButton_1b3yt_60",
|
|
685
689
|
content: "_content_1b3yt_78"
|
|
686
|
-
},
|
|
690
|
+
}, le = ({ isOpen: e, onClose: t, title: n, children: r, size: a = "md", closeOnOverlayClick: o = !0, className: l = "" }) => (i(() => (e ? document.body.style.overflow = "hidden" : document.body.style.overflow = "unset", () => {
|
|
687
691
|
document.body.style.overflow = "unset";
|
|
688
692
|
}), [e]), i(() => {
|
|
689
693
|
let n = (n) => {
|
|
@@ -725,7 +729,7 @@ var x = "astrogators_access_token", S = "astrogators_refresh_token", C = () => l
|
|
|
725
729
|
dot: "_dot_1uhnh_34",
|
|
726
730
|
bounce: "_bounce_1uhnh_1",
|
|
727
731
|
visuallyHidden: "_visuallyHidden_1uhnh_91"
|
|
728
|
-
},
|
|
732
|
+
}, ue = ({ size: e = "md", variant: t = "spinner", className: n = "" }) => t === "dots" ? /* @__PURE__ */ c("div", {
|
|
729
733
|
className: `${$.dots} ${$[e]} ${n}`,
|
|
730
734
|
children: [
|
|
731
735
|
/* @__PURE__ */ s("span", { className: $.dot }),
|
|
@@ -741,4 +745,4 @@ var x = "astrogators_access_token", S = "astrogators_refresh_token", C = () => l
|
|
|
741
745
|
})
|
|
742
746
|
});
|
|
743
747
|
//#endregion
|
|
744
|
-
export {
|
|
748
|
+
export { oe as AllyCodeDropdown, L as ApiClient, ie as AuthProvider, ce as Badge, g as Button, se as Card, u as Container, m as Footer, v as Input, ue as Loader, le as Modal, b as Select, f as TopBar, R as apiClient, I as authedFetch, re as clearAllyCodes, A as clearTokens, P as configureAuthRefresh, J as formatAllyCode, C as getAccessToken, H as getAllyCodesFromStorage, E as getRefreshToken, ne as getSelectedAllyCode, z as initializeApiClient, ee as isAuthenticated, F as refreshAccessToken, T as removeAccessToken, U as removeAllyCodeFromStorage, O as removeRefreshToken, te as saveAllyCodeToStorage, w as setAccessToken, D as setRefreshToken, G as setSelectedAllyCode, k as setTokens, ae as unformatAllyCode, W as updateAllyCodeLastUsed, q as useAuth };
|
package/dist/src/index.d.ts
CHANGED
|
@@ -10,6 +10,8 @@ export { AuthProvider, useAuth } from './contexts/AuthContext';
|
|
|
10
10
|
export type { AuthContextValue, AuthProviderProps } from './contexts/AuthContext';
|
|
11
11
|
export { ApiClient, apiClient, initializeApiClient } from './services/api';
|
|
12
12
|
export type { ApiClientConfig } from './services/api';
|
|
13
|
+
export { authedFetch, refreshAccessToken, configureAuthRefresh, } from './services/tokenRefresh';
|
|
14
|
+
export type { AuthRefreshConfig } from './services/tokenRefresh';
|
|
13
15
|
export { getAccessToken, setAccessToken, removeAccessToken, getRefreshToken, setRefreshToken, removeRefreshToken, setTokens, clearTokens, isAuthenticated, } from './services/auth';
|
|
14
16
|
export { getAllyCodesFromStorage, saveAllyCodeToStorage, removeAllyCodeFromStorage, updateAllyCodeLastUsed, getSelectedAllyCode, setSelectedAllyCode, clearAllyCodes, } from './services/allyCodeStorage';
|
|
15
17
|
export type { StoredAllyCode } from './services/allyCodeStorage';
|
|
@@ -1,6 +1,12 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* API Client
|
|
3
|
-
* HTTP client with JWT token injection and automatic refresh
|
|
3
|
+
* HTTP client with JWT token injection and automatic refresh.
|
|
4
|
+
*
|
|
5
|
+
* Token injection + refresh-and-retry are delegated to the shared
|
|
6
|
+
* `authedFetch` primitive (services/tokenRefresh) so there is ONE refresh
|
|
7
|
+
* implementation across the app, and any service-specific client (with its
|
|
8
|
+
* own base URL) can reuse it. This class is the convenience layer on top:
|
|
9
|
+
* base-URL joining, JSON encoding, and structured error parsing.
|
|
4
10
|
*/
|
|
5
11
|
export interface ApiClientConfig {
|
|
6
12
|
baseURL: string;
|
|
@@ -8,11 +14,7 @@ export interface ApiClientConfig {
|
|
|
8
14
|
}
|
|
9
15
|
export declare class ApiClient {
|
|
10
16
|
private baseURL;
|
|
11
|
-
private onUnauthorized?;
|
|
12
|
-
private isRefreshing;
|
|
13
|
-
private refreshPromise;
|
|
14
17
|
constructor(config: ApiClientConfig);
|
|
15
|
-
private refreshAccessToken;
|
|
16
18
|
request<T>(endpoint: string, options?: RequestInit): Promise<T>;
|
|
17
19
|
get<T>(endpoint: string, options?: RequestInit): Promise<T>;
|
|
18
20
|
post<T>(endpoint: string, data?: unknown, options?: RequestInit): Promise<T>;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
export interface AuthRefreshConfig {
|
|
2
|
+
baseURL: string;
|
|
3
|
+
onUnauthorized?: () => void;
|
|
4
|
+
}
|
|
5
|
+
/** Point the refresh primitive at the auth service. Idempotent. */
|
|
6
|
+
export declare const configureAuthRefresh: (config: AuthRefreshConfig) => void;
|
|
7
|
+
/**
|
|
8
|
+
* Exchange the stored refresh token for a fresh access token. Concurrent
|
|
9
|
+
* callers share one in-flight request. On failure the tokens are cleared and
|
|
10
|
+
* `onUnauthorized` fires, then the error propagates.
|
|
11
|
+
*/
|
|
12
|
+
export declare const refreshAccessToken: () => Promise<string>;
|
|
13
|
+
/**
|
|
14
|
+
* `fetch` that injects the current bearer token and, on a 401 from an
|
|
15
|
+
* authenticated request, refreshes the token once and retries.
|
|
16
|
+
*
|
|
17
|
+
* Returns the final Response — it does NOT throw on non-2xx, so callers keep
|
|
18
|
+
* full control over status handling (mirrors the raw `fetch` contract). When a
|
|
19
|
+
* refresh is needed but fails (e.g. the refresh token is also expired), the
|
|
20
|
+
* original 401 Response is returned so the caller can surface a re-login state.
|
|
21
|
+
*
|
|
22
|
+
* Works against ANY resource URL; only the refresh hop uses the configured
|
|
23
|
+
* auth base URL.
|
|
24
|
+
*/
|
|
25
|
+
export declare const authedFetch: (input: string, init?: RequestInit) => Promise<Response>;
|