kiosapi 0.1.6 → 0.1.7
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/dist/api.js +39 -16
- package/dist/commands.js +2 -3
- package/package.json +1 -1
package/dist/api.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { loadConfig } from './config.js';
|
|
2
|
-
import { dim } from './ui.js';
|
|
2
|
+
import { dim, sleep } from './ui.js';
|
|
3
3
|
/** Turn an upstream HTTP status into an actionable Indonesian message. */
|
|
4
4
|
function humanizeError(status) {
|
|
5
5
|
if (status === 401)
|
|
@@ -61,22 +61,45 @@ export async function resolveModel(flag) {
|
|
|
61
61
|
process.stderr.write(`${dim(`(model otomatis: ${pick.id} — atur tetap dengan: kiosapi setel model <id>)`)}\n`);
|
|
62
62
|
return pick.id;
|
|
63
63
|
}
|
|
64
|
-
/**
|
|
64
|
+
/** Prefer the gateway's own (localized) error message; fall back to a status-based one. */
|
|
65
|
+
async function gatewayError(res) {
|
|
66
|
+
try {
|
|
67
|
+
const body = (await res.json());
|
|
68
|
+
if (body?.error?.message)
|
|
69
|
+
return body.error.message;
|
|
70
|
+
}
|
|
71
|
+
catch {
|
|
72
|
+
// non-JSON body
|
|
73
|
+
}
|
|
74
|
+
return humanizeError(res.status);
|
|
75
|
+
}
|
|
76
|
+
const RETRY_BACKOFF_MS = [5000, 10000, 20000];
|
|
77
|
+
/**
|
|
78
|
+
* Authenticated request to the gateway. Retries 429 (rate limit) with a silent backoff — agent/`tim`
|
|
79
|
+
* runs burst many requests and easily hit the per-minute cap, so a brief wait + retry keeps them
|
|
80
|
+
* going instead of failing. On other errors, surfaces the gateway's own message.
|
|
81
|
+
*/
|
|
65
82
|
async function authedFetch(path, init) {
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
83
|
+
for (let attempt = 0;; attempt++) {
|
|
84
|
+
const { baseUrl, apiKey } = loadConfig();
|
|
85
|
+
if (!apiKey)
|
|
86
|
+
throw new Error('Belum masuk. Jalankan: kiosapi masuk');
|
|
87
|
+
const res = await fetch(`${baseUrl}${path}`, {
|
|
88
|
+
...init,
|
|
89
|
+
headers: {
|
|
90
|
+
Authorization: `Bearer ${apiKey}`,
|
|
91
|
+
'Content-Type': 'application/json',
|
|
92
|
+
...init?.headers,
|
|
93
|
+
},
|
|
94
|
+
});
|
|
95
|
+
if (res.ok)
|
|
96
|
+
return res;
|
|
97
|
+
if (res.status === 429 && attempt < RETRY_BACKOFF_MS.length) {
|
|
98
|
+
await sleep(RETRY_BACKOFF_MS[attempt] ?? 20000);
|
|
99
|
+
continue;
|
|
100
|
+
}
|
|
101
|
+
throw new Error(await gatewayError(res));
|
|
102
|
+
}
|
|
80
103
|
}
|
|
81
104
|
/** GET /v1/saldo — own balance summary. */
|
|
82
105
|
export async function fetchSaldo() {
|
package/dist/commands.js
CHANGED
|
@@ -436,10 +436,9 @@ export async function cmdTim(args) {
|
|
|
436
436
|
/** saldo — show own balance, bonus tokens, and month-to-date spend. */
|
|
437
437
|
export async function cmdSaldo() {
|
|
438
438
|
const s = await fetchSaldo();
|
|
439
|
-
console.log(`${bold('Saldo')}
|
|
440
|
-
console.log(`Bonus token : ${idn(s.bonus_tokens)}`);
|
|
439
|
+
console.log(`${bold('Saldo')} : ${green(rupiah(s.balance_rupiah))}`);
|
|
441
440
|
const cap = s.monthly_cap_rupiah != null ? ` / batas ${rupiah(s.monthly_cap_rupiah)}` : '';
|
|
442
|
-
console.log(`Bulan ini
|
|
441
|
+
console.log(`Bulan ini : ${rupiah(s.month_spend_rupiah)}${dim(cap)}`);
|
|
443
442
|
}
|
|
444
443
|
/** pakai — usage summary over the last N days (default 30). */
|
|
445
444
|
export async function cmdPakai(args) {
|