8
Helpers dan CLI
Modul helpers dibuka lewat subpath ua-parser-js/helpers. Field exports pada package.json memetakan subpath itu ke tiga berkas: versi CommonJS, versi ESM, dan berkas type (package.json:231-2351). Modul ini mengekspor sepuluh nama (src/helpers/ua-parser-helpers.js:100-1112); dua di antaranya masih aktif, delapan sisanya hanya alias @deprecated. Di luar paket pustaka, repository juga memasang satu perintah CLI lewat field bin (package.json:2423).
Fungsi bantu yang masih aktif
Hanya dua ekspor yang bukan alias lama: getOutlookEdition dan isFrozenUA (src/helpers/ua-parser-helpers.d.ts:7-84).
isFrozenUA tidak diimplementasikan di repository ini. Modul helpers mengimpor fungsi itu dari paket ua-is-frozen lalu mengekspornya kembali (src/helpers/ua-parser-helpers.js:145), sehingga kontraknya sederhana: satu string UA masuk, satu boolean keluar (src/helpers/ua-parser-helpers.d.ts:86). Fungsinya mendeteksi UA yang sudah dibekukan atau dikurangi, misalnya UA Android yang versinya diubah menjadi K dan 93.0.0.0.
getOutlookEdition(name, version) menerjemahkan nama dan versi mentah Outlook menjadi edisi yang ramah pengembang. Kalau salah satu argumen kosong, fungsi langsung mengembalikan name; kalau keduanya terisi, nama dinormalisasi dengan toLowerCase() dan pembuangan awalan microsoft (src/helpers/ua-parser-helpers.js:60-627).
graph TD
A["getOutlookEdition name dan version"] --> B{"name dan version terisi"}
B -- tidak --> Z0["return name"]
B -- ya --> C["cleanName = lowercase + buang awalan microsoft"]
C --> M{"cleanName == macoutlook"}
M -- ya --> M1{"parseInt major >= 16"}
M1 -- ya --> MM["Outlook for Mac (Modern)"]
M1 -- tidak --> ML["Outlook for Mac (Legacy)"]
M -- tidak --> W{"cleanName == outlook"}
W -- tidak --> Z1["return name"]
W -- ya --> V{"parts[0] sebagai major"}
V -- 15 --> V15["Outlook 2013"]
V -- 14 --> V14["Outlook 2010"]
V -- 12 --> V12["Outlook 2007"]
V -- kurang dari 12 --> VLT["Outlook (Legacy)"]
V -- 16 --> V16{"parts[2] sebagai build < 10000"}
V16 -- ya --> MSI["Outlook 2016 (MSI / Volume License)"]
V16 -- tidak --> C2R["Outlook 365 / 2019+ (Modern)"]
style A fill:#f59e0b,color:#000
style B fill:#f59e0b,color:#000
style M fill:#f59e0b,color:#000
style V fill:#f59e0b,color:#000
style V16 fill:#f59e0b,color:#000
style C fill:#8b5cf6,color:#fff
style MM fill:#2d7d46,color:#fff
style C2R fill:#2d7d46,color:#fff
style MSI fill:#dc2626,color:#fff
style ML fill:#dc2626,color:#fff
style VLT fill:#dc2626,color:#fff
style Z0 fill:#dc2626,color:#fff
style Z1 fill:#dc2626,color:#fff
%% fig: Pohon keputusan getOutlookEdition
%% desc: Fungsi memisahkan cabang Mac dan Windows lalu memetakan major dan build ke nama edisi Outlook.Cabang Mac dipisah karena mesin render-nya berbeda: macoutlook dengan major >= 16 menjadi Modern, di bawahnya Legacy (src/helpers/ua-parser-helpers.js:64-698). Cabang Windows memecah version.split('.') menjadi parts, memakai parts[0] sebagai major dan parts[2] || 0 sebagai build (src/helpers/ua-parser-helpers.js:72-769). Pemetaan versi lama memakai major secara langsung (src/helpers/ua-parser-helpers.js:77-8110), sedangkan major 16 dipecah lagi berdasarkan build: di bawah 10000 berarti MSI, selebihnya Click-to-Run (src/helpers/ua-parser-helpers.js:84-9311).
| Kondisi | Keluaran |
|---|---|
cleanName === 'macoutlook' dan major >= 16 | Outlook for Mac (Modern) |
cleanName === 'macoutlook' dan major < 16 | Outlook for Mac (Legacy) |
major === 15 | Outlook 2013 |
major === 14 | Outlook 2010 |
major === 12 | Outlook 2007 |
major < 12 | Outlook (Legacy) |
major === 16 dan build < 10000 | Outlook 2016 (MSI / Volume License) |
major === 16 dan build >= 10000 | Outlook 365 / 2019+ (Modern) |
| nama lain, atau major di luar 12/14/15/16 | name asli |
Nilai terakhir berasal dari baris fallback yang mengembalikan name tanpa perubahan (src/helpers/ua-parser-helpers.js:9712). Contoh yang diuji: getOutlookEdition('Microsoft Outlook', '16.0.4266.1001') menghasilkan Outlook 2016 (MSI / Volume License), versi 16.0.14326.20000 menghasilkan Outlook 365 / 2019+ (Modern), dan versi 15.0.4569.1506 menghasilkan Outlook 2013 (test/unit/submodules/helpers.spec.js:16-2313). Masukan yang tidak dikenal tetap utuh, misalnya Microsoft Outlook dengan versi SomeRandomString (test/unit/submodules/helpers.spec.js:30-3814).
Helper lama yang sudah deprecated
Delapan nama sisanya kini hanya alias. Setiap alias diberi anotasi @deprecated plus submodule penggantinya (src/helpers/ua-parser-helpers.js:16-5415), dan anotasi yang sama diulang di berkas type (src/helpers/ua-parser-helpers.d.ts:10-4116).
| Helper lama | Pengganti | Catatan |
|---|---|---|
getDeviceVendor | device-detection | butuh model perangkat |
isAppleSilicon | device-detection | menerima IResult atau string |
isAIBot | bot-detection | alias langsung ke isAICrawler |
isBot | bot-detection | menerima IResult atau string |
isChromeFamily | browser-detection | cek engine Blink |
isElectron | browser-detection | tanpa argumen |
isFromEU | browser-detection | tanpa argumen |
isStandalonePWA | browser-detection | tanpa argumen |
graph LR
H["src/helpers/ua-parser-helpers.js"] --> D1["getDeviceVendor"]
H --> D2["isAppleSilicon"]
H --> D3["isAIBot"]
H --> D4["isBot"]
H --> D5["isChromeFamily"]
H --> D6["isElectron"]
H --> D7["isFromEU"]
H --> D8["isStandalonePWA"]
D1 --> MOD1["device-detection"]
D2 --> MOD1
D3 --> MOD2["bot-detection"]
D4 --> MOD2
D5 --> MOD3["browser-detection"]
D6 --> MOD3
D7 --> MOD3
D8 --> MOD3
style H fill:#f59e0b,color:#000
style D1 fill:#dc2626,color:#fff
style D2 fill:#dc2626,color:#fff
style D3 fill:#dc2626,color:#fff
style D4 fill:#dc2626,color:#fff
style D5 fill:#dc2626,color:#fff
style D6 fill:#dc2626,color:#fff
style D7 fill:#dc2626,color:#fff
style D8 fill:#dc2626,color:#fff
style MOD1 fill:#2d7d46,color:#fff
style MOD2 fill:#2d7d46,color:#fff
style MOD3 fill:#2d7d46,color:#fff
%% fig: Peta alias deprecated ke submodule pengganti
%% desc: Delapan ekspor lama di modul helpers hanya meneruskan fungsi dari tiga submodule pengganti.Modul helpers sendiri tidak lagi menulis ulang logika deteksi. Kedelapan alias diambil langsung dari submodule lewat require, termasuk isAICrawler dari bot-detection yang diekspor ulang dengan nama lama isAIBot (src/helpers/ua-parser-helpers.js:10-1317). Rincian perilaku tiap fungsi ada di submodule bot-detection dan submodule browser-detection dan device-detection.
Berkas .mjs di folder yang sama adalah hasil generate dari .js dan membawa peringatan DO NOT EDIT THIS FILE! (src/helpers/ua-parser-helpers.mjs:1-318). Proses generate-nya dibahas di Build dan Distribusi.
CLI
script/cli.js adalah berkas bin paket (package.json:2423). Skrip memuat node:fs, node:path, node:perf_hooks, node:readline, node:util, kelas UAParser, dan lima extension Bots, Emails, ExtraDevices, InApps, Vehicles (script/cli.js:3-1019). Seluruh badan skrip dibungkus satu blok try; error apa pun dicetak lewat console.error lalu diakhiri process.exit(1) (script/cli.js:91-9420).
Pemakaian yang didokumentasikan di changelog: npx ua-parser-js "<User-Agent>" untuk satu string, npx ua-parser-js --input-file=log.txt >> result.json untuk batch, dan npx ua-parser-js --input-file=log.txt --output-file=result.json bila hasil ingin ditulis ke berkas (CHANGELOG.md:26-3121).
Tiga mode argumen
Mode dipilih dari isi process.argv[2]: tanpa awalan - berarti mode string langsung, -h atau --help berarti bantuan, selain itu masuk mode berkas (script/cli.js:12-1622).
process.argv[2] | Perilaku | Keluaran |
|---|---|---|
tidak diawali - | setiap argumen diparse dengan UAParser(ua, [Bots, Emails, ExtraDevices, InApps, Vehicles]) | JSON.stringify(results, null, 4) ke stdout, exit(0) |
-h atau --help | mencetak teks bantuan | exit(0) |
| argumen lain | membaca --input-file, menulis ke --output-file atau stdout | exit(0) setelah selesai |
Teks bantuan dari mode --help (script/cli.js:18-2423):
Usage: npx ua-parser-js <string>
or npx ua-parser-js --input-file <filepath> [--output-file <filepath>]
-i, --input-file
-o, --output-file
Mode berkas memakai parseArgs tanpa menyertakan array argumen, jadi parseArgs membaca process.argv sendiri. Hanya dua opsi yang dideklarasikan (script/cli.js:28-3924):
| Nama panjang | short | type | Wajib | Pesan bila kosong |
|---|---|---|---|---|
--input-file | -i | string | ya | Input file must be present |
--output-file | -o | string | tidak | — |
-h dan --help tidak ada di daftar opsi parseArgs; keduanya diperiksa lebih dulu secara manual (script/cli.js:18-2423). Tanpa --input-file, skrip mencetak Input file must be present dan keluar dengan kode 1; berkas yang tidak ditemukan mencetak Input file not found: <path> dan juga keluar dengan kode 1 (script/cli.js:41-5225).
Setelah validasi, skrip membuat createReadStream(inputPath, 'utf8'), membungkusnya dengan readline.createInterface dan crlfDelay: Infinity, lalu memilih createWriteStream(outputPath) atau process.stdout sebagai tujuan (script/cli.js:54-6026).
sequenceDiagram
autonumber
box rgb(245,158,11) Entry point
participant CLI as script/cli.js
participant ARG as parseArgs
end
box rgb(139,92,246) Input
participant FS as node:fs
participant RL as node:readline
end
box rgb(51,103,145) Parser
participant UAP as UAParser
end
box rgb(45,125,70) Output
participant OUT as outputStream
end
CLI->>ARG: parseArgs dengan input-file dan output-file
ARG-->>CLI: inputFile dan outputFile
alt inputFile undefined
CLI-->>CLI: Input file must be present lalu exit 1
end
CLI->>FS: existsSync inputPath
FS-->>CLI: hasil boolean
alt berkas tidak ada
CLI-->>CLI: Input file not found lalu exit 1
end
CLI->>FS: createReadStream inputPath utf8
CLI->>RL: createInterface crlfDelay Infinity
CLI->>UAP: new UAParser dengan lima extension
CLI->>OUT: write \u0022[\n\u0022
loop rl.on line
RL-->>CLI: line
CLI->>UAP: setUA line lalu getResult
UAP-->>CLI: IResult
CLI->>OUT: write JSON.stringify result null 4
end
RL-->>CLI: rl.on close
CLI->>OUT: write \u0022\n]\u0022
alt outputPath terisi
CLI->>OUT: end lalu cetak Done dan durasi
end
CLI->>CLI: process.exit 0
%% fig: Alur mode berkas pada CLI
%% desc: Baris dibaca satu per satu oleh readline, setiap baris diparse UAParser, dan hasilnya ditulis sebagai array JSON.Setiap baris yang masuk ke rl.on('line') diparse dengan uap.setUA(line).getResult(). Hasilnya diserialisasi dengan indentasi 4 spasi, dan koma pemisah baru ditulis mulai baris kedua lewat penanda lineNumber (script/cli.js:62-7327). Karena itu berkas keluaran selalu berupa satu array JSON, dengan [ dibuka sebelum baris pertama.
Saat rl.on('close') terpicu, skrip menutup array dengan \n]. Kalau --output-file dipakai, outputStream.end mencetak Done!, Number of lines found: <n>, Task finished in: <ms>ms, dan Output written to: <path>, lalu exit(0); kalau hasil dialirkan ke stdout, skrip langsung exit(0) tanpa keempat baris tersebut sehingga keluaran tetap bersih untuk diarahkan ke berkas lain (script/cli.js:75-8928).
⚠️
inputPathdanoutputPathdi-resolve terhadap__dirnameberkas skrip, bukan direktori kerja pemanggil (script/cli.js:41-5225). Jalur relatif karena itu selalu dihitung dariscript/di dalam paket, sehingga hasilnya berbeda bila perintah dijalankan dari luar folder paket.
⚠️ Penulisan ke berkas berlangsung streaming tanpa buffering. Bila proses dihentikan sebelum
rl.on('close'), berkas keluaran berhenti tanpa\n]dan bukan JSON yang sah.
Untuk API pustaka yang dipanggil CLI, lihat API UAParser dan Extensions untuk Deteksi Tambahan.