dsh-plugin-subscription-oauth 0.7.0 → 0.8.1
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/lib/auth/allowance-scheduler.d.ts +58 -0
- package/lib/auth/allowance-scheduler.js +72 -0
- package/lib/client/UsageChip.d.ts +58 -2
- package/lib/client/UsageChip.js +116 -22
- package/lib/client/styles.d.ts +1 -1
- package/lib/client/styles.js +16 -4
- package/lib/client.js +106 -58
- package/lib/client.js.map +1 -1
- package/lib/providers/antigravity.d.ts +6 -0
- package/lib/providers/antigravity.js +65 -14
- package/lib/providers/ark-provider.js +8 -0
- package/lib/providers/ark.d.ts +3 -0
- package/lib/providers/ark.js +4 -1
- package/lib/providers/glm-provider.js +5 -0
- package/lib/providers/glm.d.ts +2 -0
- package/lib/providers/glm.js +4 -1
- package/lib/providers/grok.d.ts +3 -0
- package/lib/providers/grok.js +9 -1
- package/lib/providers/kimi-provider.js +5 -0
- package/lib/providers/kimi.d.ts +9 -0
- package/lib/providers/kimi.js +8 -1
- package/lib/providers/responses-stream.d.ts +44 -0
- package/lib/providers/responses-stream.js +125 -30
- package/package.json +1 -1
package/lib/client.js
CHANGED
|
@@ -557,6 +557,18 @@ const usageChipCss = `
|
|
|
557
557
|
color: var(--dsw-alias-label-primary, #e8e8e8);
|
|
558
558
|
font-variant-numeric: tabular-nums;
|
|
559
559
|
}
|
|
560
|
+
.dsh-subscription-usage-chip-account {
|
|
561
|
+
display: flex;
|
|
562
|
+
flex-direction: column;
|
|
563
|
+
gap: 6px;
|
|
564
|
+
/* A hairline between accounts, so two sign-ins read as two groups not one run. */
|
|
565
|
+
padding-top: 6px;
|
|
566
|
+
border-top: 1px solid var(--dsw-alias-border-secondary, #ffffff14);
|
|
567
|
+
}
|
|
568
|
+
.dsh-subscription-usage-chip-account:first-of-type {
|
|
569
|
+
padding-top: 0;
|
|
570
|
+
border-top: 0;
|
|
571
|
+
}
|
|
560
572
|
.dsh-subscription-usage-chip-panel {
|
|
561
573
|
position: absolute;
|
|
562
574
|
bottom: calc(100% + 6px);
|
|
@@ -564,9 +576,9 @@ const usageChipCss = `
|
|
|
564
576
|
z-index: 20;
|
|
565
577
|
display: flex;
|
|
566
578
|
flex-direction: column;
|
|
567
|
-
gap:
|
|
568
|
-
min-width:
|
|
569
|
-
padding:
|
|
579
|
+
gap: 10px;
|
|
580
|
+
min-width: 180px;
|
|
581
|
+
padding: 12px 14px;
|
|
570
582
|
border: 1px solid var(--dsw-alias-border-secondary, #ffffff1f);
|
|
571
583
|
border-radius: var(--dsw-radius-md, 10px);
|
|
572
584
|
background: var(--dsw-alias-bg-layer-2, #26262a);
|
|
@@ -581,7 +593,7 @@ const usageChipCss = `
|
|
|
581
593
|
.dsh-subscription-usage-chip-meter {
|
|
582
594
|
display: flex;
|
|
583
595
|
flex-direction: column;
|
|
584
|
-
gap:
|
|
596
|
+
gap: 5px;
|
|
585
597
|
}
|
|
586
598
|
.dsh-subscription-usage-chip-meterHead {
|
|
587
599
|
display: flex;
|
|
@@ -2300,14 +2312,16 @@ function balanceOf(value) {
|
|
|
2300
2312
|
* Format one wallet for the chip's compact line.
|
|
2301
2313
|
*
|
|
2302
2314
|
* A balance is money, not a percentage, so it renders as `¥6.89` rather than a meter;
|
|
2303
|
-
* the currency prefix keeps two currencies from being mistaken for one sum.
|
|
2315
|
+
* the currency prefix keeps two currencies from being mistaken for one sum. The amount
|
|
2316
|
+
* is rounded to two decimal places (a balance reads to the cent, and a figure like
|
|
2317
|
+
* `1.1` for `1.10` would mislead) and always carries both places.
|
|
2304
2318
|
*
|
|
2305
2319
|
* @param wallet - the wallet to show.
|
|
2306
|
-
* @returns the short form, e.g. `¥6.89` or
|
|
2320
|
+
* @returns the short form, e.g. `¥6.89` or `+$2.00` for a bonus wallet.
|
|
2307
2321
|
*/
|
|
2308
2322
|
function formatBalance(wallet) {
|
|
2309
2323
|
const amount = Number.parseFloat(wallet.balance);
|
|
2310
|
-
const trimmed = Number.isFinite(amount) ?
|
|
2324
|
+
const trimmed = Number.isFinite(amount) ? amount.toFixed(2) : wallet.balance;
|
|
2311
2325
|
const symbol = wallet.currency === "CNY" ? "¥" : wallet.currency === "USD" ? "$" : `${wallet.currency} `;
|
|
2312
2326
|
return `${wallet.bonus ? "+" : ""}${symbol}${trimmed}`;
|
|
2313
2327
|
}
|
|
@@ -2336,43 +2350,78 @@ function shortWindow(label) {
|
|
|
2336
2350
|
return label.length <= 4 ? label : label.slice(0, 4);
|
|
2337
2351
|
}
|
|
2338
2352
|
/**
|
|
2339
|
-
*
|
|
2353
|
+
* Reduce a route's per-account usage to one reading per account.
|
|
2340
2354
|
*
|
|
2341
|
-
* A
|
|
2342
|
-
*
|
|
2343
|
-
*
|
|
2355
|
+
* A provider can hold several accounts (two Antigravity sign-ins, say), and the chip
|
|
2356
|
+
* shows each one's allowance on its own line, the way the settings cards do — a merged
|
|
2357
|
+
* figure would hide that one account is exhausted while the other is free.
|
|
2344
2358
|
*
|
|
2345
|
-
* @param
|
|
2346
|
-
* @returns
|
|
2359
|
+
* @param usage - every account the route answered for.
|
|
2360
|
+
* @returns one reading per account that states a figure, in the route's order.
|
|
2347
2361
|
*/
|
|
2348
|
-
|
|
2349
|
-
|
|
2350
|
-
|
|
2351
|
-
|
|
2352
|
-
|
|
2362
|
+
/**
|
|
2363
|
+
* Reduce a route's per-account usage to one reading per account.
|
|
2364
|
+
*
|
|
2365
|
+
* A provider can hold several accounts (two Antigravity sign-ins, say). Every account's
|
|
2366
|
+
* windows are kept as the route stated them — a percentage-metered quota and a credit
|
|
2367
|
+
* balance (`credits`) alike — so the per-account panel shows the real figures, and the
|
|
2368
|
+
* compact line's merge decides which to integrate.
|
|
2369
|
+
*
|
|
2370
|
+
* @param usage - every account the route answered for.
|
|
2371
|
+
* @returns one reading per account that states any window, in the route's order.
|
|
2372
|
+
*/
|
|
2373
|
+
function accountReadingsOf(usage) {
|
|
2374
|
+
const out = [];
|
|
2375
|
+
for (const entry of usage) {
|
|
2376
|
+
if (entry.windows.length === 0) continue;
|
|
2377
|
+
out.push({
|
|
2378
|
+
account: entry.account,
|
|
2379
|
+
windows: entry.windows,
|
|
2380
|
+
...entry.plan === void 0 ? {} : { plan: entry.plan }
|
|
2381
|
+
});
|
|
2353
2382
|
}
|
|
2354
|
-
return
|
|
2383
|
+
return out;
|
|
2355
2384
|
}
|
|
2356
2385
|
/**
|
|
2357
|
-
*
|
|
2386
|
+
* Merge every account's percentage-metered windows into one figure per label.
|
|
2387
|
+
*
|
|
2388
|
+
* The chip's compact line integrates the whole pool: two accounts at 50 percent read as
|
|
2389
|
+
* one window at 50 percent (the same allowance spent twice as wide), not two lines. A
|
|
2390
|
+
* credit balance (`credits`) is money, not a share of a shared allowance, so it is not
|
|
2391
|
+
* merged — it stays on the per-account panel, where it reads correctly. Only windows
|
|
2392
|
+
* that state a `usedPercent` (a share of an allowance) merge.
|
|
2358
2393
|
*
|
|
2359
|
-
* @param
|
|
2360
|
-
* @
|
|
2361
|
-
* @param usage - the accounts the route answered for.
|
|
2362
|
-
* @returns the reading, or undefined when the route stated no figure.
|
|
2394
|
+
* @param readings - one per account, from {@link accountReadingsOf}.
|
|
2395
|
+
* @returns one merged window per percentage-metered label, most-spent first.
|
|
2363
2396
|
*/
|
|
2364
|
-
function
|
|
2365
|
-
|
|
2366
|
-
|
|
2367
|
-
if (window$1 === void 0) continue;
|
|
2368
|
-
|
|
2369
|
-
|
|
2397
|
+
function mergeAccountWindows(readings) {
|
|
2398
|
+
const byLabel = /* @__PURE__ */ new Map();
|
|
2399
|
+
for (const reading of readings) for (const window$1 of reading.windows) {
|
|
2400
|
+
if (window$1.usedPercent === void 0) continue;
|
|
2401
|
+
const list = byLabel.get(window$1.label) ?? [];
|
|
2402
|
+
list.push(window$1);
|
|
2403
|
+
byLabel.set(window$1.label, list);
|
|
2404
|
+
}
|
|
2405
|
+
const merged = [];
|
|
2406
|
+
for (const [label, list] of byLabel) {
|
|
2407
|
+
const withPercent = list.filter((window$1) => window$1.usedPercent !== void 0);
|
|
2408
|
+
if (withPercent.length === 0) continue;
|
|
2409
|
+
const usedPercent = withPercent.reduce((sum, window$1) => sum + (window$1.usedPercent ?? 0), 0) / withPercent.length;
|
|
2410
|
+
const resets = list.map((window$1) => window$1.resetsAt).filter((at) => typeof at === "number");
|
|
2411
|
+
merged.push({
|
|
2370
2412
|
label,
|
|
2371
|
-
|
|
2372
|
-
|
|
2373
|
-
|
|
2374
|
-
};
|
|
2413
|
+
usedPercent: Math.max(0, Math.min(100, usedPercent)),
|
|
2414
|
+
...resets.length === 0 ? {} : { resetsAt: Math.min(...resets) }
|
|
2415
|
+
});
|
|
2375
2416
|
}
|
|
2417
|
+
const order = (label) => {
|
|
2418
|
+
const short = shortWindow(label);
|
|
2419
|
+
if (short === "5h" || short === "s") return 0;
|
|
2420
|
+
if (short === "1d" || short === "mo") return 1;
|
|
2421
|
+
if (short === "7d") return 2;
|
|
2422
|
+
return 3;
|
|
2423
|
+
};
|
|
2424
|
+
return merged.sort((left, right) => order(left.label) - order(right.label));
|
|
2376
2425
|
}
|
|
2377
2426
|
/**
|
|
2378
2427
|
* Format a window's reset the way the settings cards do.
|
|
@@ -2402,6 +2451,7 @@ function formatReset(at, now) {
|
|
|
2402
2451
|
*/
|
|
2403
2452
|
function UsageChip({ call, t, isOwnProvider, accountBalance, ccSwitchBalance, useProjection }) {
|
|
2404
2453
|
const [reading, setReading] = (0, react.useState)(void 0);
|
|
2454
|
+
const [accountReadings, setAccountReadings] = (0, react.useState)(void 0);
|
|
2405
2455
|
const [balance, setBalance] = (0, react.useState)(void 0);
|
|
2406
2456
|
const [ccBalance, setCcBalance] = (0, react.useState)(void 0);
|
|
2407
2457
|
const [now, setNow] = (0, react.useState)(() => Date.now());
|
|
@@ -2438,8 +2488,7 @@ function UsageChip({ call, t, isOwnProvider, accountBalance, ccSwitchBalance, us
|
|
|
2438
2488
|
]);
|
|
2439
2489
|
const load = (0, react.useCallback)(async (target) => {
|
|
2440
2490
|
try {
|
|
2441
|
-
|
|
2442
|
-
return readingOf(target, result.status.providers.find((entry) => entry.provider === target)?.displayName ?? target, result.usage);
|
|
2491
|
+
return accountReadingsOf((await call("usage", { provider: target })).usage);
|
|
2443
2492
|
} catch {
|
|
2444
2493
|
return;
|
|
2445
2494
|
}
|
|
@@ -2465,7 +2514,7 @@ function UsageChip({ call, t, isOwnProvider, accountBalance, ccSwitchBalance, us
|
|
|
2465
2514
|
(0, react.useEffect)(() => {
|
|
2466
2515
|
const target = selected !== void 0 && isOwnProvider(selected) ? selected : lastOwn.current;
|
|
2467
2516
|
if (target === void 0) {
|
|
2468
|
-
|
|
2517
|
+
setAccountReadings(void 0);
|
|
2469
2518
|
return;
|
|
2470
2519
|
}
|
|
2471
2520
|
let live = true;
|
|
@@ -2474,7 +2523,7 @@ function UsageChip({ call, t, isOwnProvider, accountBalance, ccSwitchBalance, us
|
|
|
2474
2523
|
load(target).then((next) => {
|
|
2475
2524
|
if (!live || next === void 0) return;
|
|
2476
2525
|
lastOwn.current = target;
|
|
2477
|
-
|
|
2526
|
+
setAccountReadings(next);
|
|
2478
2527
|
});
|
|
2479
2528
|
};
|
|
2480
2529
|
refresh();
|
|
@@ -2592,10 +2641,9 @@ function UsageChip({ call, t, isOwnProvider, accountBalance, ccSwitchBalance, us
|
|
|
2592
2641
|
]
|
|
2593
2642
|
});
|
|
2594
2643
|
}
|
|
2595
|
-
if (
|
|
2596
|
-
|
|
2597
|
-
|
|
2598
|
-
const short = shortLabel(reading.provider, reading.label);
|
|
2644
|
+
if (accountReadings === void 0 || accountReadings.length === 0) return null;
|
|
2645
|
+
const short = shortLabel(selected ?? "", selected ?? "");
|
|
2646
|
+
const merged = mergeAccountWindows(accountReadings);
|
|
2599
2647
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
2600
2648
|
className: "dsh-subscription-usage-chip",
|
|
2601
2649
|
children: [
|
|
@@ -2604,7 +2652,7 @@ function UsageChip({ call, t, isOwnProvider, accountBalance, ccSwitchBalance, us
|
|
|
2604
2652
|
type: "button",
|
|
2605
2653
|
className: "dsh-subscription-usage-chip-trigger",
|
|
2606
2654
|
"aria-expanded": open,
|
|
2607
|
-
title: t("usageChipTitle", { provider:
|
|
2655
|
+
title: t("usageChipTitle", { provider: selected ?? "" }),
|
|
2608
2656
|
onClick: (event) => {
|
|
2609
2657
|
event.stopPropagation();
|
|
2610
2658
|
setOpen((was) => !was);
|
|
@@ -2612,7 +2660,7 @@ function UsageChip({ call, t, isOwnProvider, accountBalance, ccSwitchBalance, us
|
|
|
2612
2660
|
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
2613
2661
|
className: "dsh-subscription-usage-chip-label",
|
|
2614
2662
|
children: short
|
|
2615
|
-
}),
|
|
2663
|
+
}), merged.map((window$1) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
2616
2664
|
className: "dsh-subscription-usage-chip-cell",
|
|
2617
2665
|
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
2618
2666
|
className: "dsh-subscription-usage-chip-window",
|
|
@@ -2626,22 +2674,26 @@ function UsageChip({ call, t, isOwnProvider, accountBalance, ccSwitchBalance, us
|
|
|
2626
2674
|
open && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
2627
2675
|
className: "dsh-subscription-usage-chip-panel",
|
|
2628
2676
|
role: "status",
|
|
2629
|
-
children: [
|
|
2630
|
-
|
|
2631
|
-
|
|
2632
|
-
|
|
2633
|
-
|
|
2634
|
-
|
|
2677
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
2678
|
+
className: "dsh-subscription-usage-chip-full",
|
|
2679
|
+
children: t("usageChipFull", { provider: selected ?? "" })
|
|
2680
|
+
}), accountReadings.map((account) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
2681
|
+
className: "dsh-subscription-usage-chip-account",
|
|
2682
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
2683
|
+
className: "dsh-subscription-usage-chip-meterHead",
|
|
2684
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: account.plan ?? account.account })
|
|
2685
|
+
}), account.windows.map((window$1) => {
|
|
2635
2686
|
const windowReset = formatReset(window$1.resetsAt, now);
|
|
2687
|
+
const amount = window$1.usedPercent === void 0 && window$1.used !== void 0 && window$1.limit !== void 0 ? `${String(window$1.used)}/${String(window$1.limit)}` : `${String(Math.round(window$1.usedPercent ?? 0))}%`;
|
|
2636
2688
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
2637
2689
|
className: "dsh-subscription-usage-chip-meter",
|
|
2638
2690
|
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
2639
2691
|
className: "dsh-subscription-usage-chip-meterHead",
|
|
2640
2692
|
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: window$1.label }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
2641
2693
|
className: "dsh-subscription-usage-chip-detail",
|
|
2642
|
-
children: `${
|
|
2694
|
+
children: `${amount}${windowReset === void 0 ? "" : ` · ${windowReset}`}`
|
|
2643
2695
|
})]
|
|
2644
|
-
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
2696
|
+
}), window$1.usedPercent !== void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
2645
2697
|
className: "dsh-subscription-usage-chip-track",
|
|
2646
2698
|
"aria-hidden": "true",
|
|
2647
2699
|
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
@@ -2650,12 +2702,8 @@ function UsageChip({ call, t, isOwnProvider, accountBalance, ccSwitchBalance, us
|
|
|
2650
2702
|
})
|
|
2651
2703
|
})]
|
|
2652
2704
|
}, window$1.label);
|
|
2653
|
-
})
|
|
2654
|
-
|
|
2655
|
-
className: "dsh-subscription-usage-chip-detail",
|
|
2656
|
-
children: reading.plan
|
|
2657
|
-
})
|
|
2658
|
-
]
|
|
2705
|
+
})]
|
|
2706
|
+
}, account.account))]
|
|
2659
2707
|
})
|
|
2660
2708
|
]
|
|
2661
2709
|
});
|