@doedja/kbbi-js
Version:
JavaScript library and CLI for the official KBBI (Kamus Besar Bahasa Indonesia) dictionary. Anonymous lookups out of the box, optional cookie auth for etymology.
157 lines (124 loc) • 5.62 kB
Markdown
Unofficial JavaScript library and CLI for the official Kamus Besar Bahasa Indonesia at `kbbi.kemendikdasmen.go.id`. Anonymous lookups out of the box, optional login for etymology data.
- **No account required.** Anonymous lookups return the full meanings, word classes, and examples.
- **No browser required.** Native `fetch` (Node 18+) by default. The Playwright path is optional and only loads when you ask for it.
- **Lean install.** ~9 MB of dependencies, zero Chromium download in the default flow.
- **Fast.** Single lookup in under 1 second; a 13-word batch finishes in around 3 seconds at `--concurrency 4`.
- **Programmatic login.** Login is a plain HTTPS POST against the ASP.NET MVC form. No headless browser needed.
- **Batch CLI.** Pass multiple words on one command; results are emitted as a JSON array or formatted text.
The KBBI portal moved from `kbbi.kemdikbud.go.id` to `kbbi.kemendikdasmen.go.id` after the Indonesian ministry was reorganised, and the old hostname is no longer in DNS. Version 2 retargets the new host, removes the hard Playwright dependency, and exposes the cookie path as opt-in (it was treated as required in 1.x).
```bash
npm install -g @doedja/kbbi-js
npx @doedja/kbbi-js cinta
```
Need the optional browser fallback?
```bash
npm install playwright
npx playwright install chromium
```
```bash
kbbi cinta
kbbi cinta makan air
kbbi cinta --json
kbbi cinta --scrape --json
kbbi --login --email you@example.com --password '...'
kbbi --cookie-manage list
kbbi --cookie-manage add:AspNetCookieValue
kbbi --cookie-manage delete:AspNetCookieValue
kbbi cinta --browser
kbbi --help
```
Anonymous JSON output:
```json
{
"kata": "cinta",
"host": "kbbi.kemendikdasmen.go.id",
"authenticated": false,
"entri": [
{
"nama": "cin.ta",
"nomor": "",
"id": null,
"akarkata": "",
"jenis": "",
"makna": [
{
"definisi": "suka sekali; sayang benar",
"kelaskata": [{ "kode": "a", "nama": "Adjektiva" }],
"contoh": [
{ "nomor": 1, "teks": "orang tuaku -- kepada kami semua" },
{ "nomor": 2, "teks": "-- kepada sesama makhluk" }
]
}
],
"etimologi": null,
"turunan": [],
"gabungan": [],
"peribahasa": [],
"idiom": []
}
],
"mirip": []
}
```
When more than one word is given, the command emits a JSON array (one record per word). Failed lookups are reported as `{ "kata": "...", "error": "..." }` entries and set a non-zero exit code.
| Field | Anonymous | Logged in |
| --------------------- | --------- | --------- |
| `nama`, `nomor` | Yes | Yes |
| `makna` definitions | Yes | Yes |
| `kelaskata` | Yes | Yes |
| `contoh` examples | Yes | Yes |
| `etimologi` | No (gated by KBBI server) | Yes |
| `turunan`, `gabungan`, `peribahasa`, `idiom` | No (KBBI hides them) | Yes |
| `id` (eid) | No (hidden in edit links) | Yes |
| `--scrape` Phase 2 (`/DataDasarEntri/Details`) | Skipped (server redirects to login) | Followed |
```js
const KBBI = require('@doedja/kbbi-js');
(async () => {
const kbbi = new KBBI(); // no options needed
const result = await kbbi.lookup('cinta');
console.log(result.authenticated, result.entries.length, 'meanings');
})();
```
Optional configuration:
```js
const kbbi = new KBBI({
useBrowser: false, // set true to force the Playwright fallback
headless: true,
debug: false,
timeout: 20000
});
```
```js
const Auth = require('@doedja/kbbi-js/lib/auth');
const auth = new Auth();
await auth.addCookie('AspNetCookieValue');
const kbbi = new KBBI({ auth });
```
```js
const auth = new Auth();
await auth.login('you@example.com', 'secret');
// Cookie is now persisted under data/kbbi-cookies.json and reused on next lookups.
```
1. CLI parses positional args as words and any `--flag value` pairs.
2. Each lookup hits `https://kbbi.kemendikdasmen.go.id/entri/<word>` via `fetch`.
3. `lib/parser.js` (Cheerio) walks the `h2[style*="margin-bottom:3px"]` headings and their following `<ol>` / `<ul>` lists into `{ nama, nomor, makna[], etimologi, terkait }`.
4. `--scrape` adds a per-eid call to `/DataDasarEntri/Details` for callers that supplied a session cookie. The endpoint redirects anonymous callers to `/Account/Login`, so it is skipped silently in that case.
5. `--browser` swaps step 2 for a headless Chromium via Playwright. Use it only if KBBI ever fronts the site with Cloudflare or another JS challenge.
- KBBI gates some data (etymology, derivations, idioms, edit-page IDs) to logged-in accounts on the server side. There is no way to retrieve those fields without a session cookie.
- Login uses a normal ASP.NET MVC POST with the `__RequestVerificationToken` cookie + form-token pair. No captcha as of this writing; if KBBI adds one, the `--browser --login` combination (after installing Playwright) is the fallback.
- The legacy `--save-cookie`, `--add-cookie`, and `--list-cookies` flags from 1.x were dropped in favour of `--cookie-manage`. Calling `--login` now expects `--email` and `--password`.
MIT