pi-provider-qoder-cn 0.2.22 → 0.2.24
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 +4 -0
- package/dist/index.js +45 -37
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -144,6 +144,10 @@ Notes:
|
|
|
144
144
|
latest grant`, and an account that has never claimed prints no expiry line at
|
|
145
145
|
all, because with no grant there is nothing to date from, and inventing one
|
|
146
146
|
would show dates the API never sent.
|
|
147
|
+
- `Enterprise` is the org-wide pool. It names its allowance `cap` and sends no
|
|
148
|
+
`total`, so the row is keyed on any of `cap`, `used` or `remaining` carrying a
|
|
149
|
+
value: a freshly refreshed cycle reports `used: 0`, and that used to drop the
|
|
150
|
+
whole row and leave the view saying `Buckets none returned`.
|
|
147
151
|
- `Expires never` means the API reported the year-9999 sentinel, i.e. the
|
|
148
152
|
allowance has no expiry date.
|
|
149
153
|
- `Note plan quota is prorated` appears after a mid-cycle plan change.
|
package/dist/index.js
CHANGED
|
@@ -1791,29 +1791,36 @@ var init_oauth = __esm({
|
|
|
1791
1791
|
// src/index.ts
|
|
1792
1792
|
init_oauth();
|
|
1793
1793
|
|
|
1794
|
-
// src/
|
|
1795
|
-
|
|
1796
|
-
function num(value) {
|
|
1794
|
+
// src/quota.ts
|
|
1795
|
+
function quotaNumber(value) {
|
|
1797
1796
|
return typeof value === "number" && Number.isFinite(value) ? value : 0;
|
|
1798
1797
|
}
|
|
1799
|
-
function
|
|
1800
|
-
return
|
|
1798
|
+
function bucketLimit(bucket) {
|
|
1799
|
+
return quotaNumber(bucket.total ?? bucket.cap);
|
|
1801
1800
|
}
|
|
1802
1801
|
function hasAllowance(bucket) {
|
|
1803
1802
|
if (!bucket) return false;
|
|
1804
|
-
return
|
|
1803
|
+
return bucketLimit(bucket) > 0 || quotaNumber(bucket.used) > 0 || quotaNumber(bucket.remaining) > 0;
|
|
1804
|
+
}
|
|
1805
|
+
function pickBucket(raw, camel) {
|
|
1806
|
+
if (!raw) return void 0;
|
|
1807
|
+
const source = raw;
|
|
1808
|
+
const snake = camel.replace(/[A-Z]/g, (c) => `_${c.toLowerCase()}`);
|
|
1809
|
+
return source[snake] ?? source[camel];
|
|
1810
|
+
}
|
|
1811
|
+
|
|
1812
|
+
// src/auth/usage.ts
|
|
1813
|
+
init_region();
|
|
1814
|
+
function round2(value) {
|
|
1815
|
+
return Math.round(value * 100) / 100;
|
|
1805
1816
|
}
|
|
1806
1817
|
function resetTimestamp(expiresAt) {
|
|
1807
|
-
const ms =
|
|
1818
|
+
const ms = quotaNumber(expiresAt);
|
|
1808
1819
|
if (ms <= 0) return void 0;
|
|
1809
1820
|
const timestamp = ms < 1e12 ? ms * 1e3 : ms;
|
|
1810
1821
|
if (new Date(timestamp).getUTCFullYear() >= 9999) return void 0;
|
|
1811
1822
|
return new Date(timestamp).toISOString();
|
|
1812
1823
|
}
|
|
1813
|
-
function pickBucket(raw, camel) {
|
|
1814
|
-
const snake = camel.replace(/[A-Z]/g, (c) => `_${c.toLowerCase()}`);
|
|
1815
|
-
return raw[snake] ?? raw[camel];
|
|
1816
|
-
}
|
|
1817
1824
|
async function fetchQoderUsageForMode(credentials, mode) {
|
|
1818
1825
|
const region = getQoderRegionConfig(mode);
|
|
1819
1826
|
const response = await fetch(getQoderUsageURL(mode), {
|
|
@@ -1838,12 +1845,12 @@ async function fetchQoderUsageForMode(credentials, mode) {
|
|
|
1838
1845
|
const usageBuckets = buckets.map(({ id, label, quota }) => ({
|
|
1839
1846
|
id,
|
|
1840
1847
|
label,
|
|
1841
|
-
usedDisplay: round2(
|
|
1842
|
-
limitDisplay: round2(
|
|
1848
|
+
usedDisplay: round2(quotaNumber(quota?.used)).toFixed(2),
|
|
1849
|
+
limitDisplay: round2(quotaNumber(quota?.total ?? quota?.cap)).toFixed(2),
|
|
1843
1850
|
unit: quota?.unit || "credits",
|
|
1844
1851
|
resetAt
|
|
1845
1852
|
}));
|
|
1846
|
-
const remaining = buckets.reduce((sum, { quota }) => sum + Math.max(0,
|
|
1853
|
+
const remaining = buckets.reduce((sum, { quota }) => sum + Math.max(0, quotaNumber(quota?.remaining)), 0);
|
|
1847
1854
|
const unit = buckets[0]?.quota?.unit || "credits";
|
|
1848
1855
|
return {
|
|
1849
1856
|
summary: buckets.length > 0 ? `${round2(remaining)} ${unit} remaining` : "",
|
|
@@ -2448,6 +2455,11 @@ function getBeijingDailyResetCountdown(now = Date.now()) {
|
|
|
2448
2455
|
const minutes = totalMinutes % 60;
|
|
2449
2456
|
return hours > 0 ? `${hours}\u5C0F\u65F6${minutes}\u5206\u949F` : `${minutes}\u5206\u949F`;
|
|
2450
2457
|
}
|
|
2458
|
+
var CREDENTIAL_EXPIRED_CODES = /* @__PURE__ */ new Set(["105", "TOKEN_EXPIRE", "TOKEN_EXPIRED"]);
|
|
2459
|
+
var CREDENTIAL_EXPIRED_MESSAGE = /token expired|login expired|token is not active|token has expired/i;
|
|
2460
|
+
function isCredentialExpiredVerdict(code, message) {
|
|
2461
|
+
return code !== void 0 && CREDENTIAL_EXPIRED_CODES.has(code) || CREDENTIAL_EXPIRED_MESSAGE.test(message);
|
|
2462
|
+
}
|
|
2451
2463
|
function formatQoderStreamError(statusCode, rawBody, now = Date.now(), mode = "cn") {
|
|
2452
2464
|
const parsed = parseQoderErrorPayload(rawBody);
|
|
2453
2465
|
const code = parsed?.code;
|
|
@@ -2527,7 +2539,7 @@ function formatQoderStreamError(statusCode, rawBody, now = Date.now(), mode = "c
|
|
|
2527
2539
|
`- Fix: purchase a credit pack at ${store}, or wait for the next billing cycle.`
|
|
2528
2540
|
].join("\n");
|
|
2529
2541
|
}
|
|
2530
|
-
if (code
|
|
2542
|
+
if (isCredentialExpiredVerdict(code, message)) {
|
|
2531
2543
|
if (isCn) {
|
|
2532
2544
|
return [
|
|
2533
2545
|
`[Qoder CN \u51ED\u8BC1\u5931\u6548] \u767B\u5F55\u6001\u5DF2\u8FC7\u671F\u6216 Token \u5931\u6548 (\u9519\u8BEF\u7801 105)`,
|
|
@@ -2591,7 +2603,8 @@ function formatQoderStreamError(statusCode, rawBody, now = Date.now(), mode = "c
|
|
|
2591
2603
|
}
|
|
2592
2604
|
function isCredentialExpiredError(error) {
|
|
2593
2605
|
const message = error instanceof Error ? error.message : String(error ?? "");
|
|
2594
|
-
|
|
2606
|
+
if (message.includes("\u9519\u8BEF\u7801 105") || message.includes("\u51ED\u8BC1\u5931\u6548")) return true;
|
|
2607
|
+
return isCredentialExpiredVerdict(void 0, message) || /TOKEN_EXPIRED?/i.test(message);
|
|
2595
2608
|
}
|
|
2596
2609
|
|
|
2597
2610
|
// src/commands/usage.ts
|
|
@@ -2744,33 +2757,28 @@ function bucketRow(label, bucket, danger) {
|
|
|
2744
2757
|
danger
|
|
2745
2758
|
};
|
|
2746
2759
|
}
|
|
2747
|
-
function hasBucket(bucket) {
|
|
2748
|
-
if (!bucket) return false;
|
|
2749
|
-
return (bucket.total ?? 0) > 0 || (bucket.used ?? 0) > 0;
|
|
2750
|
-
}
|
|
2751
|
-
function pickBucket2(raw, camel) {
|
|
2752
|
-
if (!raw) return void 0;
|
|
2753
|
-
const snake = camel.replace(/[A-Z]/g, (c) => `_${c.toLowerCase()}`);
|
|
2754
|
-
return raw[snake] ?? raw[camel];
|
|
2755
|
-
}
|
|
2756
2760
|
function formatQoderUsage(raw, mode, now = Date.now(), options = {}) {
|
|
2757
2761
|
const color = options.color ?? false;
|
|
2758
2762
|
const region = getQoderRegionConfig(mode);
|
|
2759
2763
|
const danger = Boolean(raw?.isQuotaExceeded);
|
|
2760
2764
|
const userType = raw?.userType ? ` (${raw.userType})` : "";
|
|
2761
|
-
const showUserQuota =
|
|
2762
|
-
const showAddOnQuota =
|
|
2763
|
-
const org =
|
|
2764
|
-
const showOrg =
|
|
2765
|
-
const
|
|
2765
|
+
const showUserQuota = hasAllowance(pickBucket(raw, "userQuota"));
|
|
2766
|
+
const showAddOnQuota = hasAllowance(pickBucket(raw, "addOnQuota"));
|
|
2767
|
+
const org = pickBucket(raw, "orgResourcePackage") ?? pickBucket(raw, "sharedQuota");
|
|
2768
|
+
const showOrg = hasAllowance(org);
|
|
2769
|
+
const orgLimit = org ? bucketLimit(org) : 0;
|
|
2770
|
+
const orgPercent = org && orgLimit > 0 ? formatPercent(quotaNumber(org.used) / orgLimit * 100) : void 0;
|
|
2766
2771
|
const overallPercent = formatPercent(
|
|
2767
|
-
showOrg ? normalizePercent(raw?.totalUsagePercentage)
|
|
2772
|
+
showOrg ? orgPercent ?? normalizePercent(raw?.totalUsagePercentage) : normalizePercent(raw?.totalUsagePercentage)
|
|
2768
2773
|
);
|
|
2769
2774
|
const rows = [{ label: "Overall", percent: overallPercent, tail: "used", danger }];
|
|
2770
|
-
if (showUserQuota) rows.push(bucketRow("Plan quota",
|
|
2771
|
-
if (showAddOnQuota) rows.push(bucketRow("Add-on",
|
|
2772
|
-
if (showOrg && org)
|
|
2773
|
-
rows.push(
|
|
2775
|
+
if (showUserQuota) rows.push(bucketRow("Plan quota", pickBucket(raw, "userQuota"), danger));
|
|
2776
|
+
if (showAddOnQuota) rows.push(bucketRow("Add-on", pickBucket(raw, "addOnQuota"), danger));
|
|
2777
|
+
if (showOrg && org) {
|
|
2778
|
+
rows.push(
|
|
2779
|
+
bucketRow("Enterprise", { ...org, percentage: void 0, total: orgLimit, used: quotaNumber(org.used) }, danger)
|
|
2780
|
+
);
|
|
2781
|
+
}
|
|
2774
2782
|
const isPersonalStandard = raw?.userType === "personal_standard" || raw?.userType === "free";
|
|
2775
2783
|
const notes = [];
|
|
2776
2784
|
if (danger) {
|
|
@@ -2808,7 +2816,7 @@ function formatQoderUsage(raw, mode, now = Date.now(), options = {}) {
|
|
|
2808
2816
|
});
|
|
2809
2817
|
}
|
|
2810
2818
|
}
|
|
2811
|
-
const addOn =
|
|
2819
|
+
const addOn = pickBucket(raw, "addOnQuota");
|
|
2812
2820
|
if (showAddOnQuota && (addOn?.remaining ?? 0) > 0 && checkin) {
|
|
2813
2821
|
const expiryMs = checkin.expiresAt ? Date.parse(checkin.expiresAt) : void 0;
|
|
2814
2822
|
const grant = { expiryMs, amount: checkin.amount, validityDays: checkin.validityDays };
|
|
@@ -3518,7 +3526,7 @@ async function peekCredentialExpired(reader, decoder) {
|
|
|
3518
3526
|
if (typeof envelope.statusCodeValue === "number" && envelope.statusCodeValue !== 200) {
|
|
3519
3527
|
const parsed = parseQoderErrorPayload(envelope.body);
|
|
3520
3528
|
const message = parsed?.message ?? (typeof envelope.body === "string" ? envelope.body : "");
|
|
3521
|
-
return parsed?.code
|
|
3529
|
+
return isCredentialExpiredVerdict(parsed?.code, message);
|
|
3522
3530
|
}
|
|
3523
3531
|
return false;
|
|
3524
3532
|
} catch {
|
package/package.json
CHANGED