pleumrouter 0.3.1 → 0.5.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 +7 -5
- package/bin/pleum.mjs +54 -37
- package/package.json +1 -1
- package/src/balance.mjs +5 -4
- package/src/completion.mjs +10 -7
- package/src/config.mjs +13 -8
- package/src/health.mjs +9 -8
- package/src/i18n.mjs +37 -0
- package/src/interactive.mjs +25 -99
- package/src/lang.mjs +33 -0
- package/src/launch.mjs +18 -16
- package/src/locales/es.mjs +218 -0
- package/src/locales/ja.mjs +218 -0
- package/src/locales/ko.mjs +281 -0
- package/src/locales/zh.mjs +218 -0
- package/src/login.mjs +16 -15
- package/src/menu.mjs +129 -147
- package/src/models.mjs +12 -11
- package/src/recipes.mjs +83 -23
- package/src/run.mjs +44 -41
- package/src/settings.mjs +168 -0
- package/src/top.mjs +7 -6
- package/src/usage.mjs +10 -9
package/src/usage.mjs
CHANGED
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
|
|
4
4
|
import { V1, requireKey } from "./config.mjs";
|
|
5
5
|
import { style, padDisplay, barChart, divider } from "./ansi.mjs";
|
|
6
|
+
import { t } from "./i18n.mjs";
|
|
6
7
|
|
|
7
8
|
const GROUPS = ["model", "provider", "api_key", "day"];
|
|
8
9
|
|
|
@@ -13,8 +14,8 @@ export function parseUsageArgs(rest = []) {
|
|
|
13
14
|
if (rest[i] === "--by") by = rest[++i];
|
|
14
15
|
else if (rest[i] === "--days") days = Number(rest[++i]);
|
|
15
16
|
}
|
|
16
|
-
if (!GROUPS.includes(by)) throw new Error(
|
|
17
|
-
if (!Number.isInteger(days) || days < 1 || days > 365) throw new Error(
|
|
17
|
+
if (!GROUPS.includes(by)) throw new Error(t("--by must be one of {groups}: {by}", { groups: GROUPS.join("|"), by }));
|
|
18
|
+
if (!Number.isInteger(days) || days < 1 || days > 365) throw new Error(t("--days must be an integer 1-365: {days}", { days }));
|
|
18
19
|
return { by, days };
|
|
19
20
|
}
|
|
20
21
|
|
|
@@ -23,12 +24,12 @@ const fmtKrw = (n) => `₩${Math.round(n).toLocaleString("en-US")}`;
|
|
|
23
24
|
// report 응답 → 표시 문자열(순수 함수 — fixture 테스트 대상).
|
|
24
25
|
export function renderUsage(data, styler = style) {
|
|
25
26
|
const lines = [];
|
|
26
|
-
const
|
|
27
|
-
lines.push(`${styler.bold(styler.plum("
|
|
27
|
+
const byLabel = { model: t("by model"), provider: t("by provider"), api_key: t("by key"), day: t("by day") }[data.group_by] || data.group_by;
|
|
28
|
+
lines.push(`${styler.bold(styler.plum(t("Usage")))} ${styler.dim(`· ${byLabel} · ${t("last {days} days", { days: data.days })}`)}`);
|
|
28
29
|
lines.push(divider(undefined, styler));
|
|
29
30
|
const items = data.items || [];
|
|
30
31
|
if (!items.length) {
|
|
31
|
-
lines.push(styler.dim("
|
|
32
|
+
lines.push(styler.dim(t("No usage history")));
|
|
32
33
|
return lines.join("\n");
|
|
33
34
|
}
|
|
34
35
|
const max = Math.max(...items.map((i) => i.cost_krw), 1);
|
|
@@ -43,7 +44,7 @@ export function renderUsage(data, styler = style) {
|
|
|
43
44
|
);
|
|
44
45
|
}
|
|
45
46
|
lines.push(divider(undefined, styler));
|
|
46
|
-
lines.push(`${padDisplay("
|
|
47
|
+
lines.push(`${padDisplay(t("Total"), keyW)} ${" ".repeat(20)} ${styler.bold(fmtKrw(total.cost))}${styler.dim(` ${total.calls} calls`)}`);
|
|
47
48
|
return lines.join("\n");
|
|
48
49
|
}
|
|
49
50
|
|
|
@@ -56,14 +57,14 @@ export async function usage(rest) {
|
|
|
56
57
|
if (res.status === 403) {
|
|
57
58
|
// 구버전 로그인 키(usage:read 스코프 없음) — 재로그인으로 새 키를 받으면 해결.
|
|
58
59
|
console.error(
|
|
59
|
-
`${style.red("✗")}
|
|
60
|
-
` ${style.dim("pleum login
|
|
60
|
+
`${style.red("✗")} ${t("This API key doesn't have usage:read permission.")}\n` +
|
|
61
|
+
` ${style.dim(t("Run pleum login again to get a new key (recent keys include it by default)."))}`,
|
|
61
62
|
);
|
|
62
63
|
process.exit(1);
|
|
63
64
|
}
|
|
64
65
|
if (!res.ok) {
|
|
65
66
|
const body = await res.text().catch(() => "");
|
|
66
|
-
throw new Error(
|
|
67
|
+
throw new Error(`${t("Failed to fetch usage ({status})", { status: res.status })}${body ? `: ${body.slice(0, 200)}` : ""}`);
|
|
67
68
|
}
|
|
68
69
|
console.log(renderUsage(await res.json()));
|
|
69
70
|
}
|