dsh-plugin-subscription-oauth 0.5.0 → 0.6.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/deepseek-balance.d.ts +58 -0
- package/lib/auth/deepseek-balance.js +63 -0
- package/lib/auth/rpc.d.ts +25 -2
- package/lib/auth/rpc.js +45 -23
- package/lib/client/UsageChip.d.ts +13 -23
- package/lib/client/UsageChip.js +27 -28
- package/lib/client/index.js +0 -14
- package/lib/client/subscriptions-rpc.d.ts +21 -20
- package/lib/client/subscriptions-rpc.js +16 -14
- package/lib/client.js +34 -38
- package/lib/client.js.map +1 -1
- package/lib/index.d.ts +12 -0
- package/lib/index.js +33 -1
- package/lib/protocol.d.ts +33 -3
- package/lib/protocol.js +1 -0
- package/lib/providers/kimi.d.ts +8 -0
- package/lib/providers/kimi.js +27 -1
- package/lib/translate/moonshot-schema.d.ts +54 -0
- package/lib/translate/moonshot-schema.js +142 -0
- package/package.json +1 -1
|
@@ -10,9 +10,6 @@
|
|
|
10
10
|
import { RPC_PREFIX } from '../protocol.js';
|
|
11
11
|
/** The shared channel the node half's routes are mounted on. */
|
|
12
12
|
const CHANNEL = '/api';
|
|
13
|
-
/** The host's own DeepSeek account controller, from which the chip reads a balance. */
|
|
14
|
-
const ACCOUNT_CHANNEL = '/api';
|
|
15
|
-
const ACCOUNT_NAMESPACE = 'account';
|
|
16
13
|
/** A failed call: either the transport rejected or the endpoint answered `ok: false`. */
|
|
17
14
|
export class SubscriptionsRpcError extends Error {
|
|
18
15
|
code;
|
|
@@ -46,23 +43,25 @@ export function createSubscriptionsCall(rpc) {
|
|
|
46
43
|
};
|
|
47
44
|
}
|
|
48
45
|
/**
|
|
49
|
-
* Read the DeepSeek account's balance through the
|
|
46
|
+
* Read the DeepSeek account's balance through the plugin's own RPC.
|
|
50
47
|
*
|
|
51
|
-
* The
|
|
52
|
-
*
|
|
53
|
-
* the
|
|
48
|
+
* The browser cannot call the host's account service directly — it sits behind the
|
|
49
|
+
* host's Remote controller, not a `/api` fetch route — so the node half reads it and
|
|
50
|
+
* serves it on the plugin's channel, the same one the rest of the chip's data travels.
|
|
54
51
|
*
|
|
55
52
|
* @param rpc - the browser connection's RPC caller.
|
|
56
|
-
* @returns the balance, or
|
|
53
|
+
* @returns the balance, or undefined when there is nothing to show.
|
|
57
54
|
*/
|
|
58
55
|
export function createAccountBalanceCall(rpc) {
|
|
59
56
|
return async function call() {
|
|
60
57
|
let result;
|
|
61
58
|
try {
|
|
62
|
-
result = await rpc.call(
|
|
59
|
+
result = await rpc.call(CHANNEL, `${RPC_PREFIX}deepseek-balance`, {
|
|
63
60
|
version: '1',
|
|
64
61
|
locale: Intl.DateTimeFormat().resolvedOptions().locale ?? 'en-US',
|
|
65
|
-
|
|
62
|
+
// East-positive whole seconds, as the host's account service expects (the same
|
|
63
|
+
// value DSH's own account card sends).
|
|
64
|
+
timezoneOffsetSeconds: -new Date().getTimezoneOffset() * 60,
|
|
66
65
|
});
|
|
67
66
|
}
|
|
68
67
|
catch (error) {
|
|
@@ -77,18 +76,21 @@ export function createAccountBalanceCall(rpc) {
|
|
|
77
76
|
* Read a manually added provider's balance through the plugin's cc-switch endpoint.
|
|
78
77
|
*
|
|
79
78
|
* The caller names the credential reference the provider's profile uses (its
|
|
80
|
-
*
|
|
79
|
+
* Read a non-subscription provider's balance through the plugin's cc-switch endpoint.
|
|
80
|
+
*
|
|
81
|
+
* The caller names the provider; the server maps it to the credential reference the
|
|
82
|
+
* provider's profile names (`apiKeyEnv`) and resolves that to the API key. The result
|
|
81
83
|
* is `undefined` when there is no key or the provider did not answer — never a wrong
|
|
82
84
|
* figure.
|
|
83
85
|
*
|
|
84
86
|
* @param rpc - the browser connection's RPC caller.
|
|
85
|
-
* @returns a narrow caller taking the
|
|
87
|
+
* @returns a narrow caller taking the provider id.
|
|
86
88
|
*/
|
|
87
89
|
export function createCcSwitchBalanceCall(rpc) {
|
|
88
|
-
return async function call(
|
|
90
|
+
return async function call(provider) {
|
|
89
91
|
let result;
|
|
90
92
|
try {
|
|
91
|
-
result = await rpc.call(CHANNEL, `${RPC_PREFIX}ccswitch-balance`, {
|
|
93
|
+
result = await rpc.call(CHANNEL, `${RPC_PREFIX}ccswitch-balance`, { provider });
|
|
92
94
|
}
|
|
93
95
|
catch (error) {
|
|
94
96
|
throw new SubscriptionsRpcError(messageOf(error), 'RPC_TRANSPORT');
|
package/lib/client.js
CHANGED
|
@@ -632,8 +632,6 @@ const RPC_PREFIX = "subscription-oauth.";
|
|
|
632
632
|
//#region src/client/subscriptions-rpc.ts
|
|
633
633
|
/** The shared channel the node half's routes are mounted on. */
|
|
634
634
|
const CHANNEL = "/api";
|
|
635
|
-
/** The host's own DeepSeek account controller, from which the chip reads a balance. */
|
|
636
|
-
const ACCOUNT_CHANNEL = "/api";
|
|
637
635
|
/** A failed call: either the transport rejected or the endpoint answered `ok: false`. */
|
|
638
636
|
var SubscriptionsRpcError = class extends Error {
|
|
639
637
|
constructor(message, code) {
|
|
@@ -664,23 +662,23 @@ function createSubscriptionsCall(rpc) {
|
|
|
664
662
|
};
|
|
665
663
|
}
|
|
666
664
|
/**
|
|
667
|
-
* Read the DeepSeek account's balance through the
|
|
665
|
+
* Read the DeepSeek account's balance through the plugin's own RPC.
|
|
668
666
|
*
|
|
669
|
-
* The
|
|
670
|
-
*
|
|
671
|
-
* the
|
|
667
|
+
* The browser cannot call the host's account service directly — it sits behind the
|
|
668
|
+
* host's Remote controller, not a `/api` fetch route — so the node half reads it and
|
|
669
|
+
* serves it on the plugin's channel, the same one the rest of the chip's data travels.
|
|
672
670
|
*
|
|
673
671
|
* @param rpc - the browser connection's RPC caller.
|
|
674
|
-
* @returns the balance, or
|
|
672
|
+
* @returns the balance, or undefined when there is nothing to show.
|
|
675
673
|
*/
|
|
676
674
|
function createAccountBalanceCall(rpc) {
|
|
677
675
|
return async function call() {
|
|
678
676
|
let result;
|
|
679
677
|
try {
|
|
680
|
-
result = await rpc.call(
|
|
678
|
+
result = await rpc.call(CHANNEL, `${RPC_PREFIX}deepseek-balance`, {
|
|
681
679
|
version: "1",
|
|
682
680
|
locale: Intl.DateTimeFormat().resolvedOptions().locale ?? "en-US",
|
|
683
|
-
timezoneOffsetSeconds: -(/* @__PURE__ */ new Date()).getTimezoneOffset()
|
|
681
|
+
timezoneOffsetSeconds: -(/* @__PURE__ */ new Date()).getTimezoneOffset() * 60
|
|
684
682
|
});
|
|
685
683
|
} catch (error) {
|
|
686
684
|
throw new SubscriptionsRpcError(messageOf$1(error), "RPC_TRANSPORT");
|
|
@@ -693,18 +691,21 @@ function createAccountBalanceCall(rpc) {
|
|
|
693
691
|
* Read a manually added provider's balance through the plugin's cc-switch endpoint.
|
|
694
692
|
*
|
|
695
693
|
* The caller names the credential reference the provider's profile uses (its
|
|
696
|
-
*
|
|
694
|
+
* Read a non-subscription provider's balance through the plugin's cc-switch endpoint.
|
|
695
|
+
*
|
|
696
|
+
* The caller names the provider; the server maps it to the credential reference the
|
|
697
|
+
* provider's profile names (`apiKeyEnv`) and resolves that to the API key. The result
|
|
697
698
|
* is `undefined` when there is no key or the provider did not answer — never a wrong
|
|
698
699
|
* figure.
|
|
699
700
|
*
|
|
700
701
|
* @param rpc - the browser connection's RPC caller.
|
|
701
|
-
* @returns a narrow caller taking the
|
|
702
|
+
* @returns a narrow caller taking the provider id.
|
|
702
703
|
*/
|
|
703
704
|
function createCcSwitchBalanceCall(rpc) {
|
|
704
|
-
return async function call(
|
|
705
|
+
return async function call(provider) {
|
|
705
706
|
let result;
|
|
706
707
|
try {
|
|
707
|
-
result = await rpc.call(CHANNEL, `${RPC_PREFIX}ccswitch-balance`, {
|
|
708
|
+
result = await rpc.call(CHANNEL, `${RPC_PREFIX}ccswitch-balance`, { provider });
|
|
708
709
|
} catch (error) {
|
|
709
710
|
throw new SubscriptionsRpcError(messageOf$1(error), "RPC_TRANSPORT");
|
|
710
711
|
}
|
|
@@ -2272,21 +2273,23 @@ function providerOf(projection) {
|
|
|
2272
2273
|
return (projection?.next ?? projection?.lastUsed)?.provider;
|
|
2273
2274
|
}
|
|
2274
2275
|
/**
|
|
2275
|
-
* Reduce the
|
|
2276
|
+
* Reduce the node half's balance payload to the wallets the chip shows.
|
|
2276
2277
|
*
|
|
2277
2278
|
* Bonus wallets are shown after the topped-up ones, so a reader sees their own credit
|
|
2278
|
-
* first and any promotional credit as a secondary figure.
|
|
2279
|
+
* first and any promotional credit as a secondary figure. A bonus wallet that holds
|
|
2280
|
+
* nothing is dropped rather than shown as `+¥0`: the platform reports one for every
|
|
2281
|
+
* currency whether or not there is a bonus, and an empty one is noise, not information.
|
|
2279
2282
|
*
|
|
2280
|
-
* @param value - the
|
|
2283
|
+
* @param value - the node half's balance, or undefined when there is none.
|
|
2281
2284
|
* @returns the wallets, topped-up first then bonus, or undefined when nothing is usable.
|
|
2282
2285
|
*/
|
|
2283
2286
|
function balanceOf(value) {
|
|
2284
|
-
if (value === null || value === void 0
|
|
2285
|
-
const wallets = [...value.
|
|
2287
|
+
if (value === null || value === void 0) return void 0;
|
|
2288
|
+
const wallets = [...(value.wallets ?? []).map((wallet) => ({
|
|
2286
2289
|
currency: wallet.currency,
|
|
2287
2290
|
balance: wallet.balance,
|
|
2288
2291
|
bonus: false
|
|
2289
|
-
})), ...(value.bonusWallets ?? []).map((wallet) => ({
|
|
2292
|
+
})), ...(value.bonusWallets ?? []).filter((wallet) => Number.parseFloat(wallet.balance) > 0).map((wallet) => ({
|
|
2290
2293
|
currency: wallet.currency,
|
|
2291
2294
|
balance: wallet.balance,
|
|
2292
2295
|
bonus: true
|
|
@@ -2397,7 +2400,7 @@ function formatReset(at, now) {
|
|
|
2397
2400
|
* @param props - injected RPC caller, copy, and the session's provider reader.
|
|
2398
2401
|
* @returns the chip, or null when there is nothing true to say.
|
|
2399
2402
|
*/
|
|
2400
|
-
function UsageChip({ call, t, isOwnProvider, accountBalance, ccSwitchBalance,
|
|
2403
|
+
function UsageChip({ call, t, isOwnProvider, accountBalance, ccSwitchBalance, useProjection }) {
|
|
2401
2404
|
const [reading, setReading] = (0, react.useState)(void 0);
|
|
2402
2405
|
const [balance, setBalance] = (0, react.useState)(void 0);
|
|
2403
2406
|
const [ccBalance, setCcBalance] = (0, react.useState)(void 0);
|
|
@@ -2406,15 +2409,16 @@ function UsageChip({ call, t, isOwnProvider, accountBalance, ccSwitchBalance, cc
|
|
|
2406
2409
|
const lastOwn = (0, react.useRef)(void 0);
|
|
2407
2410
|
const selected = useProjection("modelSelection", (value) => providerOf(value));
|
|
2408
2411
|
const isDeepSeek = selected === "deepseek-account";
|
|
2409
|
-
const
|
|
2412
|
+
const isBalanceProvider = selected !== void 0 && !isOwnProvider(selected) && !isDeepSeek;
|
|
2410
2413
|
(0, react.useEffect)(() => {
|
|
2411
|
-
if (
|
|
2414
|
+
if (!isBalanceProvider || selected === void 0) {
|
|
2412
2415
|
setCcBalance(void 0);
|
|
2413
2416
|
return;
|
|
2414
2417
|
}
|
|
2415
2418
|
let live = true;
|
|
2419
|
+
const target = selected;
|
|
2416
2420
|
const refresh = () => {
|
|
2417
|
-
ccSwitchBalance(
|
|
2421
|
+
ccSwitchBalance(target).then((value) => {
|
|
2418
2422
|
if (live) setCcBalance(value === void 0 ? void 0 : {
|
|
2419
2423
|
currency: value.currency,
|
|
2420
2424
|
total: value.total
|
|
@@ -2427,7 +2431,11 @@ function UsageChip({ call, t, isOwnProvider, accountBalance, ccSwitchBalance, cc
|
|
|
2427
2431
|
live = false;
|
|
2428
2432
|
clearInterval(timer);
|
|
2429
2433
|
};
|
|
2430
|
-
}, [
|
|
2434
|
+
}, [
|
|
2435
|
+
isBalanceProvider,
|
|
2436
|
+
selected,
|
|
2437
|
+
ccSwitchBalance
|
|
2438
|
+
]);
|
|
2431
2439
|
const load = (0, react.useCallback)(async (target) => {
|
|
2432
2440
|
try {
|
|
2433
2441
|
const result = await call("usage", { provider: target });
|
|
@@ -2490,7 +2498,7 @@ function UsageChip({ call, t, isOwnProvider, accountBalance, ccSwitchBalance, cc
|
|
|
2490
2498
|
document.removeEventListener("click", close);
|
|
2491
2499
|
};
|
|
2492
2500
|
}, [open]);
|
|
2493
|
-
if (
|
|
2501
|
+
if (isBalanceProvider) {
|
|
2494
2502
|
if (ccBalance === void 0) return null;
|
|
2495
2503
|
const short$1 = shortLabel(selected ?? "", selected ?? "");
|
|
2496
2504
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
@@ -2680,17 +2688,6 @@ const SECTION_ORDER = 92;
|
|
|
2680
2688
|
*/
|
|
2681
2689
|
const CHIP_ORDER = 10;
|
|
2682
2690
|
/**
|
|
2683
|
-
* The credential reference a manually added provider's balance query uses, by provider
|
|
2684
|
-
* id.
|
|
2685
|
-
*
|
|
2686
|
-
* A manually added provider is not one this plugin serves, so the only way to read its
|
|
2687
|
-
* balance is cc-switch's query, which needs the provider's API key. The provider's
|
|
2688
|
-
* profile names that key by reference (`apiKeyEnv`), and the host's credential service
|
|
2689
|
-
* resolves the name; this map is the one place a provider id is tied to that name. A
|
|
2690
|
-
* provider with no entry gets no balance.
|
|
2691
|
-
*/
|
|
2692
|
-
const CC_SWITCH_CREDENTIAL_REFS = { huanling: "HUANLING_API_KEY" };
|
|
2693
|
-
/**
|
|
2694
2691
|
* Required services: `slots` carries the registration seat, `connection` the
|
|
2695
2692
|
* RPC caller, and `locale` the copy dictionaries.
|
|
2696
2693
|
*/
|
|
@@ -2734,8 +2731,7 @@ function apply(ctx) {
|
|
|
2734
2731
|
t,
|
|
2735
2732
|
isOwnProvider: (provider) => OWN_PROVIDER_IDS.has(provider),
|
|
2736
2733
|
accountBalance: createAccountBalanceCall(connection.rpc),
|
|
2737
|
-
ccSwitchBalance: createCcSwitchBalanceCall(connection.rpc)
|
|
2738
|
-
ccSwitchCredentialRef: (provider) => CC_SWITCH_CREDENTIAL_REFS[provider]
|
|
2734
|
+
ccSwitchBalance: createCcSwitchBalanceCall(connection.rpc)
|
|
2739
2735
|
})
|
|
2740
2736
|
}, UsageChip));
|
|
2741
2737
|
}
|