astrogators-shared-ui 0.7.0-rc.1 → 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/README.md +29 -30
- package/dist/index.css +1 -1
- package/dist/index.js +139 -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/dist/src/types/user.d.ts +2 -0
- package/package.json +2 -5
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-token`, {
|
|
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, e), 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,85 +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]),
|
|
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) {
|
|
427
|
+
let t = m.find((t) => "ally_code" in t && t.ally_code === e);
|
|
428
|
+
t && "id" in t && N(t.id);
|
|
429
|
+
} else e && !r && W(e);
|
|
430
|
+
}, [
|
|
431
|
+
r,
|
|
432
|
+
m,
|
|
433
|
+
N
|
|
434
|
+
]), F = n(async (e) => {
|
|
420
435
|
if (!/^\d{9}$/.test(e)) throw Error("Ally code must be exactly 9 digits");
|
|
421
436
|
if (r) {
|
|
422
|
-
let t = await
|
|
423
|
-
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);
|
|
424
439
|
} else {
|
|
425
|
-
let t = await
|
|
440
|
+
let t = await R.get(`/api/v1/player-data/player/${e}`);
|
|
426
441
|
if (!t) throw Error("Invalid ally code - player not found");
|
|
427
|
-
|
|
442
|
+
te({
|
|
428
443
|
ally_code: e,
|
|
429
|
-
player_name: t
|
|
444
|
+
player_name: t.data?.name ?? null,
|
|
430
445
|
last_used_at: (/* @__PURE__ */ new Date()).toISOString()
|
|
431
|
-
}), h(
|
|
446
|
+
}), h(H()), m.length === 0 && P(e);
|
|
432
447
|
}
|
|
433
|
-
}, [
|
|
434
|
-
r
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
448
|
+
}, [
|
|
449
|
+
r,
|
|
450
|
+
m.length,
|
|
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));
|
|
454
|
+
}, [
|
|
455
|
+
r,
|
|
456
|
+
g,
|
|
457
|
+
P
|
|
458
|
+
]), L = n(() => {
|
|
443
459
|
x({
|
|
444
460
|
show: !1,
|
|
445
461
|
localStorageCodes: []
|
|
446
462
|
});
|
|
447
|
-
}, []),
|
|
463
|
+
}, []), B = n(async () => {
|
|
448
464
|
if (!r) return;
|
|
449
|
-
let e =
|
|
465
|
+
let e = H();
|
|
450
466
|
for (let t of e) try {
|
|
451
|
-
await
|
|
467
|
+
await F(t.ally_code);
|
|
452
468
|
} catch (e) {
|
|
453
469
|
console.error(`Failed to migrate ally code ${t.ally_code}:`, e);
|
|
454
470
|
}
|
|
455
|
-
|
|
471
|
+
re(), L();
|
|
456
472
|
}, [
|
|
457
473
|
r,
|
|
458
|
-
|
|
459
|
-
|
|
474
|
+
F,
|
|
475
|
+
L
|
|
460
476
|
]);
|
|
461
477
|
i(() => {
|
|
462
|
-
|
|
463
|
-
}, [
|
|
464
|
-
let
|
|
478
|
+
M();
|
|
479
|
+
}, [M]);
|
|
480
|
+
let V = {
|
|
465
481
|
user: r,
|
|
466
482
|
isAuthenticated: !!r,
|
|
467
483
|
isLoading: c,
|
|
@@ -471,30 +487,30 @@ var x = "astrogators_access_token", S = "astrogators_refresh_token", C = () => l
|
|
|
471
487
|
refreshUser: E,
|
|
472
488
|
forgotPassword: D,
|
|
473
489
|
resetPassword: O,
|
|
474
|
-
resendVerification:
|
|
490
|
+
resendVerification: j,
|
|
475
491
|
authEnabled: u,
|
|
476
492
|
isLoadingFeatures: f,
|
|
477
493
|
allyCodes: m,
|
|
478
494
|
selectedAllyCode: g,
|
|
479
495
|
isLoadingAllyCodes: v,
|
|
480
|
-
fetchAllyCodes:
|
|
481
|
-
addAllyCode:
|
|
482
|
-
removeAllyCode:
|
|
483
|
-
selectAllyCode:
|
|
484
|
-
updateAllyCodeLastUsed:
|
|
496
|
+
fetchAllyCodes: M,
|
|
497
|
+
addAllyCode: F,
|
|
498
|
+
removeAllyCode: I,
|
|
499
|
+
selectAllyCode: P,
|
|
500
|
+
updateAllyCodeLastUsed: N,
|
|
485
501
|
migrationPrompt: b,
|
|
486
|
-
dismissMigrationPrompt:
|
|
487
|
-
migrateLocalStorageCodes:
|
|
502
|
+
dismissMigrationPrompt: L,
|
|
503
|
+
migrateLocalStorageCodes: B
|
|
488
504
|
};
|
|
489
|
-
return /* @__PURE__ */ s(
|
|
490
|
-
value:
|
|
505
|
+
return /* @__PURE__ */ s(K.Provider, {
|
|
506
|
+
value: V,
|
|
491
507
|
children: e
|
|
492
508
|
});
|
|
493
|
-
},
|
|
494
|
-
let e = r(
|
|
509
|
+
}, q = () => {
|
|
510
|
+
let e = r(K);
|
|
495
511
|
if (e === void 0) throw Error("useAuth must be used within an AuthProvider");
|
|
496
512
|
return e;
|
|
497
|
-
},
|
|
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 = {
|
|
498
514
|
allyCodeDropdown: "_allyCodeDropdown_1m0tw_1",
|
|
499
515
|
select: "_select_1m0tw_8",
|
|
500
516
|
manageButton: "_manageButton_1m0tw_12",
|
|
@@ -506,10 +522,10 @@ var x = "astrogators_access_token", S = "astrogators_refresh_token", C = () => l
|
|
|
506
522
|
codesList: "_codesList_1m0tw_67",
|
|
507
523
|
codeItem: "_codeItem_1m0tw_71",
|
|
508
524
|
doneButton: "_doneButton_1m0tw_88"
|
|
509
|
-
},
|
|
510
|
-
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) => ({
|
|
511
527
|
value: e.ally_code,
|
|
512
|
-
label: e.player_name ? `${e.player_name} (${
|
|
528
|
+
label: e.player_name ? `${e.player_name} (${J(e.ally_code)})` : J(e.ally_code)
|
|
513
529
|
})), T = (t) => {
|
|
514
530
|
let n = t.target.value || null;
|
|
515
531
|
i(n), e?.(n);
|
|
@@ -579,7 +595,7 @@ var x = "astrogators_access_token", S = "astrogators_refresh_token", C = () => l
|
|
|
579
595
|
className: Y.codesList,
|
|
580
596
|
children: n.map((e) => /* @__PURE__ */ c("div", {
|
|
581
597
|
className: Y.codeItem,
|
|
582
|
-
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, {
|
|
583
599
|
variant: "ghost",
|
|
584
600
|
size: "sm",
|
|
585
601
|
onClick: () => E(e.ally_code),
|
|
@@ -616,7 +632,7 @@ var x = "astrogators_access_token", S = "astrogators_refresh_token", C = () => l
|
|
|
616
632
|
"padding-md": "_padding-md_b4471_36",
|
|
617
633
|
"padding-lg": "_padding-lg_b4471_40",
|
|
618
634
|
hoverable: "_hoverable_b4471_45"
|
|
619
|
-
},
|
|
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 }) => {
|
|
620
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;
|
|
621
637
|
return /* @__PURE__ */ c("div", {
|
|
622
638
|
className: `${X.card} ${n ? X.chamfered : ""} ${X[t]} ${X[`padding-${i}`]} ${m} ${a ? X.hoverable : ""} ${d}`,
|
|
@@ -638,7 +654,7 @@ var x = "astrogators_access_token", S = "astrogators_refresh_token", C = () => l
|
|
|
638
654
|
style: h
|
|
639
655
|
}),
|
|
640
656
|
/* @__PURE__ */ s("div", {
|
|
641
|
-
className:
|
|
657
|
+
className: "chamfered-diagonal-border chamfered-diagonal-br",
|
|
642
658
|
style: h
|
|
643
659
|
})
|
|
644
660
|
] }), e]
|
|
@@ -655,7 +671,7 @@ var x = "astrogators_access_token", S = "astrogators_refresh_token", C = () => l
|
|
|
655
671
|
warning: "_warning_rk7t5_47",
|
|
656
672
|
error: "_error_rk7t5_52",
|
|
657
673
|
info: "_info_rk7t5_57"
|
|
658
|
-
},
|
|
674
|
+
}, ce = ({ children: e, variant: t = "default", size: n = "md", className: r = "" }) => /* @__PURE__ */ s("span", {
|
|
659
675
|
className: `${Z.badge} ${Z[t]} ${Z[n]} ${r}`,
|
|
660
676
|
children: e
|
|
661
677
|
}), Q = {
|
|
@@ -671,7 +687,7 @@ var x = "astrogators_access_token", S = "astrogators_refresh_token", C = () => l
|
|
|
671
687
|
title: "_title_1b3yt_53",
|
|
672
688
|
closeButton: "_closeButton_1b3yt_60",
|
|
673
689
|
content: "_content_1b3yt_78"
|
|
674
|
-
},
|
|
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", () => {
|
|
675
691
|
document.body.style.overflow = "unset";
|
|
676
692
|
}), [e]), i(() => {
|
|
677
693
|
let n = (n) => {
|
|
@@ -713,7 +729,7 @@ var x = "astrogators_access_token", S = "astrogators_refresh_token", C = () => l
|
|
|
713
729
|
dot: "_dot_1uhnh_34",
|
|
714
730
|
bounce: "_bounce_1uhnh_1",
|
|
715
731
|
visuallyHidden: "_visuallyHidden_1uhnh_91"
|
|
716
|
-
},
|
|
732
|
+
}, ue = ({ size: e = "md", variant: t = "spinner", className: n = "" }) => t === "dots" ? /* @__PURE__ */ c("div", {
|
|
717
733
|
className: `${$.dots} ${$[e]} ${n}`,
|
|
718
734
|
children: [
|
|
719
735
|
/* @__PURE__ */ s("span", { className: $.dot }),
|
|
@@ -729,4 +745,4 @@ var x = "astrogators_access_token", S = "astrogators_refresh_token", C = () => l
|
|
|
729
745
|
})
|
|
730
746
|
});
|
|
731
747
|
//#endregion
|
|
732
|
-
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>;
|
package/dist/src/types/user.d.ts
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "astrogators-shared-ui",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.8.0",
|
|
4
4
|
"description": "Shared UI components and utilities for Astrogator's Table applications",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -51,8 +51,5 @@
|
|
|
51
51
|
"vite": "^8.0.9",
|
|
52
52
|
"vite-plugin-dts": "^4.5.4"
|
|
53
53
|
},
|
|
54
|
-
"dependencies": {
|
|
55
|
-
"@fontsource-variable/inter-tight": "^5.2.7",
|
|
56
|
-
"@fontsource/michroma": "^5.2.8"
|
|
57
|
-
}
|
|
54
|
+
"dependencies": {}
|
|
58
55
|
}
|