earsiv-istisna
v0.1.0
Published
GİB e-Arşiv Portal'ının resmi olmayan API'si üzerinden yalnızca hizmet ihracı (KDV'den istisna, ISTISNA tipi) faturası kesen komut satırı aracı; mal ihracatı, tevkifat, özel matrah, e-SMM veya normal SATIS faturası desteklemez.
Maintainers
Readme
earsiv-istisna
GİB e-Arşiv Portal üzerinden hizmet ihracı (KDV'den istisna, 3065 sayılı Kanun 11/1-a) faturası kesen terminal aracı. Kurulan komutun adı fatura'dır.
⚠️ Önce bunu okuyun
- Yalnızca
faturaTipi: "ISTISNA"hizmet ihracı faturası keser. Mal ihracatı, tevkifat, özel matrah, e-SMM ve normalSATISfaturası desteklenmez.- Portal'ın resmi olmayan, dokümante edilmemiş JSON uç noktalarını konuşur. GİB bunları haber vermeden değiştirebilir; o durumda araç sessizce kırılabilir.
- Resmi bir GİB entegratörü değildir. Kestiğiniz her faturayı e-Arşiv Portal üzerinden kendiniz doğrulayın.
Hızlı başlangıç
Aşağıdaki beş adım, sıfırdan imzalı bir faturaya kadar olan yolun tamamıdır. Varsayılan ortam test'tir — prod'a geçmek her zaman bilinçli bir eylemdir.
1. Kurun (Node.js ≥ 22.12 gerekir)
npm install -g earsiv-istisna
fatura --helpKurmadan denemek için: npx earsiv-istisna --help
2. Giriş yapın — kullanıcı kodu ve parolayı sorar, Portal'da doğrular, sonra kaydeder
fatura login --env testTest hesabınız yoksa: Test ortamı bölümü tek kullanımlık hesap alma yolunu anlatır.
3. Müşteriyi ekleyin — adım adım sorar, ülkeyi listeden seçtirir
fatura clients add4. Taslağı oluşturun — önce GİB'e hiçbir şey göndermeden deneyin
fatura draft --client acme --amount 1500 --desc "Ocak 2026 danışmanlık" --dry-run
fatura draft --client acme --amount 1500 --desc "Ocak 2026 danışmanlık"--dry-run aynı özeti basar ama GİB'e istek göndermez ve kimlik bilgisi bile istemez. Gerçek müşteri verinizi paylaşımlı test ortamına koymadan doğrulama yapmanın yolu budur.
5. Önizleyin, imzalayın, arşivleyin
fatura preview <ettn> # tarayıcıda açar
fatura sign <ettn> # SMS ile imzalar - GERİ ALINAMAZ, yalnızca prod'da çalışır
fatura download <ettn> # HTML + XML + JSON olarak arşive yazarGerçek fatura kesmeye hazır olduğunuzda her komuta --env prod ekleyin ve önce prod kontrol listesine bakın.
Komutlar
Tüm komutlar üç global bayrağı destekler: --env <test|prod> (varsayılan test), --json (script kullanımı için saf JSON), --verbose (GİB'in ham hata mesajı).
| Komut | Ne yapar |
|---|---|
| fatura login | Etkileşimli giriş; Portal'da doğrulayıp credentials.json'a kaydeder |
| fatura logout | GİB oturumunu gerçekten kapatır (--all ile her iki ortam) |
| fatura whoami | Portaldaki kayıtlı mükellef bilgilerinizi gösterir |
| fatura list | Belgeleri listeler — terminalde interaktif tarayıcı açılır |
| fatura show <ettn> | Bir belgenin tüm alanlarını gösterir |
| fatura draft | TCMB kuruyla ISTISNA taslak oluşturur (--dry-run ile kuru çalıştırır) |
| fatura preview <ettn> | Taslağı HTML olarak tarayıcıda açar |
| fatura clients / clients add | Müşteri profillerini listeler / etkileşimli ekler |
| fatura delete <ettn> | İmzalanmamış taslağı siler (onay ister) |
| fatura sign <ettn> | SMS ile imzalar (onay ister, geri alınamaz) |
| fatura download <ettn> | Belgeyi arşive indirir (--pdf opsiyonel) |
| fatura export --year 2026 | Yıllık arşivi tek ZIP'e paketler |
Tam bayrak listesi: fatura <komut> --help
fatura draft # --client verilmezse etkileşimli form açılır
fatura draft --client acme --amount 1500 --desc "Ocak 2026 danışmanlık"
fatura draft --client acme --amount 1500 --date 2026-06-15 # geriye tarihli, aşağıdaki uyarıya bakın
fatura draft --client acme --amount 1500 --currency EUR # müşterinin para birimini geçici olarak ezer
fatura draft --client acme --amount 4500 --dry-run --json # tam payload'ı JSON olarak basar
fatura list --unsigned
fatura list --from 2026-01-01 --to 2026-06-30
fatura delete <ettn> --reason "Hatalı tutar"
fatura export --year 2026 --output ~/Desktop/2026-faturalar.zipfatura list gerçek bir terminalde çalıştırıldığında interaktif tarayıcı açar:
╭────────────────────────────────────────────────────────────────────────────╮
│ Tarih Belge No Alıcı Durum ETTN │
│ > 15-07-2026 GIB2026000000123 Acme Export Solutio… Onaylandı a1b2c3d4… │
│ 22-07-2026 GIB2026000000129 Vega Digital Servic… Onaylanmadı b2c3d4e5… │
╰────────────────────────────────────────────────────────────────────────────╯
↑/↓ Gezin Enter Detay / Filtrele Esc Temizle q Çıkış
p Önizle i İndir d Sil │ s İmzala (GERİ ALINAMAZ)| Tuş | Eylem |
|---|---|
| ↑ ↓ | Satır seç |
| Enter | Detay panelini aç/kapat (belge detayı yalnızca burada çekilir) |
| / · Esc | Canlı filtre (unvan, belge no, ETTN) · temizle |
| p · i | Tarayıcıda önizle · indir ve arşivle |
| d · s | Sil · imzala |
d ve s TUI içinden çalıştırılmaz — TUI kapanır ve çalıştırmanız gereken komutu basar. Silme ve imzalama kendi onay kapılarını gerektirir (tarayıcı önizlemesi, tutarı elle yazarak teyit, SMS kodu); bunları bir klavye döngüsüne sıkıştırmak zayıflatırdı. Kısayollar belge durumuna göre etkinleşir; devre dışı olanlar soluk görünür.
TUI yalnızca gerçek bir terminalde açılır — --json verildiğinde veya çıktı yönlendirildiğinde düz metin/JSON basılır.
Yapılandırma
Üç dosya, hepsi ~/.config/fatura/ altında. Hiçbiri zorunlu değildir; config.json yoksa varsayılanlar geçerlidir.
| Dosya | İçerik | Nasıl oluşur |
|---|---|---|
| credentials.json | GİB kullanıcı kodu/parola, ortam başına | fatura login |
| clients.json | Müşteri profilleri | fatura clients add |
| config.json | Ortam, kur kuralı, not şablonu, arşiv dizini | Elle (opsiyonel) |
Müşteri profili
fatura clients add ile eklemeniz önerilir. Alan adları kasıtlı olarak Türkçedir:
{
"acme": {
"unvan": "Acme Inc.",
"ulke": "Amerika Birleşik Dev",
"paraBirimi": "USD",
"varsayilanAciklama": "Yazılım danışmanlık hizmeti",
"vatId": "US123456789"
}
}Zorunlu alanlar yalnızca unvan, ulke ve paraBirimi'dir. sehir, adres, postaKodu, eposta, vergiDairesi opsiyoneldir — GİB'in kendi formunda da opsiyoneldirler.
⚠️
ulkealanı GİB'in ülke listesindeki değerle birebir eşleşmeli, ISO kodu değil. Bu listenin iki tuzağı var:
- Kırpık: çoğu değer ~20 karakterde kesilmiş (
"Amerika Birleşik Dev","Kongo (Demokratik Cu)").- Yanlış Türkçe yazım GİB'de doğru olabilir:
"Birleşik Krallik"geçerli,"Birleşik Krallık"değil;"Misir"geçerli,"Mısır"değil.Bu yüzden
clients add'in ülke adımı serbest metin kabul etmez: yazdıkça 260'lık liste daralır, seçip Enter'a basarsınız. Elle yazarsanız neredeyse kesin hatalı yazarsınız.draftbu alanı doğrular ve listede yoksa en yakın 3 eşleşmeyi önerir.
| Alan | Zorunlu | Açıklama |
|---|---|---|
| unvan | evet | Faturadaki alıcı unvanı |
| ulke | evet | GİB'in portaldaki ülke listesinden birebir bir değer |
| paraBirimi | evet | ISO 4217 kodu (USD, EUR, ...). GİB'in formunda yok — TCMB kurunu çekmek için bu aracın kendi gereksinimi |
| varsayilanAciklama | önerilir | draft --desc verilmezse kullanılır; ikisi de yoksa draft hata verir. Bu alan olmadan her ayki faturada açıklamayı yeniden yazmanız gerekir. fatura clients çıktısında eksik olanlar [!] varsayılan açıklama yok ile işaretlenir |
| vatId | hayır | Alıcının kendi ülkesindeki vergi/EIN numarası. Faturanın VKN alanına değil, not metnine "Alıcı VAT ID: ..." olarak eklenir |
| sehir · adres · postaKodu · eposta · vergiDairesi | hayır | Verilmezse payload'da boş gider |
Alıcı VKN'si hiç sorulmaz — her hizmet ihracı faturası sabit 2222222222 alıcı VKN'siyle kesilir.
clients add formu: sırasıyla unvan, anahtar (unvan'dan otomatik önerilir), ülke, para birimi (dördü zorunlu); sonra opsiyonel alanlar (boş geçmek için Enter); son adım varsayılan açıklamadır ve form onu zorunlu tutar. Sonunda özet gösterip onay ister. Esc her adımda tümünü iptal eder. Var olan bir anahtarın üzerine yazmadan önce ayrıca onay ister.
Para birimi adımı yaygın kodları önerir ama başka bir ISO kodu da kabul eder; TCMB'nin yayımlamadığı bir kod girilirse uyarır, engellemez.
Elle düzenlemek de her zaman mümkündür — ikisi birbirini dışlamaz. Eski, tüm alanları dolu formatta bir clients.json olduğu gibi çalışır.
config.json
{
"defaultEnvironment": "test",
"credentialProvider": "file",
"rate": { "type": "ForexBuying", "dateRule": "previousBusinessDay" },
"exemption": { "note": "302-11/1-A HİZMET İHRACI\n{tutarYazi}\n#YALNIZ: {tlYazi}\n#{paraBirimi} Kuru : {kur} TRY" },
"archiveDir": "~/Documents/fatura-arsiv"
}| Anahtar | Değerler | Açıklama |
|---|---|---|
| defaultEnvironment | "test" | "prod" | --env'in varsayılanı. Varsayılanın varsayılanı testtir |
| credentialProvider | "file" | "op" | "keychain" | "pass" | Aşağıdaki katlanmış bölüme bakın |
| rate.type | "ForexBuying" | "ForexSelling" | "BanknoteBuying" | "BanknoteSelling" | TCMB bülteninden okunacak kur alanı |
| rate.dateRule | "previousBusinessDay" | "invoiceDate" | Hangi günün bülteni kullanılacak |
| exemption.note | şablon | Faturanın not alanı — yer tutuculu bir şablondur |
| archiveDir | dizin yolu | Arşiv kökü. Varsayılan ~/Documents/fatura-arsiv |
| Yer tutucu | İçerik | Örnek |
|---|---|---|
| {tutar} | Fatura tutarı, rakam | 1234.00 |
| {paraBirimi} | Para birimi kodu | USD |
| {kur} | Birim TCMB kuru | 40.1234 |
| {tlKarsiligi} | TL karşılığı, rakam | 49512.28 |
| {tutarYazi} | Tutarın Türkçe yazıyla karşılığı + para birimi adı | BinikiyüzotuzdörtAmerikanDoları |
| {tlYazi} | TL karşılığı yazıyla (tam sayı ve kuruş ayrı) | KırkDokuzBinBeşYüzOnİki.TRY YirmiSekiz.KRŞ |
| {aciklama} | Hizmet açıklaması | Yazılım geliştirme hizmeti |
| {vatId} | Müşterinin VAT ID'si (yoksa boş) | DE123456789 |
Bilinmeyen bir yer tutucu (örn. yazım hatasıyla {tutrYazi}) hata verir, sessizce boş bırakılmaz — bir config.json yazım hatasının imzalanacak bir faturaya sızmasını önler.
Varsayılan şablondaki satırlar bir GİB ya da yasal zorunluluk DEĞİLDİR. Aracın yazarının CLI'ye geçmeden önce kullandığı başka bir faturalama uygulamasının konvansiyonudur; varsayılan yalnızca geçişte faturaların önceki yıllara göre farklı görünmemesi için aynı biçimi üretir. Bu satırların gerekip gerekmediğini muhasebecinizle teyit edin.
Çeviricinin (src/core/turkish-numbers.ts) kuralları:
100→Yüz(BirYüzdeğil),1000→Bin(BirBindeğil).1000000→BirMilyon— istisna yalnızca yüz ve bin için geçerli.- İki farklı büyük/küçük harf biçimi var (önceki uygulamanın tutarsızlığı, birebir korundu):
{tutarYazi}yalnızca ilk harf büyük,{tlYazi}her kelimenin baş harfi büyük. {tutarYazi}yalnızca tam sayı kısmını çevirir;{tlYazi}hem tam sayı hem kuruşu çevirir — kuruşun hukuken anlamlı olduğu tek para birimi TL'dir.
TRY faturalarında: TL'nin TL'ye kuru yoktur, {kur} 1 ve {tlKarsiligi} {tutar}'a eşit olur; varsayılan şablon #TRY Kuru : 1 TRY gibi doğru ama gereksiz bir satır üretir. (Ayrıca draft bugün bir TRY faturasını zaten tamamlayamıyor — bkz. Bilinen sınırlar.)
Hangisinin kullanılacağı config.json'daki credentialProvider ile seçilir (varsayılan file).
file (varsayılan) — fatura login bu dosyayı sizin için yazar. Elle yazmak isterseniz şema ortam anahtarlıdır:
mkdir -p ~/.config/fatura
cat > ~/.config/fatura/credentials.json <<'EOF'
{
"test": {"username":"TEST_VKN_VEYA_TCKN","password":"TEST_PAROLA"},
"prod": {"username":"PROD_VKN_VEYA_TCKN","password":"PROD_PAROLA"}
}
EOF
chmod 600 ~/.config/fatura/credentials.jsonEski düz format ({"username": ..., "password": ...}) hâlâ okunur — o durumda aynı bilgi her iki ortam için kullanılır. fatura login çalıştırdığınızda dosya otomatik olarak ortam-anahtarlı biçime geçirilir; diğer ortamın kaydı korunur. İzinler grup/diğer için okunabilir bırakılırsa CLI uyarır ama çalışmaya devam eder.
op (1Password CLI — WSL ve macOS'ta önerilen) · { "credentialProvider": "op" }
op CLI kurulu olmalı. Referanslar config.json'daki op.usernameRef / op.passwordRef ile değiştirilebilir (varsayılan op://Private/GIB e-Arsiv/username).
keychain (yalnızca macOS) · { "credentialProvider": "keychain" }
macOS'un security komutuyla GIB e-Arsiv servisi altında username ve password hesaplarını arar.
pass (gpg tabanlı, yaygın WSL alternatifi) · { "credentialProvider": "pass" }
pass show gib-earsiv/username ve pass show gib-earsiv/password yollarını okur.
fatura loginyalnızcafilesağlayıcısı içindir. Diğerleri seçiliyken çalışmaz, o sağlayıcıyı kendi aracıyla yönetmeniz gerektiğini söyleyen bir hata verir.
fatura login davranışı: kullanıcı kodu ve parolayı sırayla sorar (parola * ile maskelenir), kaydetmeden önce Portal'a gerçekten bağlanıp doğrular. Doğrulama başarısızsa hiçbir şey kaydedilmez, GİB'in Türkçe hatası gösterilir ve tekrar denemeniz istenir. Başarılıysa hemen ardından logout çağrılır. Etkileşimlidir: --json ile kullanılamaz, TTY gerektirir; Esc her adımda iptal eder.
⚠️ Bilmeniz gerekenler
Bu üç başlık, aracın davranışının parayla ve mevzuatla temas ettiği yerlerdir.
Kur seçimi
Varsayılan ForexBuying (döviz alış) ve bir önceki iş günü (previousBusinessDay).
TCMB o günün kurunu 15:30 TRT'de yayımlar; sabah kesilen bir faturada o günün kuru henüz kesinleşmemiş olur. Varsayılanın gerekçesi budur.
Bu bir muhasebe tercihidir, GİB kuralı değildir. Uygulamadan önce muhasebecinize teyit ettirin. İkisi de config.json'daki rate.type / rate.dateRule ile değiştirilebilir.
draft çıktısı hangi bültenin kullanıldığını (tarih, bülten no, geri düşülüp düşülmediği) her zaman gösterir; arşive yazılan .json aynı denetim izini kalıcı olarak saklar.
Geriye tarihli fatura (--date)
GİB belgeTarihi alanına teknik olarak hiçbir kısıt uygulamıyor — test ortamında 1 gün, 1 ay, 3 ay, 7 ay öncesi ve 1 ay sonrası (gelecek tarih) elle denendi, hepsi kabul edildi.
Kısıt tamamen hukukidir, teknik değil — araç bunu kendi başına uygulamaz; hangi tarihi kullanacağınızı bilmek size düşer.
(Bu bir hukuki görüş değildir; muhasebecinize teyit ettirin.) VUK 231/5, faturanın hizmetin yapılmasından itibaren azami yedi gün içinde düzenlenmesini öngörür; süre geçtikten sonra düzenlenen bir fatura hiç düzenlenmemiş sayılabilir ve özel usulsüzlük cezasına konu olabilir. Ayrıca fatura tarihi hangi KDV beyan dönemine dahil edileceğini belirler — kapanmış bir döneme geriye dönük tarih atarsanız düzeltme gerekebilir.
--date verdiğiniz tarih TCMB kur sorgusunun hangi bültene bakacağını da belirler.
İmzalama geri alınamaz
delete ve sign her zaman bir onay adımıyla biter: silme için e/H; imzalama için önizlemeyi gördüğünüzü onaylama + tutarı elle yeniden yazma + SMS kodu.
--yes / --force gibi bir bypass bayrağı yoktur ve eklenmeyecektir (--json modu dahil). Bu komutlar gerçek bir TTY ister; girdiyi borudan/dosyadan yönlendirmek (echo e | fatura delete ...) kasıtlı olarak reddedilir — bir boru, bir insanın ekranı görüp karar verdiğinin kanıtı değildir.
Gerekçe: imzalanan bir e-Arşiv faturası mali veri haline gelir — değiştirilemez, silinemez; yalnızca 8 gün içinde iptal talebi açılabilir veya bir iade faturasıyla düzeltilebilir. Zaten imzalanmış bir belgeyi tekrar imzalamak da reddedilir.
⚠️ Prod'a geçiş kontrol listesi
- [ ] Tüm akış (
draft→preview→sign→download) test ortamında baştan sona temiz çalıştı mı? - [ ] İlk prod faturası küçük tutarlı, gerçek bir fatura mı (uydurma tutar değil)?
- [ ] Kur seçimi (
rate.type,rate.dateRule) muhasebecinize teyit ettirildi mi?
Prod'da imzalanan her fatura mali veridir ve geri alınamaz.
Bilinen sınırlar
- SMS ile imzalama test ortamında çalışmaz, yalnızca prod'da. Test ortamında
signakışını SMS adımından öncesine kadar deneyebilirsiniz. - Oturum token'ı IP'ye bağlıdır.
downloadtoken'ın alındığı makineden yapılmalıdır. - Portal'da ayrı bir istisna kodu alanı yoktur. 302 gerekçesi yalnızca
not(serbest metin) alanına yazılır; bu kodu başka bir payload alanına yazan yapılandırılabilir bir mekanizma yoktur. draft,TRYpara birimiyle bir taslak tamamlayamaz — TCMB bülteninde TL'nin TL'ye kuru olmadığından kur adımıKur hatası: TRY ... bülteninde yok.ile durur.--pdfopsiyoneldir ve Playwright'ın ayrıca kurulmasını gerektirir; XML hukuken asıl belgedir.- GİB tek eşzamanlı oturuma izin verir — iki
faturakomutunu aynı anda çalıştırmayın.
GİB tek eşzamanlı oturuma izin verir. Bir fatura komutundan sonra oturum GİB tarafında açık kalırsa web portalına girerken bu hatayı alırsınız. fatura logout bunu gerçekten düzeltir, yalnızca yerel dosyayı silmez:
fatura logout --env prod
fatura logout --all # hem test hem prod- Önbellekte token varsa, o token'la GİB'e
assoscmd=logoutgönderilir, sonra yerel önbellek silinir. Kimlik bilgisi gerekmez. - Token yoksa (süreç çökmüş, Ctrl+C yenmiş),
credentials.jsonile kısa süreliğine giriş yapılıp hemen çıkılır — açık kalmış bir oturumu kapatmanın kurtarma yoludur. - Kimlik bilgisi de yoksa komut çökmez: yerel önbellek yine temizlenir, ama GİB'deki oturumun açık kalmış olabileceği belirtilir ve web portalındaki "Güvenli Çıkış" önerilir.
Ctrl+C ile de aynı koruma çalışır: bir komut giriş yaptıktan sonra SIGINT/SIGTERM alırsa, fatura mümkünse GİB oturumunu kapatıp öyle çıkar (çıkış kodu 130). Bu, sign'ın onay adımlarını etkilemez — SMS imzalama isteği hiçbir zaman Ctrl+C ile atılmaz, yalnızca ondan ÖNCEKİ adımlar iptal edilebilir.
Test ortamı
Varsayılan ortam test'tir (earsivportaltest.efatura.gov.tr). Kendi kullanıcınızı yaratmanıza gerek yok; portal tek kullanımlık hesap öneriyor:
curl -s -X POST https://earsivportaltest.efatura.gov.tr/earsiv-services/esign \
--data-urlencode 'assoscmd=kullaniciOner' --data-urlencode 'rtype=json'Yanıt {"userid":"<sayısal kod>"} şeklindedir; parolası her zaman sabit "1"'dir. Dönen kodu fatura login --env test ile kaydedin. userid boş dönerse havuz o an tükenmiştir, sonra tekrar deneyin.
Bu hesap paylaşımlıdır — aynı havuzdan başka geliştiriciler de kullanıcı alıyor ve oluşturduğunuz her belge portalda görünür kalıyor. Gerçek müşteri bilgilerinizi (unvan, adres, VAT ID) buraya koymayın; onun yerine
draft --dry-runkullanın: GİB'e hiç bağlanmaz, kimlik bilgisi bile gerektirmez, ama TCMB kurunu gerçekten çeker ve normaldraftile aynı özeti basar.--jsoneklerseniz alan alan doğrulayabilmeniz için tam payload'ı basar.
| Yol | İçerik | İzinler |
|---|---|---|
| ~/.config/fatura/config.json | Config | — |
| ~/.config/fatura/clients.json | Müşteri profilleri | 0700 dizin, 0600 dosya |
| ~/.config/fatura/credentials.json | GİB kullanıcı adı/parola, ortam başına | 0600 önerilir |
| ~/.cache/fatura/token-<env>.json | Oturum token önbelleği | 0700 / 0600 |
| ~/.cache/fatura/kur-*.json | TCMB kur önbelleği | 0700 / 0600 |
| archiveDir | İmzalanan/indirilen belgeler | 0700 / 0600 |
Arşiv düzeni — download (ve sign'ın otomatik arşivlemesi) belgeyi archiveDir/<yıl>/<ay>/ altına yazar:
<belgeNumarasi>_<musteriAnahtari>_<YYYY-MM-DD>.html
<belgeNumarasi>_<musteriAnahtari>_<YYYY-MM-DD>.xml
<belgeNumarasi>_<musteriAnahtari>_<YYYY-MM-DD>.json (kur denetim izi + GİB'in tam payload'ı)
<belgeNumarasi>_<musteriAnahtari>_<YYYY-MM-DD>.pdf (yalnızca --pdf ile)Bu mali veridir: dosyalar her yazımdan sonra chmod ile 0600'e sabitlenir. Yeni yıl/ay dizinleri 0700 açılır; ancak önceden var olan bir kök/yıl dizininin izinleri geriye dönük düzeltilmez.
export --year <YYYY> bu yapıyı tek ZIP'e paketler (varsayılan archiveDir/fatura-arsiv-<yıl>.zip).
GİB PDF üretmiyor — e-Arşiv Portal yalnızca HTML ve XML sunuyor. PDF, portalın döndürdüğü HTML'in istemci tarafında headless bir tarayıcıyla (Playwright/Chromium) render edilmesiyle üretilir.
Playwright bu paketin bağımlılığı değildir (~300 MB Chromium indirdiği için). --pdf verilip kurulu değilse:
PDF üretimi için Playwright gerekiyor (GİB PDF vermiyor, HTML'den üretiliyor).
pnpm add -D playwright && pnpm exec playwright install chromium
Not: yaklaşık 300 MB headless Chromium indirir.
Alternatif: --html veya --xml kullanın; XML hukuken asıl belgedir.XML, GİB'in gönderdiği ve hukuken asıl belgedir. PDF yalnızca okunabilirlik için türetilmiş bir ek çıktıdır. sign otomatik arşivlemede PDF üretmez (HTML+XML+JSON); PDF'i sonradan fatura download <ettn> --pdf ile alırsınız.
| Kod | Anlam |
|---|---|
| 0 | Başarılı |
| 1 | Genel/beklenmeyen hata |
| 2 | Kimlik doğrulama/oturum/yetki hatası |
| 3 | Ağ hatası |
| 4 | Doğrulama hatası (geçersiz bayrak, onay reddedildi, TTY yok, ...) |
| 5 | TCMB kur hatası |
| 6 | Config hatası (bozuk JSON veya şemaya uymuyor) |
| 130 | Ctrl+C (SIGINT) veya SIGTERM |
git clone https://github.com/erenkan/earsiv-istisna.git
cd earsiv-istisna
corepack enable
pnpm install
pnpm buildWSL kullanıcıları için corepack enable şarttır. Windows tarafındaki bir pnpm/npm kurulumu PATH'e sızmışsa (/mnt/c/... altında bir pnpm.exe) o binary WSL içinde çöker; corepack enable doğru ikiliyi PATH'e önce koyar.
Derlenen sürümü global fatura yapmak için en güvenilir yol sembolik bağdır:
mkdir -p ~/.local/bin
ln -sf "$PWD/dist/cli/index.js" ~/.local/bin/fatura
which fatura # ~/.local/bin/fatura~/.local/bin PATH'te değilse: echo 'export PATH="$HOME/.local/bin:$PATH"' >> ~/.bashrc. Sembolik bağ dist/cli/index.js'i gösterir, pnpm build sonrası otomatik güncellenir. Hiç kurulum yapmadan node dist/cli/index.js whoami de tamamen eşdeğerdir.
pnpm link --globalde kullanılabilir ama pnpm'in global bin dizini PATH'te değilse (pnpm setupçalıştırılmamışsa) açık bir hatayla exit 1 verir.
Test:
pnpm test # birim testleri, gerçek ağ isteği YOK
pnpm test:watch
pnpm test:integration # GERÇEK test ortamına HTTP isteği atar - CI'da çalıştırmayın
pnpm typecheckYapı — tek npm paketi, dizin düzeyinde iki katman:
src/core/— GİB HTTP istemcisi, TCMB kur çekme, para aritmetiği (Decimal), fatura payload şablonu. Saf fonksiyonlar;console.*/process.exit/ dosya sistemi erişimi yok.src/cli/—faturakomut satırı aracı (Commander.js + Ink). Config/credential/arşiv erişimi burada.test/core/,test/cli/— aynı ayrımla eşleşen testler.
Derleme çıktısı dist/core/ ve dist/cli/ altına yazılır (dist/cli/index.js = fatura). Yayımlanan npm paketinde yalnızca dist/ ve README.md bulunur.
