astrogators-shared-ui 0.16.3 → 0.16.4
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/LICENSE +21 -0
- package/README.md +11 -4
- package/dist/index.js +255 -239
- package/package.json +8 -6
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 psytor
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
# astrogators-shared-ui
|
|
2
2
|
|
|
3
3
|
Shared React components, auth, and API client for the Astrogator's Table
|
|
4
|
-
frontends (`astrogators-hub`, `mod-ledger-ui`, `nightwatcher-ui
|
|
5
|
-
to the public npm registry as
|
|
4
|
+
frontends (`astrogators-hub`, `mod-ledger-ui`, `nightwatcher-ui`,
|
|
5
|
+
`navicharts-ui`). Published to the public npm registry as
|
|
6
|
+
`astrogators-shared-ui` (unscoped).
|
|
6
7
|
|
|
7
8
|
> The git repo lives under `psytor/astrogators-shared-ui` on GitHub, but the
|
|
8
9
|
> package itself is published to **npmjs.org**, not GitHub Packages. No
|
|
@@ -177,9 +178,14 @@ const result = await apiClient.post('/api/v1/mod-ledger/evaluate/123456789', {
|
|
|
177
178
|
|
|
178
179
|
The client:
|
|
179
180
|
- injects the access token into `Authorization`
|
|
180
|
-
-
|
|
181
|
-
|
|
181
|
+
- proactively refreshes before a request goes out if the access token is
|
|
182
|
+
expired or expiring within 30s (decoded client-side), and reactively on a
|
|
183
|
+
`401` from the resource server — both via `/api/v1/auth/refresh`, retrying
|
|
184
|
+
the original request once
|
|
182
185
|
- calls `onUnauthorized` if refresh fails
|
|
186
|
+
- retries a `502`/`503`/`504` response (idempotent methods only) or a thrown
|
|
187
|
+
`fetch` (any method, since nothing reached the server) a couple of times
|
|
188
|
+
with a short backoff, to ride out a backend container swap mid-deploy
|
|
183
189
|
|
|
184
190
|
Endpoints are written **without** the service prefix — the prefix lives in
|
|
185
191
|
the configured `baseURL`.
|
|
@@ -254,6 +260,7 @@ Sci-fi cut-corner effect, available as utility classes or via `Card`:
|
|
|
254
260
|
npm install
|
|
255
261
|
npm run build # tsc && vite build → dist/
|
|
256
262
|
npm run type-check # tsc --noEmit
|
|
263
|
+
npm test # vitest run — logic tests in tests/ (not visual)
|
|
257
264
|
```
|
|
258
265
|
|
|
259
266
|
There is no `dev` server worth running (this is a library, not an app).
|
package/dist/index.js
CHANGED
|
@@ -140,12 +140,12 @@ var _ = [
|
|
|
140
140
|
x(e), w(t);
|
|
141
141
|
}, D = () => {
|
|
142
142
|
S(), T();
|
|
143
|
-
},
|
|
144
|
-
|
|
145
|
-
},
|
|
143
|
+
}, ee = () => !!b(), O = "", k, A = null, j = (e) => {
|
|
144
|
+
O = e.baseURL, k = e.onUnauthorized;
|
|
145
|
+
}, M = () => A || (A = (async () => {
|
|
146
146
|
let e = C();
|
|
147
147
|
if (!e) throw Error("No refresh token available");
|
|
148
|
-
let t = await fetch(`${
|
|
148
|
+
let t = await fetch(`${O}/api/v1/auth/refresh`, {
|
|
149
149
|
method: "POST",
|
|
150
150
|
headers: { "Content-Type": "application/json" },
|
|
151
151
|
body: JSON.stringify({ refresh_token: e })
|
|
@@ -155,21 +155,21 @@ var _ = [
|
|
|
155
155
|
return E(n.access_token, n.refresh_token), n.access_token;
|
|
156
156
|
})().finally(() => {
|
|
157
157
|
A = null;
|
|
158
|
-
}), A),
|
|
158
|
+
}), A), N = 30, P = [700, 1500], F = /* @__PURE__ */ new Set([
|
|
159
159
|
502,
|
|
160
160
|
503,
|
|
161
161
|
504
|
|
162
|
-
]),
|
|
162
|
+
]), te = (e) => {
|
|
163
163
|
let t = (e ?? "GET").toUpperCase();
|
|
164
164
|
return t === "GET" || t === "HEAD" || t === "OPTIONS";
|
|
165
|
-
},
|
|
166
|
-
let n =
|
|
167
|
-
for (let a = 0; a <=
|
|
168
|
-
a > 0 && await
|
|
169
|
-
let o = a <
|
|
165
|
+
}, I = (e) => e == null || typeof e == "string", ne = (e) => new Promise((t) => setTimeout(t, e)), re = async (e, t) => {
|
|
166
|
+
let n = te(t.method) && I(t.body), r = I(t.body), i;
|
|
167
|
+
for (let a = 0; a <= P.length; a++) {
|
|
168
|
+
a > 0 && await ne(P[a - 1]);
|
|
169
|
+
let o = a < P.length;
|
|
170
170
|
try {
|
|
171
171
|
let r = await fetch(e, t);
|
|
172
|
-
if (o && n &&
|
|
172
|
+
if (o && n && F.has(r.status)) continue;
|
|
173
173
|
return r;
|
|
174
174
|
} catch (e) {
|
|
175
175
|
if (i = e, o && r) continue;
|
|
@@ -177,39 +177,39 @@ var _ = [
|
|
|
177
177
|
}
|
|
178
178
|
}
|
|
179
179
|
throw i ?? /* @__PURE__ */ Error("fetchWithRetry: retries exhausted");
|
|
180
|
-
},
|
|
180
|
+
}, ie = (e) => {
|
|
181
181
|
try {
|
|
182
182
|
let t = e.split(".")[1].replace(/-/g, "+").replace(/_/g, "/"), { exp: n } = JSON.parse(atob(t));
|
|
183
|
-
return typeof n == "number" && Date.now() / 1e3 >= n -
|
|
183
|
+
return typeof n == "number" && Date.now() / 1e3 >= n - N;
|
|
184
184
|
} catch {
|
|
185
185
|
return !1;
|
|
186
186
|
}
|
|
187
|
-
},
|
|
187
|
+
}, ae = async (e, t = {}) => {
|
|
188
188
|
let n = b();
|
|
189
|
-
if (n &&
|
|
190
|
-
n = await
|
|
189
|
+
if (n && ie(n)) try {
|
|
190
|
+
n = await M();
|
|
191
191
|
} catch {
|
|
192
192
|
n = b();
|
|
193
193
|
}
|
|
194
194
|
let r = { ...t.headers };
|
|
195
195
|
n && (r.Authorization = `Bearer ${n}`);
|
|
196
|
-
let i = await
|
|
196
|
+
let i = await re(e, {
|
|
197
197
|
...t,
|
|
198
198
|
headers: r
|
|
199
199
|
});
|
|
200
200
|
if (i.status !== 401 || !n) return i;
|
|
201
201
|
try {
|
|
202
|
-
return r.Authorization = `Bearer ${await
|
|
202
|
+
return r.Authorization = `Bearer ${await M()}`, await re(e, {
|
|
203
203
|
...t,
|
|
204
204
|
headers: r
|
|
205
205
|
});
|
|
206
206
|
} catch {
|
|
207
207
|
return i;
|
|
208
208
|
}
|
|
209
|
-
},
|
|
209
|
+
}, oe = class {
|
|
210
210
|
baseURL;
|
|
211
211
|
constructor(e) {
|
|
212
|
-
this.baseURL = e.baseURL,
|
|
212
|
+
this.baseURL = e.baseURL, j({
|
|
213
213
|
baseURL: e.baseURL,
|
|
214
214
|
onUnauthorized: e.onUnauthorized
|
|
215
215
|
});
|
|
@@ -218,7 +218,7 @@ var _ = [
|
|
|
218
218
|
let n = {
|
|
219
219
|
"Content-Type": "application/json",
|
|
220
220
|
...t.headers
|
|
221
|
-
}, r = await
|
|
221
|
+
}, r = await ae(`${this.baseURL}${e}`, {
|
|
222
222
|
...t,
|
|
223
223
|
headers: n
|
|
224
224
|
});
|
|
@@ -268,53 +268,54 @@ var _ = [
|
|
|
268
268
|
method: "DELETE"
|
|
269
269
|
});
|
|
270
270
|
}
|
|
271
|
-
},
|
|
272
|
-
|
|
273
|
-
},
|
|
271
|
+
}, L, se = (e) => {
|
|
272
|
+
L = new oe(e);
|
|
273
|
+
}, R = "astrogators_ally_codes", ce = "astrogators_selected_ally_code", z = () => {
|
|
274
274
|
try {
|
|
275
|
-
let e = localStorage.getItem(
|
|
275
|
+
let e = localStorage.getItem(R);
|
|
276
276
|
return e ? JSON.parse(e) : [];
|
|
277
277
|
} catch (e) {
|
|
278
278
|
return console.error("Failed to read ally codes from localStorage:", e), [];
|
|
279
279
|
}
|
|
280
|
-
},
|
|
280
|
+
}, le = (e) => {
|
|
281
281
|
try {
|
|
282
|
-
let t =
|
|
282
|
+
let t = z();
|
|
283
283
|
if (t.some((t) => t.ally_code === e.ally_code)) return;
|
|
284
|
-
t.push(e), localStorage.setItem(
|
|
284
|
+
t.push(e), localStorage.setItem(R, JSON.stringify(t));
|
|
285
285
|
} catch (e) {
|
|
286
286
|
console.error("Failed to save ally code to localStorage:", e);
|
|
287
287
|
}
|
|
288
|
-
},
|
|
288
|
+
}, ue = (e) => {
|
|
289
289
|
try {
|
|
290
|
-
let t =
|
|
291
|
-
localStorage.setItem(
|
|
290
|
+
let t = z().filter((t) => t.ally_code !== e);
|
|
291
|
+
localStorage.setItem(R, JSON.stringify(t));
|
|
292
292
|
} catch (e) {
|
|
293
293
|
console.error("Failed to remove ally code from localStorage:", e);
|
|
294
294
|
}
|
|
295
|
-
},
|
|
295
|
+
}, de = (e) => {
|
|
296
296
|
try {
|
|
297
|
-
let t =
|
|
297
|
+
let t = z().map((t) => t.ally_code === e ? {
|
|
298
298
|
...t,
|
|
299
299
|
last_used_at: (/* @__PURE__ */ new Date()).toISOString()
|
|
300
300
|
} : t);
|
|
301
|
-
localStorage.setItem(
|
|
301
|
+
localStorage.setItem(R, JSON.stringify(t));
|
|
302
302
|
} catch (e) {
|
|
303
303
|
console.error("Failed to update ally code last used:", e);
|
|
304
304
|
}
|
|
305
|
-
},
|
|
306
|
-
e ? localStorage.setItem(
|
|
307
|
-
},
|
|
308
|
-
localStorage.removeItem(
|
|
309
|
-
},
|
|
305
|
+
}, fe = () => localStorage.getItem(ce), B = (e) => {
|
|
306
|
+
e ? localStorage.setItem(ce, e) : localStorage.removeItem(ce);
|
|
307
|
+
}, pe = () => {
|
|
308
|
+
localStorage.removeItem(R), localStorage.removeItem(ce);
|
|
309
|
+
}, me = t(void 0), he = ({ children: e, apiBaseUrl: t }) => {
|
|
310
310
|
let [n, i] = s(null), [o, c] = s(!0), [u, d] = s(!0), [f, p] = s(!0), [m, h] = s([]), [g, _] = s(null), [v, y] = s(!1), [b, x] = s({
|
|
311
311
|
show: !1,
|
|
312
312
|
localStorageCodes: []
|
|
313
313
|
});
|
|
314
|
-
|
|
314
|
+
se({ baseURL: t }), a(() => {
|
|
315
315
|
(async () => {
|
|
316
316
|
try {
|
|
317
|
-
|
|
317
|
+
let e = await L.get("/api/v1/config/features");
|
|
318
|
+
d(e.auth_enabled);
|
|
318
319
|
} catch (e) {
|
|
319
320
|
console.error("Failed to fetch features:", e), d(!0);
|
|
320
321
|
} finally {
|
|
@@ -323,12 +324,13 @@ var _ = [
|
|
|
323
324
|
})();
|
|
324
325
|
}, [t]);
|
|
325
326
|
let S = r(async () => {
|
|
326
|
-
if (!
|
|
327
|
+
if (!ee()) {
|
|
327
328
|
i(null), c(!1);
|
|
328
329
|
return;
|
|
329
330
|
}
|
|
330
331
|
try {
|
|
331
|
-
|
|
332
|
+
let e = await L.get("/api/v1/users/me");
|
|
333
|
+
i(e);
|
|
332
334
|
} catch (e) {
|
|
333
335
|
console.error("Failed to fetch user:", e), i(null), D();
|
|
334
336
|
} finally {
|
|
@@ -340,159 +342,161 @@ var _ = [
|
|
|
340
342
|
}, [S]);
|
|
341
343
|
let C = async (e) => {
|
|
342
344
|
try {
|
|
343
|
-
let t = await
|
|
344
|
-
E(t.access_token, t.refresh_token)
|
|
345
|
+
let t = await L.post("/api/v1/auth/login", e);
|
|
346
|
+
E(t.access_token, t.refresh_token);
|
|
347
|
+
let n = await L.get("/api/v1/users/me");
|
|
348
|
+
i(n);
|
|
345
349
|
} catch (e) {
|
|
346
350
|
throw console.error("Login failed:", e), e;
|
|
347
351
|
}
|
|
348
352
|
}, w = async (e) => {
|
|
349
353
|
try {
|
|
350
|
-
await
|
|
354
|
+
await L.post("/api/v1/auth/register", e);
|
|
351
355
|
} catch (e) {
|
|
352
356
|
throw console.error("Registration failed:", e), e;
|
|
353
357
|
}
|
|
354
358
|
}, T = () => {
|
|
355
|
-
D(), i(null), h([]), _(null),
|
|
359
|
+
D(), i(null), h([]), _(null), B(null), x({
|
|
356
360
|
show: !1,
|
|
357
361
|
localStorageCodes: []
|
|
358
362
|
});
|
|
359
|
-
},
|
|
363
|
+
}, O = async () => {
|
|
360
364
|
await S();
|
|
361
365
|
}, k = async (e) => {
|
|
362
366
|
try {
|
|
363
|
-
return (await
|
|
367
|
+
return (await L.post("/api/v1/auth/forgot-password", e)).message;
|
|
364
368
|
} catch (e) {
|
|
365
369
|
throw console.error("Forgot password failed:", e), e;
|
|
366
370
|
}
|
|
367
371
|
}, A = async (e) => {
|
|
368
372
|
try {
|
|
369
|
-
return (await
|
|
373
|
+
return (await L.post("/api/v1/auth/reset-password", e)).message;
|
|
370
374
|
} catch (e) {
|
|
371
375
|
throw console.error("Reset password failed:", e), e;
|
|
372
376
|
}
|
|
373
|
-
},
|
|
377
|
+
}, j = async (e) => {
|
|
374
378
|
try {
|
|
375
|
-
return (await
|
|
379
|
+
return (await L.post("/api/v1/auth/resend-verification", e)).message;
|
|
376
380
|
} catch (e) {
|
|
377
381
|
throw console.error("Resend verification failed:", e), e;
|
|
378
382
|
}
|
|
379
|
-
},
|
|
383
|
+
}, M = r(async () => {
|
|
380
384
|
y(!0);
|
|
381
385
|
try {
|
|
382
386
|
let e = [];
|
|
383
387
|
if (n) {
|
|
384
|
-
let t = await
|
|
388
|
+
let t = await L.get("/api/v1/users/me/ally-codes");
|
|
385
389
|
h(t.ally_codes), e = t.ally_codes.map((e) => e.ally_code);
|
|
386
|
-
let n =
|
|
390
|
+
let n = z();
|
|
387
391
|
n.length > 0 && x({
|
|
388
392
|
show: !0,
|
|
389
393
|
localStorageCodes: n.map((e) => e.ally_code)
|
|
390
394
|
});
|
|
391
395
|
} else {
|
|
392
|
-
let t =
|
|
396
|
+
let t = z();
|
|
393
397
|
h(t), e = t.map((e) => e.ally_code);
|
|
394
398
|
}
|
|
395
|
-
let t =
|
|
396
|
-
_(r), r !== t &&
|
|
399
|
+
let t = fe(), r = t && e.includes(t) ? t : null;
|
|
400
|
+
_(r), r !== t && B(r);
|
|
397
401
|
} catch (e) {
|
|
398
402
|
console.error("Failed to fetch ally codes:", e), h([]);
|
|
399
403
|
} finally {
|
|
400
404
|
y(!1);
|
|
401
405
|
}
|
|
402
|
-
}, [n]),
|
|
403
|
-
n && typeof e == "number" ? (await
|
|
404
|
-
}, [n,
|
|
405
|
-
if (_(e),
|
|
406
|
+
}, [n]), N = r(async (e) => {
|
|
407
|
+
n && typeof e == "number" ? (await L.put(`/api/v1/users/me/ally-codes/${e}/use`, {}), await M()) : !n && typeof e == "string" && (de(e), h(z()));
|
|
408
|
+
}, [n, M]), P = r((e) => {
|
|
409
|
+
if (_(e), B(e), e && n) {
|
|
406
410
|
let t = m.find((t) => "ally_code" in t && t.ally_code === e);
|
|
407
|
-
t && "id" in t &&
|
|
408
|
-
} else e && !n &&
|
|
411
|
+
t && "id" in t && N(t.id);
|
|
412
|
+
} else e && !n && de(e);
|
|
409
413
|
}, [
|
|
410
414
|
n,
|
|
411
415
|
m,
|
|
412
|
-
|
|
413
|
-
]),
|
|
416
|
+
N
|
|
417
|
+
]), F = r(async (e) => {
|
|
414
418
|
if (!/^\d{9}$/.test(e)) throw Error("Ally code must be exactly 9 digits");
|
|
415
419
|
if (n) {
|
|
416
|
-
let t = await
|
|
417
|
-
h((e) => [t, ...e]), m.length === 0 &&
|
|
420
|
+
let t = await L.post("/api/v1/users/me/ally-codes", { ally_code: e });
|
|
421
|
+
h((e) => [t, ...e]), m.length === 0 && P(e);
|
|
418
422
|
} else {
|
|
419
|
-
let t = await
|
|
423
|
+
let t = await L.get(`/api/v1/player-data/player/${e}`);
|
|
420
424
|
if (!t) throw Error("Invalid ally code - player not found");
|
|
421
|
-
|
|
425
|
+
le({
|
|
422
426
|
ally_code: e,
|
|
423
427
|
player_name: t.data?.name ?? null,
|
|
424
428
|
last_used_at: (/* @__PURE__ */ new Date()).toISOString()
|
|
425
|
-
}), h(
|
|
429
|
+
}), h(z()), m.length === 0 && P(e);
|
|
426
430
|
}
|
|
427
431
|
}, [
|
|
428
432
|
n,
|
|
429
433
|
m.length,
|
|
430
|
-
|
|
431
|
-
]),
|
|
432
|
-
n && typeof e == "number" ? (await
|
|
434
|
+
P
|
|
435
|
+
]), te = r(async (e) => {
|
|
436
|
+
n && typeof e == "number" ? (await L.delete(`/api/v1/users/me/ally-codes/${e}`), h((t) => t.filter((t) => "id" in t && t.id !== e))) : !n && typeof e == "string" && (ue(e), h(z()), g === e && P(null));
|
|
433
437
|
}, [
|
|
434
438
|
n,
|
|
435
439
|
g,
|
|
436
|
-
|
|
437
|
-
]),
|
|
440
|
+
P
|
|
441
|
+
]), I = r(() => {
|
|
438
442
|
x({
|
|
439
443
|
show: !1,
|
|
440
444
|
localStorageCodes: []
|
|
441
445
|
});
|
|
442
|
-
}, []),
|
|
446
|
+
}, []), ne = r(async () => {
|
|
443
447
|
if (!n) return;
|
|
444
|
-
let e =
|
|
448
|
+
let e = z();
|
|
445
449
|
for (let t of e) try {
|
|
446
|
-
await
|
|
450
|
+
await F(t.ally_code);
|
|
447
451
|
} catch (e) {
|
|
448
452
|
console.error(`Failed to migrate ally code ${t.ally_code}:`, e);
|
|
449
453
|
}
|
|
450
|
-
|
|
454
|
+
pe(), I();
|
|
451
455
|
}, [
|
|
452
456
|
n,
|
|
453
|
-
|
|
454
|
-
|
|
457
|
+
F,
|
|
458
|
+
I
|
|
455
459
|
]);
|
|
456
460
|
a(() => {
|
|
457
|
-
|
|
458
|
-
}, [
|
|
459
|
-
let
|
|
461
|
+
M();
|
|
462
|
+
}, [M]);
|
|
463
|
+
let re = {
|
|
460
464
|
user: n,
|
|
461
465
|
isAuthenticated: !!n,
|
|
462
466
|
isLoading: o,
|
|
463
467
|
login: C,
|
|
464
468
|
register: w,
|
|
465
469
|
logout: T,
|
|
466
|
-
refreshUser:
|
|
470
|
+
refreshUser: O,
|
|
467
471
|
forgotPassword: k,
|
|
468
472
|
resetPassword: A,
|
|
469
|
-
resendVerification:
|
|
473
|
+
resendVerification: j,
|
|
470
474
|
authEnabled: u,
|
|
471
475
|
isLoadingFeatures: f,
|
|
472
476
|
allyCodes: m,
|
|
473
477
|
selectedAllyCode: g,
|
|
474
478
|
isLoadingAllyCodes: v,
|
|
475
|
-
fetchAllyCodes:
|
|
476
|
-
addAllyCode:
|
|
477
|
-
removeAllyCode:
|
|
478
|
-
selectAllyCode:
|
|
479
|
-
updateAllyCodeLastUsed:
|
|
479
|
+
fetchAllyCodes: M,
|
|
480
|
+
addAllyCode: F,
|
|
481
|
+
removeAllyCode: te,
|
|
482
|
+
selectAllyCode: P,
|
|
483
|
+
updateAllyCodeLastUsed: N,
|
|
480
484
|
migrationPrompt: b,
|
|
481
|
-
dismissMigrationPrompt:
|
|
482
|
-
migrateLocalStorageCodes:
|
|
485
|
+
dismissMigrationPrompt: I,
|
|
486
|
+
migrateLocalStorageCodes: ne
|
|
483
487
|
};
|
|
484
|
-
return /* @__PURE__ */ l(
|
|
485
|
-
value:
|
|
488
|
+
return /* @__PURE__ */ l(me.Provider, {
|
|
489
|
+
value: re,
|
|
486
490
|
children: e
|
|
487
491
|
});
|
|
488
|
-
},
|
|
489
|
-
let e = i(
|
|
492
|
+
}, V = () => {
|
|
493
|
+
let e = i(me);
|
|
490
494
|
if (e === void 0) throw Error("useAuth must be used within an AuthProvider");
|
|
491
495
|
return e;
|
|
492
496
|
};
|
|
493
497
|
//#endregion
|
|
494
498
|
//#region src/hooks/useDismissableMenu.ts
|
|
495
|
-
function
|
|
499
|
+
function ge({ isOpen: e, onClose: t, triggerRef: n, panelRef: r }) {
|
|
496
500
|
a(() => {
|
|
497
501
|
if (!e) return;
|
|
498
502
|
let i = (e) => {
|
|
@@ -511,7 +515,7 @@ function ve({ isOpen: e, onClose: t, triggerRef: n, panelRef: r }) {
|
|
|
511
515
|
r
|
|
512
516
|
]);
|
|
513
517
|
}
|
|
514
|
-
var
|
|
518
|
+
var H = {
|
|
515
519
|
navMenu: "_navMenu_vspnm_1",
|
|
516
520
|
trigger: "_trigger_vspnm_8",
|
|
517
521
|
tabActive: "_tabActive_vspnm_29",
|
|
@@ -524,9 +528,9 @@ var B = {
|
|
|
524
528
|
groupLabel: "_groupLabel_vspnm_92",
|
|
525
529
|
groupItems: "_groupItems_vspnm_97",
|
|
526
530
|
groupItem: "_groupItem_vspnm_97"
|
|
527
|
-
},
|
|
528
|
-
let { isAuthenticated: s, user: c } =
|
|
529
|
-
|
|
531
|
+
}, _e = ({ app: e, isCurrentApp: t, activeSectionId: n, isOpen: r, onOpenChange: i, onSectionClick: a }) => {
|
|
532
|
+
let { isAuthenticated: s, user: c } = V(), d = o(null), f = o(null), p = `navmenu-panel-${e.id}`;
|
|
533
|
+
ge({
|
|
530
534
|
isOpen: r,
|
|
531
535
|
onClose: () => i(!1),
|
|
532
536
|
triggerRef: d,
|
|
@@ -542,24 +546,24 @@ var B = {
|
|
|
542
546
|
let i = t && n === e.id;
|
|
543
547
|
return /* @__PURE__ */ l("a", {
|
|
544
548
|
href: e.href,
|
|
545
|
-
className: `${
|
|
549
|
+
className: `${H.sectionLink} ${r ?? ""} ${i ? H.sectionActive : ""}`,
|
|
546
550
|
"aria-current": i ? "page" : void 0,
|
|
547
551
|
onClick: h(e),
|
|
548
552
|
children: e.label
|
|
549
553
|
}, e.id);
|
|
550
554
|
};
|
|
551
555
|
return /* @__PURE__ */ u("div", {
|
|
552
|
-
className:
|
|
556
|
+
className: H.navMenu,
|
|
553
557
|
children: [/* @__PURE__ */ u("button", {
|
|
554
558
|
type: "button",
|
|
555
559
|
ref: d,
|
|
556
|
-
className: `${
|
|
560
|
+
className: `${H.trigger} ${t ? H.tabActive : ""}`,
|
|
557
561
|
"aria-expanded": r,
|
|
558
562
|
"aria-controls": p,
|
|
559
563
|
"aria-haspopup": "true",
|
|
560
564
|
onClick: () => i(!r),
|
|
561
565
|
children: [e.label, /* @__PURE__ */ l("svg", {
|
|
562
|
-
className:
|
|
566
|
+
className: H.chevron,
|
|
563
567
|
width: "10",
|
|
564
568
|
height: "6",
|
|
565
569
|
viewBox: "0 0 10 6",
|
|
@@ -576,9 +580,9 @@ var B = {
|
|
|
576
580
|
}), r && /* @__PURE__ */ l("div", {
|
|
577
581
|
id: p,
|
|
578
582
|
ref: f,
|
|
579
|
-
className:
|
|
583
|
+
className: H.panel,
|
|
580
584
|
children: e.status === "coming-soon" ? /* @__PURE__ */ l("div", {
|
|
581
|
-
className:
|
|
585
|
+
className: H.comingSoon,
|
|
582
586
|
children: "Coming soon"
|
|
583
587
|
}) : /* @__PURE__ */ l("nav", {
|
|
584
588
|
"aria-label": `${e.label} sections`,
|
|
@@ -587,20 +591,20 @@ var B = {
|
|
|
587
591
|
if (!g(e)) return m(e) ? v(e) : null;
|
|
588
592
|
let t = e.items.filter(m);
|
|
589
593
|
return /* @__PURE__ */ u("div", {
|
|
590
|
-
className:
|
|
591
|
-
children: [v(e,
|
|
592
|
-
className:
|
|
593
|
-
children: t.map((e) => v(e,
|
|
594
|
+
className: H.group,
|
|
595
|
+
children: [v(e, H.groupLabel), /* @__PURE__ */ l("div", {
|
|
596
|
+
className: H.groupItems,
|
|
597
|
+
children: t.map((e) => v(e, H.groupItem))
|
|
594
598
|
})]
|
|
595
599
|
}, e.id);
|
|
596
600
|
})
|
|
597
601
|
})
|
|
598
602
|
})]
|
|
599
603
|
});
|
|
600
|
-
},
|
|
604
|
+
}, ve = { burger: "_burger_javjr_1" }, ye = n(({ isOpen: e, onClick: t, controlsId: n }, r) => /* @__PURE__ */ l("button", {
|
|
601
605
|
ref: r,
|
|
602
606
|
type: "button",
|
|
603
|
-
className:
|
|
607
|
+
className: ve.burger,
|
|
604
608
|
onClick: t,
|
|
605
609
|
"aria-expanded": e,
|
|
606
610
|
"aria-controls": n,
|
|
@@ -629,8 +633,8 @@ var B = {
|
|
|
629
633
|
})
|
|
630
634
|
})
|
|
631
635
|
}));
|
|
632
|
-
|
|
633
|
-
var
|
|
636
|
+
ye.displayName = "NavBurger";
|
|
637
|
+
var U = {
|
|
634
638
|
selectWrapper: "_selectWrapper_ir4bq_1",
|
|
635
639
|
fullWidth: "_fullWidth_ir4bq_7",
|
|
636
640
|
label: "_label_ir4bq_11",
|
|
@@ -641,25 +645,25 @@ var V = {
|
|
|
641
645
|
arrow: "_arrow_ir4bq_71",
|
|
642
646
|
errorText: "_errorText_ir4bq_81",
|
|
643
647
|
helperText: "_helperText_ir4bq_86"
|
|
644
|
-
},
|
|
648
|
+
}, be = e.forwardRef(({ label: e, error: t, helperText: n, options: r, placeholder: i, fullWidth: a = !1, className: o = "", id: s, ...c }, d) => {
|
|
645
649
|
let f = s || `select-${Math.random().toString(36).substr(2, 9)}`, p = !!t;
|
|
646
650
|
return /* @__PURE__ */ u("div", {
|
|
647
|
-
className: `${
|
|
651
|
+
className: `${U.selectWrapper} ${a ? U.fullWidth : ""} ${o}`,
|
|
648
652
|
children: [
|
|
649
653
|
e && /* @__PURE__ */ u("label", {
|
|
650
654
|
htmlFor: f,
|
|
651
|
-
className:
|
|
655
|
+
className: U.label,
|
|
652
656
|
children: [e, c.required && /* @__PURE__ */ l("span", {
|
|
653
|
-
className:
|
|
657
|
+
className: U.required,
|
|
654
658
|
children: "*"
|
|
655
659
|
})]
|
|
656
660
|
}),
|
|
657
661
|
/* @__PURE__ */ u("div", {
|
|
658
|
-
className:
|
|
662
|
+
className: U.selectContainer,
|
|
659
663
|
children: [/* @__PURE__ */ u("select", {
|
|
660
664
|
ref: d,
|
|
661
665
|
id: f,
|
|
662
|
-
className: `${
|
|
666
|
+
className: `${U.select} ${p ? U.error : ""}`,
|
|
663
667
|
...c,
|
|
664
668
|
children: [
|
|
665
669
|
i && /* @__PURE__ */ l("option", {
|
|
@@ -675,23 +679,23 @@ var V = {
|
|
|
675
679
|
!r && c.children
|
|
676
680
|
]
|
|
677
681
|
}), /* @__PURE__ */ l("span", {
|
|
678
|
-
className:
|
|
682
|
+
className: U.arrow,
|
|
679
683
|
children: "▼"
|
|
680
684
|
})]
|
|
681
685
|
}),
|
|
682
686
|
t && /* @__PURE__ */ l("span", {
|
|
683
|
-
className:
|
|
687
|
+
className: U.errorText,
|
|
684
688
|
children: t
|
|
685
689
|
}),
|
|
686
690
|
n && !t && /* @__PURE__ */ l("span", {
|
|
687
|
-
className:
|
|
691
|
+
className: U.helperText,
|
|
688
692
|
children: n
|
|
689
693
|
})
|
|
690
694
|
]
|
|
691
695
|
});
|
|
692
696
|
});
|
|
693
|
-
|
|
694
|
-
var
|
|
697
|
+
be.displayName = "Select";
|
|
698
|
+
var W = {
|
|
695
699
|
button: "_button_159ms_1",
|
|
696
700
|
sm: "_sm_159ms_22",
|
|
697
701
|
md: "_md_159ms_28",
|
|
@@ -707,18 +711,18 @@ var H = {
|
|
|
707
711
|
spinner: "_spinner_159ms_116",
|
|
708
712
|
spin: "_spin_159ms_116",
|
|
709
713
|
loadingText: "_loadingText_159ms_131"
|
|
710
|
-
},
|
|
711
|
-
className: `${
|
|
714
|
+
}, G = ({ children: e, variant: t = "primary", size: n = "md", fullWidth: r = !1, loading: i = !1, disabled: a = !1, className: o = "", ...s }) => /* @__PURE__ */ l("button", {
|
|
715
|
+
className: `${W.button} ${W[t]} ${W[n]} ${r ? W.fullWidth : ""} ${i ? W.loading : ""} ${o}`,
|
|
712
716
|
disabled: a || i,
|
|
713
717
|
...s,
|
|
714
718
|
children: i ? /* @__PURE__ */ u("span", {
|
|
715
|
-
className:
|
|
716
|
-
children: [/* @__PURE__ */ l("span", { className:
|
|
717
|
-
className:
|
|
719
|
+
className: W.loadingSpinner,
|
|
720
|
+
children: [/* @__PURE__ */ l("span", { className: W.spinner }), /* @__PURE__ */ l("span", {
|
|
721
|
+
className: W.loadingText,
|
|
718
722
|
children: e
|
|
719
723
|
})]
|
|
720
724
|
}) : e
|
|
721
|
-
}),
|
|
725
|
+
}), K = {
|
|
722
726
|
inputWrapper: "_inputWrapper_15t4g_1",
|
|
723
727
|
fullWidth: "_fullWidth_15t4g_7",
|
|
724
728
|
label: "_label_15t4g_11",
|
|
@@ -727,40 +731,40 @@ var H = {
|
|
|
727
731
|
error: "_error_15t4g_55",
|
|
728
732
|
errorText: "_errorText_15t4g_63",
|
|
729
733
|
helperText: "_helperText_15t4g_68"
|
|
730
|
-
},
|
|
734
|
+
}, xe = e.forwardRef(({ label: e, error: t, helperText: n, fullWidth: r = !1, className: i = "", id: a, ...o }, s) => {
|
|
731
735
|
let c = a || `input-${Math.random().toString(36).substr(2, 9)}`, d = !!t;
|
|
732
736
|
return /* @__PURE__ */ u("div", {
|
|
733
|
-
className: `${
|
|
737
|
+
className: `${K.inputWrapper} ${r ? K.fullWidth : ""} ${i}`,
|
|
734
738
|
children: [
|
|
735
739
|
e && /* @__PURE__ */ u("label", {
|
|
736
740
|
htmlFor: c,
|
|
737
|
-
className:
|
|
741
|
+
className: K.label,
|
|
738
742
|
children: [e, o.required && /* @__PURE__ */ l("span", {
|
|
739
|
-
className:
|
|
743
|
+
className: K.required,
|
|
740
744
|
children: "*"
|
|
741
745
|
})]
|
|
742
746
|
}),
|
|
743
747
|
/* @__PURE__ */ l("input", {
|
|
744
748
|
ref: s,
|
|
745
749
|
id: c,
|
|
746
|
-
className: `${
|
|
750
|
+
className: `${K.input} ${d ? K.error : ""}`,
|
|
747
751
|
...o
|
|
748
752
|
}),
|
|
749
753
|
t && /* @__PURE__ */ l("span", {
|
|
750
|
-
className:
|
|
754
|
+
className: K.errorText,
|
|
751
755
|
children: t
|
|
752
756
|
}),
|
|
753
757
|
n && !t && /* @__PURE__ */ l("span", {
|
|
754
|
-
className:
|
|
758
|
+
className: K.helperText,
|
|
755
759
|
children: n
|
|
756
760
|
})
|
|
757
761
|
]
|
|
758
762
|
});
|
|
759
763
|
});
|
|
760
|
-
|
|
764
|
+
xe.displayName = "Input";
|
|
761
765
|
//#endregion
|
|
762
766
|
//#region src/utils/formatAllyCode.ts
|
|
763
|
-
var
|
|
767
|
+
var q = (e) => !e || e.length !== 9 ? e : `${e.slice(0, 3)}-${e.slice(3, 6)}-${e.slice(6, 9)}`, Se = (e) => e.replace(/-/g, ""), J = {
|
|
764
768
|
allyCodeDropdown: "_allyCodeDropdown_1pawi_1",
|
|
765
769
|
select: "_select_1pawi_8",
|
|
766
770
|
manageButton: "_manageButton_1pawi_12",
|
|
@@ -773,26 +777,29 @@ var G = (e) => !e || e.length !== 9 ? e : `${e.slice(0, 3)}-${e.slice(3, 6)}-${e
|
|
|
773
777
|
codeItem: "_codeItem_1pawi_71",
|
|
774
778
|
doneButton: "_doneButton_1pawi_88",
|
|
775
779
|
inline: "_inline_1pawi_107"
|
|
776
|
-
},
|
|
777
|
-
let { allyCodes: a, selectedAllyCode: c, selectAllyCode: d, removeAllyCode: f, addAllyCode: p, isLoadingAllyCodes: m } =
|
|
780
|
+
}, Ce = ({ onAllyCodeSelected: e, className: t = "", isOpen: n, onOpenChange: r, variant: i = "floating" }) => {
|
|
781
|
+
let { allyCodes: a, selectedAllyCode: c, selectAllyCode: d, removeAllyCode: f, addAllyCode: p, isLoadingAllyCodes: m } = V(), [h, g] = s(!1), _ = n ?? h, v = (e) => {
|
|
778
782
|
g(e), r?.(e);
|
|
779
|
-
}, [y, b] = s(""), [x, S] = s(""), [C, w] = s(""), [T, E] = s(!1), D = o(null),
|
|
780
|
-
|
|
783
|
+
}, [y, b] = s(""), [x, S] = s(""), [C, w] = s(""), [T, E] = s(!1), D = o(null), ee = o(null);
|
|
784
|
+
ge({
|
|
781
785
|
isOpen: _ && i === "floating",
|
|
782
786
|
onClose: () => v(!1),
|
|
783
787
|
triggerRef: D,
|
|
784
|
-
panelRef:
|
|
788
|
+
panelRef: ee
|
|
785
789
|
});
|
|
786
|
-
let
|
|
790
|
+
let O = a.map((e) => ({
|
|
787
791
|
value: e.ally_code,
|
|
788
|
-
label: e.player_name ? `${e.player_name} (${
|
|
792
|
+
label: e.player_name ? `${e.player_name} (${q(e.ally_code)})` : q(e.ally_code)
|
|
789
793
|
})), k = (t) => {
|
|
790
794
|
let n = t.target.value || null;
|
|
791
795
|
d(n), e?.(n);
|
|
792
796
|
}, A = async (e) => {
|
|
793
797
|
let t = a.find((t) => t.ally_code === e);
|
|
794
|
-
|
|
795
|
-
|
|
798
|
+
if (t) {
|
|
799
|
+
let e = "id" in t ? t.id : t.ally_code;
|
|
800
|
+
await f(e);
|
|
801
|
+
}
|
|
802
|
+
}, j = async () => {
|
|
796
803
|
if (S(""), w(""), !/^\d{9}$/.test(y)) {
|
|
797
804
|
S("Ally code must be exactly 9 digits");
|
|
798
805
|
return;
|
|
@@ -805,59 +812,59 @@ var G = (e) => !e || e.length !== 9 ? e : `${e.slice(0, 3)}-${e.slice(3, 6)}-${e
|
|
|
805
812
|
} finally {
|
|
806
813
|
E(!1);
|
|
807
814
|
}
|
|
808
|
-
},
|
|
815
|
+
}, M = a.length > 0;
|
|
809
816
|
return /* @__PURE__ */ u("div", {
|
|
810
|
-
className: `${
|
|
817
|
+
className: `${J.allyCodeDropdown} ${i === "inline" ? J.inline : ""} ${t}`,
|
|
811
818
|
children: [
|
|
812
|
-
|
|
813
|
-
options:
|
|
819
|
+
M && /* @__PURE__ */ l(be, {
|
|
820
|
+
options: O,
|
|
814
821
|
value: c || "",
|
|
815
822
|
onChange: k,
|
|
816
823
|
placeholder: "Select ally code",
|
|
817
824
|
disabled: m,
|
|
818
|
-
className:
|
|
825
|
+
className: J.select
|
|
819
826
|
}),
|
|
820
827
|
_ && /* @__PURE__ */ u("div", {
|
|
821
|
-
className:
|
|
822
|
-
ref:
|
|
828
|
+
className: J.managePanel,
|
|
829
|
+
ref: ee,
|
|
823
830
|
id: "ally-code-manage-panel",
|
|
824
831
|
children: [
|
|
825
832
|
/* @__PURE__ */ l("h4", { children: "Manage Ally Codes" }),
|
|
826
833
|
/* @__PURE__ */ u("div", {
|
|
827
|
-
className:
|
|
834
|
+
className: J.addSection,
|
|
828
835
|
children: [
|
|
829
836
|
/* @__PURE__ */ u("div", {
|
|
830
|
-
className:
|
|
831
|
-
children: [/* @__PURE__ */ l(
|
|
837
|
+
className: J.addInputGroup,
|
|
838
|
+
children: [/* @__PURE__ */ l(xe, {
|
|
832
839
|
type: "text",
|
|
833
840
|
placeholder: "9-digit ally code",
|
|
834
841
|
value: y,
|
|
835
842
|
onChange: (e) => b(e.target.value.replace(/\D/g, "").slice(0, 9)),
|
|
836
843
|
disabled: T
|
|
837
|
-
}), /* @__PURE__ */ l(
|
|
844
|
+
}), /* @__PURE__ */ l(G, {
|
|
838
845
|
variant: "primary",
|
|
839
846
|
size: "sm",
|
|
840
|
-
onClick:
|
|
847
|
+
onClick: j,
|
|
841
848
|
loading: T,
|
|
842
849
|
disabled: y.length !== 9,
|
|
843
850
|
children: "Add"
|
|
844
851
|
})]
|
|
845
852
|
}),
|
|
846
853
|
x && /* @__PURE__ */ l("div", {
|
|
847
|
-
className:
|
|
854
|
+
className: J.error,
|
|
848
855
|
children: x
|
|
849
856
|
}),
|
|
850
857
|
C && /* @__PURE__ */ l("div", {
|
|
851
|
-
className:
|
|
858
|
+
className: J.success,
|
|
852
859
|
children: C
|
|
853
860
|
})
|
|
854
861
|
]
|
|
855
862
|
}),
|
|
856
863
|
/* @__PURE__ */ l("div", {
|
|
857
|
-
className:
|
|
864
|
+
className: J.codesList,
|
|
858
865
|
children: a.map((e) => /* @__PURE__ */ u("div", {
|
|
859
|
-
className:
|
|
860
|
-
children: [/* @__PURE__ */ l("span", { children: e.player_name ? `${e.player_name} (${
|
|
866
|
+
className: J.codeItem,
|
|
867
|
+
children: [/* @__PURE__ */ l("span", { children: e.player_name ? `${e.player_name} (${q(e.ally_code)})` : q(e.ally_code) }), /* @__PURE__ */ l(G, {
|
|
861
868
|
variant: "ghost",
|
|
862
869
|
size: "sm",
|
|
863
870
|
onClick: () => A(e.ally_code),
|
|
@@ -865,50 +872,50 @@ var G = (e) => !e || e.length !== 9 ? e : `${e.slice(0, 3)}-${e.slice(3, 6)}-${e
|
|
|
865
872
|
})]
|
|
866
873
|
}, e.ally_code))
|
|
867
874
|
}),
|
|
868
|
-
/* @__PURE__ */ l(
|
|
875
|
+
/* @__PURE__ */ l(G, {
|
|
869
876
|
variant: "secondary",
|
|
870
877
|
size: "sm",
|
|
871
878
|
onClick: () => v(!1),
|
|
872
|
-
className:
|
|
879
|
+
className: J.doneButton,
|
|
873
880
|
children: "Done"
|
|
874
881
|
})
|
|
875
882
|
]
|
|
876
883
|
}),
|
|
877
884
|
/* @__PURE__ */ l("span", {
|
|
878
885
|
ref: D,
|
|
879
|
-
children: /* @__PURE__ */ l(
|
|
886
|
+
children: /* @__PURE__ */ l(G, {
|
|
880
887
|
variant: "ghost",
|
|
881
888
|
size: "sm",
|
|
882
889
|
onClick: () => v(!_),
|
|
883
|
-
className:
|
|
890
|
+
className: J.manageButton,
|
|
884
891
|
"aria-expanded": _,
|
|
885
892
|
"aria-controls": "ally-code-manage-panel",
|
|
886
893
|
"aria-haspopup": "true",
|
|
887
|
-
children:
|
|
894
|
+
children: M ? "Manage" : "+ Add ally code"
|
|
888
895
|
})
|
|
889
896
|
})
|
|
890
897
|
]
|
|
891
898
|
});
|
|
892
|
-
},
|
|
899
|
+
}, we = {
|
|
893
900
|
authCluster: "_authCluster_17o10_1",
|
|
894
901
|
userLink: "_userLink_17o10_7",
|
|
895
902
|
adminLink: "_adminLink_17o10_16"
|
|
896
|
-
},
|
|
897
|
-
let { user: t, isAuthenticated: n, logout: r, authEnabled: i } =
|
|
903
|
+
}, Te = ({ showAuth: e = !0 }) => {
|
|
904
|
+
let { user: t, isAuthenticated: n, logout: r, authEnabled: i } = V();
|
|
898
905
|
return e ? n ? /* @__PURE__ */ u("div", {
|
|
899
|
-
className:
|
|
906
|
+
className: we.authCluster,
|
|
900
907
|
children: [
|
|
901
908
|
t?.role === "admin" && /* @__PURE__ */ l("a", {
|
|
902
909
|
href: "/admin/users",
|
|
903
|
-
className:
|
|
910
|
+
className: we.adminLink,
|
|
904
911
|
children: "Admin"
|
|
905
912
|
}),
|
|
906
913
|
/* @__PURE__ */ l("a", {
|
|
907
914
|
href: "/profile",
|
|
908
|
-
className:
|
|
915
|
+
className: we.userLink,
|
|
909
916
|
children: t?.username
|
|
910
917
|
}),
|
|
911
|
-
/* @__PURE__ */ l(
|
|
918
|
+
/* @__PURE__ */ l(G, {
|
|
912
919
|
variant: "ghost",
|
|
913
920
|
size: "sm",
|
|
914
921
|
onClick: () => {
|
|
@@ -918,24 +925,24 @@ var G = (e) => !e || e.length !== 9 ? e : `${e.slice(0, 3)}-${e.slice(3, 6)}-${e
|
|
|
918
925
|
})
|
|
919
926
|
]
|
|
920
927
|
}) : i ? /* @__PURE__ */ u("div", {
|
|
921
|
-
className:
|
|
928
|
+
className: we.authCluster,
|
|
922
929
|
children: [/* @__PURE__ */ l("a", {
|
|
923
930
|
href: "/login",
|
|
924
|
-
children: /* @__PURE__ */ l(
|
|
931
|
+
children: /* @__PURE__ */ l(G, {
|
|
925
932
|
variant: "ghost",
|
|
926
933
|
size: "sm",
|
|
927
934
|
children: "Login"
|
|
928
935
|
})
|
|
929
936
|
}), /* @__PURE__ */ l("a", {
|
|
930
937
|
href: "/register",
|
|
931
|
-
children: /* @__PURE__ */ l(
|
|
938
|
+
children: /* @__PURE__ */ l(G, {
|
|
932
939
|
variant: "primary",
|
|
933
940
|
size: "sm",
|
|
934
941
|
children: "Sign Up"
|
|
935
942
|
})
|
|
936
943
|
})]
|
|
937
944
|
}) : null : null;
|
|
938
|
-
},
|
|
945
|
+
}, Y = {
|
|
939
946
|
backdrop: "_backdrop_3ax21_1",
|
|
940
947
|
panel: "_panel_3ax21_11",
|
|
941
948
|
accordion: "_accordion_3ax21_24",
|
|
@@ -955,14 +962,23 @@ var G = (e) => !e || e.length !== 9 ? e : `${e.slice(0, 3)}-${e.slice(3, 6)}-${e
|
|
|
955
962
|
allySection: "_allySection_3ax21_112",
|
|
956
963
|
extrasSection: "_extrasSection_3ax21_113",
|
|
957
964
|
accountSection: "_accountSection_3ax21_114"
|
|
958
|
-
}, De = ({ isOpen: e, onClose: t, currentApp: n, activeSectionId: r, onSectionClick: i, rightExtras: c, showAuth: f, panelId: p, returnFocusRef: m }) => {
|
|
959
|
-
let { isAuthenticated: h, user: v } =
|
|
965
|
+
}, Ee = "a[href], button:not([disabled]), input:not([disabled]), select:not([disabled]), textarea:not([disabled]), [tabindex]:not([tabindex=\"-1\"])", De = ({ isOpen: e, onClose: t, currentApp: n, activeSectionId: r, onSectionClick: i, rightExtras: c, showAuth: f, panelId: p, returnFocusRef: m }) => {
|
|
966
|
+
let { isAuthenticated: h, user: v } = V(), [y, b] = s(n === "hub" ? null : n), x = o(null);
|
|
960
967
|
if (a(() => (e ? document.body.style.overflow = "hidden" : document.body.style.overflow = "unset", () => {
|
|
961
968
|
document.body.style.overflow = "unset";
|
|
962
969
|
}), [e]), a(() => {
|
|
963
970
|
if (!e) return;
|
|
964
971
|
let r = (e) => {
|
|
965
|
-
e.key === "Escape"
|
|
972
|
+
if (e.key === "Escape") {
|
|
973
|
+
t(), m.current?.focus();
|
|
974
|
+
return;
|
|
975
|
+
}
|
|
976
|
+
if (e.key === "Tab") {
|
|
977
|
+
let t = x.current?.querySelectorAll(Ee);
|
|
978
|
+
if (!t || t.length === 0) return;
|
|
979
|
+
let n = t[0], r = t[t.length - 1], i = document.activeElement, a = i === x.current || !x.current?.contains(i);
|
|
980
|
+
e.shiftKey && (i === n || a) ? (e.preventDefault(), r.focus()) : !e.shiftKey && (i === r || a) && (e.preventDefault(), n.focus());
|
|
981
|
+
}
|
|
966
982
|
};
|
|
967
983
|
return document.addEventListener("keydown", r), b(n === "hub" ? null : n), x.current?.focus(), () => document.removeEventListener("keydown", r);
|
|
968
984
|
}, [e]), !e) return null;
|
|
@@ -970,7 +986,7 @@ var G = (e) => !e || e.length !== 9 ? e : `${e.slice(0, 3)}-${e.slice(3, 6)}-${e
|
|
|
970
986
|
e === n && i?.(r, a), t();
|
|
971
987
|
};
|
|
972
988
|
return d(/* @__PURE__ */ l("div", {
|
|
973
|
-
className:
|
|
989
|
+
className: Y.backdrop,
|
|
974
990
|
onClick: t,
|
|
975
991
|
children: /* @__PURE__ */ u("div", {
|
|
976
992
|
ref: x,
|
|
@@ -979,32 +995,32 @@ var G = (e) => !e || e.length !== 9 ? e : `${e.slice(0, 3)}-${e.slice(3, 6)}-${e
|
|
|
979
995
|
"aria-modal": "true",
|
|
980
996
|
"aria-label": "Navigation menu",
|
|
981
997
|
tabIndex: -1,
|
|
982
|
-
className:
|
|
998
|
+
className: Y.panel,
|
|
983
999
|
onClick: (e) => e.stopPropagation(),
|
|
984
1000
|
children: [
|
|
985
1001
|
/* @__PURE__ */ l("div", {
|
|
986
|
-
className:
|
|
1002
|
+
className: Y.accordion,
|
|
987
1003
|
children: _.map((e) => {
|
|
988
1004
|
let t = y === e.id, i = n === e.id, a = (e) => !(e.requiresAuth && !h || e.roles && (!v || !e.roles.includes(v.role))), o = `mobile-accordion-${e.id}`, s = (t, n) => {
|
|
989
1005
|
let a = i && r === t.id;
|
|
990
1006
|
return /* @__PURE__ */ l("a", {
|
|
991
1007
|
href: t.href,
|
|
992
|
-
className: `${
|
|
1008
|
+
className: `${Y.sectionLink} ${n ?? ""} ${a ? Y.sectionActive : ""}`,
|
|
993
1009
|
"aria-current": a ? "page" : void 0,
|
|
994
1010
|
onClick: S(e.id, t),
|
|
995
1011
|
children: t.label
|
|
996
1012
|
}, t.id);
|
|
997
1013
|
};
|
|
998
1014
|
return /* @__PURE__ */ u("div", {
|
|
999
|
-
className:
|
|
1015
|
+
className: Y.accordionItem,
|
|
1000
1016
|
children: [/* @__PURE__ */ u("button", {
|
|
1001
1017
|
type: "button",
|
|
1002
|
-
className: `${
|
|
1018
|
+
className: `${Y.accordionHeader} ${i ? Y.currentApp : ""}`,
|
|
1003
1019
|
"aria-expanded": t,
|
|
1004
1020
|
"aria-controls": o,
|
|
1005
1021
|
onClick: () => b(t ? null : e.id),
|
|
1006
1022
|
children: [e.label, /* @__PURE__ */ l("svg", {
|
|
1007
|
-
className: `${
|
|
1023
|
+
className: `${Y.chevron} ${t ? Y.chevronOpen : ""}`,
|
|
1008
1024
|
width: "10",
|
|
1009
1025
|
height: "6",
|
|
1010
1026
|
viewBox: "0 0 10 6",
|
|
@@ -1020,18 +1036,18 @@ var G = (e) => !e || e.length !== 9 ? e : `${e.slice(0, 3)}-${e.slice(3, 6)}-${e
|
|
|
1020
1036
|
})]
|
|
1021
1037
|
}), t && /* @__PURE__ */ l("div", {
|
|
1022
1038
|
id: o,
|
|
1023
|
-
className:
|
|
1039
|
+
className: Y.accordionPanel,
|
|
1024
1040
|
children: e.status === "coming-soon" ? /* @__PURE__ */ l("div", {
|
|
1025
|
-
className:
|
|
1041
|
+
className: Y.comingSoon,
|
|
1026
1042
|
children: "Coming soon"
|
|
1027
1043
|
}) : e.sections.map((e) => {
|
|
1028
1044
|
if (!g(e)) return a(e) ? s(e) : null;
|
|
1029
1045
|
let t = e.items.filter(a);
|
|
1030
1046
|
return /* @__PURE__ */ u("div", {
|
|
1031
|
-
className:
|
|
1032
|
-
children: [s(e,
|
|
1033
|
-
className:
|
|
1034
|
-
children: t.map((e) => s(e,
|
|
1047
|
+
className: Y.group,
|
|
1048
|
+
children: [s(e, Y.groupLabel), /* @__PURE__ */ l("div", {
|
|
1049
|
+
className: Y.groupItems,
|
|
1050
|
+
children: t.map((e) => s(e, Y.groupItem))
|
|
1035
1051
|
})]
|
|
1036
1052
|
}, e.id);
|
|
1037
1053
|
})
|
|
@@ -1040,26 +1056,26 @@ var G = (e) => !e || e.length !== 9 ? e : `${e.slice(0, 3)}-${e.slice(3, 6)}-${e
|
|
|
1040
1056
|
})
|
|
1041
1057
|
}),
|
|
1042
1058
|
/* @__PURE__ */ l("div", {
|
|
1043
|
-
className:
|
|
1044
|
-
children: /* @__PURE__ */ l(
|
|
1059
|
+
className: Y.allySection,
|
|
1060
|
+
children: /* @__PURE__ */ l(Ce, { variant: "inline" })
|
|
1045
1061
|
}),
|
|
1046
1062
|
c && /* @__PURE__ */ l("div", {
|
|
1047
|
-
className:
|
|
1063
|
+
className: Y.extrasSection,
|
|
1048
1064
|
children: c
|
|
1049
1065
|
}),
|
|
1050
1066
|
/* @__PURE__ */ l("div", {
|
|
1051
|
-
className:
|
|
1052
|
-
children: /* @__PURE__ */ l(
|
|
1067
|
+
className: Y.accountSection,
|
|
1068
|
+
children: /* @__PURE__ */ l(Te, { showAuth: f })
|
|
1053
1069
|
})
|
|
1054
1070
|
]
|
|
1055
1071
|
})
|
|
1056
1072
|
}), document.body);
|
|
1057
|
-
},
|
|
1073
|
+
}, Oe = {
|
|
1058
1074
|
logoLink: "_logoLink_12f5f_3",
|
|
1059
1075
|
appMenus: "_appMenus_12f5f_10",
|
|
1060
1076
|
desktopRight: "_desktopRight_12f5f_19",
|
|
1061
1077
|
extrasGroup: "_extrasGroup_12f5f_25"
|
|
1062
|
-
},
|
|
1078
|
+
}, ke = ({ currentApp: e, activeSectionId: t, onNavigate: n, rightExtras: r, showAuth: i = !0, className: d }) => {
|
|
1063
1079
|
let [f, p] = s(null), [m, g] = s(!1), v = o(null), y = "suite-mobile-nav-panel";
|
|
1064
1080
|
return a(() => {
|
|
1065
1081
|
let e = window.matchMedia("(max-width: 768px)"), t = () => {
|
|
@@ -1070,12 +1086,12 @@ var G = (e) => !e || e.length !== 9 ? e : `${e.slice(0, 3)}-${e.slice(3, 6)}-${e
|
|
|
1070
1086
|
className: d,
|
|
1071
1087
|
logo: /* @__PURE__ */ l("a", {
|
|
1072
1088
|
href: "/",
|
|
1073
|
-
className:
|
|
1089
|
+
className: Oe.logoLink,
|
|
1074
1090
|
children: "The Astrogator's Table"
|
|
1075
1091
|
}),
|
|
1076
1092
|
leftContent: /* @__PURE__ */ l("nav", {
|
|
1077
|
-
className:
|
|
1078
|
-
children: _.map((r) => /* @__PURE__ */ l(
|
|
1093
|
+
className: Oe.appMenus,
|
|
1094
|
+
children: _.map((r) => /* @__PURE__ */ l(_e, {
|
|
1079
1095
|
app: r,
|
|
1080
1096
|
isCurrentApp: e === r.id,
|
|
1081
1097
|
activeSectionId: t,
|
|
@@ -1085,19 +1101,19 @@ var G = (e) => !e || e.length !== 9 ? e : `${e.slice(0, 3)}-${e.slice(3, 6)}-${e
|
|
|
1085
1101
|
}, r.id))
|
|
1086
1102
|
}),
|
|
1087
1103
|
rightContent: /* @__PURE__ */ u(c, { children: [/* @__PURE__ */ u("div", {
|
|
1088
|
-
className:
|
|
1104
|
+
className: Oe.desktopRight,
|
|
1089
1105
|
children: [
|
|
1090
1106
|
r && /* @__PURE__ */ l("div", {
|
|
1091
|
-
className:
|
|
1107
|
+
className: Oe.extrasGroup,
|
|
1092
1108
|
children: r
|
|
1093
1109
|
}),
|
|
1094
|
-
/* @__PURE__ */ l(
|
|
1110
|
+
/* @__PURE__ */ l(Ce, {
|
|
1095
1111
|
isOpen: f === "ally",
|
|
1096
1112
|
onOpenChange: (e) => p(e ? "ally" : null)
|
|
1097
1113
|
}),
|
|
1098
|
-
/* @__PURE__ */ l(
|
|
1114
|
+
/* @__PURE__ */ l(Te, { showAuth: i })
|
|
1099
1115
|
]
|
|
1100
|
-
}), /* @__PURE__ */ l(
|
|
1116
|
+
}), /* @__PURE__ */ l(ye, {
|
|
1101
1117
|
ref: v,
|
|
1102
1118
|
isOpen: m,
|
|
1103
1119
|
onClick: () => {
|
|
@@ -1122,7 +1138,7 @@ var G = (e) => !e || e.length !== 9 ? e : `${e.slice(0, 3)}-${e.slice(3, 6)}-${e
|
|
|
1122
1138
|
defaultContent: "_defaultContent_zjuj8_13",
|
|
1123
1139
|
copyright: "_copyright_zjuj8_21",
|
|
1124
1140
|
disclaimer: "_disclaimer_zjuj8_26"
|
|
1125
|
-
},
|
|
1141
|
+
}, Ae = ({ children: e, className: t = "" }) => /* @__PURE__ */ l("footer", {
|
|
1126
1142
|
className: `${X.footer} ${t}`,
|
|
1127
1143
|
children: /* @__PURE__ */ l("div", {
|
|
1128
1144
|
className: X.content,
|
|
@@ -1144,11 +1160,11 @@ var G = (e) => !e || e.length !== 9 ? e : `${e.slice(0, 3)}-${e.slice(3, 6)}-${e
|
|
|
1144
1160
|
});
|
|
1145
1161
|
//#endregion
|
|
1146
1162
|
//#region src/utils/formatTime.ts
|
|
1147
|
-
function
|
|
1163
|
+
function je(e) {
|
|
1148
1164
|
let t = /([zZ]|[+-]\d{2}:?\d{2})$/.test(e);
|
|
1149
1165
|
return new Date(t ? e : `${e}Z`);
|
|
1150
1166
|
}
|
|
1151
|
-
function
|
|
1167
|
+
function Me(e, t) {
|
|
1152
1168
|
let n = Math.max(0, Math.floor((t - e.getTime()) / 1e3));
|
|
1153
1169
|
if (n < 60) return `${n}s ago`;
|
|
1154
1170
|
let r = Math.floor(n / 60);
|
|
@@ -1156,38 +1172,38 @@ function je(e, t) {
|
|
|
1156
1172
|
let i = Math.floor(r / 60);
|
|
1157
1173
|
return i < 24 ? `${i}h ago` : `${Math.floor(i / 24)}d ago`;
|
|
1158
1174
|
}
|
|
1159
|
-
function
|
|
1175
|
+
function Ne(e) {
|
|
1160
1176
|
return `${Math.floor(e / 60)}:${(e % 60).toString().padStart(2, "0")}`;
|
|
1161
1177
|
}
|
|
1162
|
-
var
|
|
1178
|
+
var Pe = {
|
|
1163
1179
|
rosterRefresh: "_rosterRefresh_1rbul_3",
|
|
1164
1180
|
updatedLabel: "_updatedLabel_1rbul_11",
|
|
1165
1181
|
refreshButton: "_refreshButton_1rbul_19",
|
|
1166
1182
|
spin: "_spin_1rbul_31"
|
|
1167
|
-
},
|
|
1183
|
+
}, Fe = ({ onRefresh: e, isRefreshing: t, cachedAt: n = null, refreshAvailableAt: r = null, labelPrefix: i = "Updated", className: o = "" }) => {
|
|
1168
1184
|
let [c, d] = s(() => Date.now()), f = !!n || r != null && r > c;
|
|
1169
1185
|
a(() => {
|
|
1170
1186
|
if (!f) return;
|
|
1171
1187
|
let e = setInterval(() => d(Date.now()), 1e3);
|
|
1172
1188
|
return () => clearInterval(e);
|
|
1173
1189
|
}, [f]);
|
|
1174
|
-
let p = r ? Math.max(0, Math.ceil((r - c) / 1e3)) : 0, m = n ? je(
|
|
1190
|
+
let p = r ? Math.max(0, Math.ceil((r - c) / 1e3)) : 0, m = n ? Me(je(n), c) : null, h = t || p > 0, g = p > 0 ? `Fresh data available in ${Ne(p)}` : "Refresh roster";
|
|
1175
1191
|
return /* @__PURE__ */ u("div", {
|
|
1176
|
-
className: `${
|
|
1192
|
+
className: `${Pe.rosterRefresh} ${o}`,
|
|
1177
1193
|
children: [m && /* @__PURE__ */ l("span", {
|
|
1178
|
-
className:
|
|
1194
|
+
className: Pe.updatedLabel,
|
|
1179
1195
|
title: g,
|
|
1180
|
-
children: p > 0 ? `${i} ${m} · fresh in ${
|
|
1181
|
-
}), /* @__PURE__ */ l(
|
|
1196
|
+
children: p > 0 ? `${i} ${m} · fresh in ${Ne(p)}` : `${i} ${m}`
|
|
1197
|
+
}), /* @__PURE__ */ l(G, {
|
|
1182
1198
|
variant: "outline",
|
|
1183
1199
|
size: "sm",
|
|
1184
1200
|
onClick: e,
|
|
1185
1201
|
disabled: h,
|
|
1186
1202
|
title: g,
|
|
1187
1203
|
"aria-label": "Refresh roster",
|
|
1188
|
-
className:
|
|
1204
|
+
className: Pe.refreshButton,
|
|
1189
1205
|
children: /* @__PURE__ */ l("span", {
|
|
1190
|
-
className: t ?
|
|
1206
|
+
className: t ? Pe.spin : void 0,
|
|
1191
1207
|
children: "⟳"
|
|
1192
1208
|
})
|
|
1193
1209
|
})]
|
|
@@ -1203,7 +1219,7 @@ var Ne = {
|
|
|
1203
1219
|
"padding-md": "_padding-md_1vw8g_43",
|
|
1204
1220
|
"padding-lg": "_padding-lg_1vw8g_47",
|
|
1205
1221
|
hoverable: "_hoverable_1vw8g_52"
|
|
1206
|
-
},
|
|
1222
|
+
}, Ie = ({ children: e, variant: t = "default", chamfered: n = !1, chamferSize: r = "md", padding: i = "md", hoverable: a = !1, showDiagonalBorders: o = !0, edgeColor: s, className: d = "", onClick: f, style: p }) => {
|
|
1207
1223
|
let m = n ? r === "asymmetric" ? "chamfered-box-asymmetric" : r === "sm" ? "chamfered-box-sm" : r === "lg" ? "chamfered-box-lg" : "chamfered-box" : "", h = s ?? (n ? "var(--color-border)" : void 0), g = h ? { color: h } : void 0, _ = h ? {
|
|
1208
1224
|
...p,
|
|
1209
1225
|
"--card-edge-color": h
|
|
@@ -1233,7 +1249,7 @@ var Ne = {
|
|
|
1233
1249
|
})
|
|
1234
1250
|
] }), e]
|
|
1235
1251
|
});
|
|
1236
|
-
},
|
|
1252
|
+
}, Le = {
|
|
1237
1253
|
badge: "_badge_rk7t5_1",
|
|
1238
1254
|
sm: "_sm_rk7t5_11",
|
|
1239
1255
|
md: "_md_rk7t5_16",
|
|
@@ -1245,8 +1261,8 @@ var Ne = {
|
|
|
1245
1261
|
warning: "_warning_rk7t5_47",
|
|
1246
1262
|
error: "_error_rk7t5_52",
|
|
1247
1263
|
info: "_info_rk7t5_57"
|
|
1248
|
-
},
|
|
1249
|
-
className: `${
|
|
1264
|
+
}, Re = ({ children: e, variant: t = "default", size: n = "md", className: r = "" }) => /* @__PURE__ */ l("span", {
|
|
1265
|
+
className: `${Le.badge} ${Le[t]} ${Le[n]} ${r}`,
|
|
1250
1266
|
children: e
|
|
1251
1267
|
}), Q = {
|
|
1252
1268
|
overlay: "_overlay_1b3yt_1",
|
|
@@ -1261,7 +1277,7 @@ var Ne = {
|
|
|
1261
1277
|
title: "_title_1b3yt_53",
|
|
1262
1278
|
closeButton: "_closeButton_1b3yt_60",
|
|
1263
1279
|
content: "_content_1b3yt_78"
|
|
1264
|
-
},
|
|
1280
|
+
}, ze = ({ isOpen: e, onClose: t, title: n, children: r, size: i = "md", closeOnOverlayClick: o = !0, className: s = "" }) => (a(() => (e ? document.body.style.overflow = "hidden" : document.body.style.overflow = "unset", () => {
|
|
1265
1281
|
document.body.style.overflow = "unset";
|
|
1266
1282
|
}), [e]), a(() => {
|
|
1267
1283
|
let n = (n) => {
|
|
@@ -1303,7 +1319,7 @@ var Ne = {
|
|
|
1303
1319
|
dot: "_dot_1uhnh_34",
|
|
1304
1320
|
bounce: "_bounce_1uhnh_1",
|
|
1305
1321
|
visuallyHidden: "_visuallyHidden_1uhnh_91"
|
|
1306
|
-
},
|
|
1322
|
+
}, Be = ({ size: e = "md", variant: t = "spinner", className: n = "" }) => t === "dots" ? /* @__PURE__ */ u("div", {
|
|
1307
1323
|
className: `${$.dots} ${$[e]} ${n}`,
|
|
1308
1324
|
children: [
|
|
1309
1325
|
/* @__PURE__ */ l("span", { className: $.dot }),
|
|
@@ -1317,10 +1333,10 @@ var Ne = {
|
|
|
1317
1333
|
className: $.visuallyHidden,
|
|
1318
1334
|
children: "Loading..."
|
|
1319
1335
|
})
|
|
1320
|
-
}),
|
|
1336
|
+
}), Ve = async (e) => {
|
|
1321
1337
|
if (e.length === 0) return {};
|
|
1322
|
-
let t = [...new Set(e)], n = await
|
|
1338
|
+
let t = [...new Set(e)], n = await L.get(`/api/v1/users/lookup?ids=${t.join(",")}`);
|
|
1323
1339
|
return Object.fromEntries(n.users.map((e) => [e.id, e.username]));
|
|
1324
1340
|
};
|
|
1325
1341
|
//#endregion
|
|
1326
|
-
export {
|
|
1342
|
+
export { Ce as AllyCodeDropdown, oe as ApiClient, he as AuthProvider, Re as Badge, G as Button, Ie as Card, p as Container, Ae as Footer, xe as Input, Be as Loader, ze as Modal, ke as NavBar, Fe as RosterRefresh, _ as SUITE_NAV, be as Select, h as TopBar, L as apiClient, ae as authedFetch, pe as clearAllyCodes, D as clearTokens, j as configureAuthRefresh, Ve as fetchUsernames, q as formatAllyCode, Ne as formatCountdown, Me as formatRelativeTime, b as getAccessToken, z as getAllyCodesFromStorage, C as getRefreshToken, fe as getSelectedAllyCode, se as initializeApiClient, ee as isAuthenticated, g as isSuiteNavGroup, je as parseBackendTimestamp, M as refreshAccessToken, S as removeAccessToken, ue as removeAllyCodeFromStorage, T as removeRefreshToken, le as saveAllyCodeToStorage, x as setAccessToken, w as setRefreshToken, B as setSelectedAllyCode, E as setTokens, Se as unformatAllyCode, de as updateAllyCodeLastUsed, V as useAuth };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "astrogators-shared-ui",
|
|
3
|
-
"version": "0.16.
|
|
3
|
+
"version": "0.16.4",
|
|
4
4
|
"description": "Shared UI components and utilities for Astrogator's Table applications",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -23,7 +23,9 @@
|
|
|
23
23
|
"dev": "vite",
|
|
24
24
|
"build": "tsc && vite build",
|
|
25
25
|
"preview": "vite preview",
|
|
26
|
-
"type-check": "tsc --noEmit"
|
|
26
|
+
"type-check": "tsc --noEmit",
|
|
27
|
+
"test": "vitest run",
|
|
28
|
+
"prepublishOnly": "npm run type-check && npm test"
|
|
27
29
|
},
|
|
28
30
|
"repository": {
|
|
29
31
|
"type": "git",
|
|
@@ -48,8 +50,8 @@
|
|
|
48
50
|
"react": "^19.2.5",
|
|
49
51
|
"react-dom": "^19.2.5",
|
|
50
52
|
"typescript": "^6.0.3",
|
|
51
|
-
"vite": "^8.0
|
|
52
|
-
"vite-plugin-dts": "^4.5.4"
|
|
53
|
-
|
|
54
|
-
|
|
53
|
+
"vite": "^8.3.0",
|
|
54
|
+
"vite-plugin-dts": "^4.5.4",
|
|
55
|
+
"vitest": "^5.0.1"
|
|
56
|
+
}
|
|
55
57
|
}
|