turkiyem 1.9.0 → 1.10.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 CHANGED
@@ -12,7 +12,7 @@
12
12
  </p>
13
13
 
14
14
  <p align="center">
15
- 8 şehrin toplu taşıma verileri, AFAD deprem bilgileri, Open-Meteo hava durumu, TCMB döviz kurları — hepsi tek bir <code>npm</code> paketi içinde.
15
+ 9 şehrin toplu taşıma verileri, güncel nöbetçi eczaneler, AFAD deprem bilgileri, Open-Meteo hava durumu, TCMB döviz kurları — hepsi tek bir <code>npm</code> paketi içinde.
16
16
  </p>
17
17
 
18
18
  ---
@@ -52,6 +52,7 @@ Türkiye'de toplu taşıma verileri onlarca farklı belediye sitesi, API ve veri
52
52
 
53
53
  - 🔎 Tarayıcı açmadan **hat ve durak sorgulama**
54
54
  - 📍 Terminal üzerinden **canlı araç takibi** (İstanbul, Bursa)
55
+ - 💊 Anlık **nöbetçi eczane** sorgulama seçenekleri
55
56
  - 🌍 **Deprem bildirimleri** renkli uyarılarla
56
57
  - ⛅ **Hava durumu** ve **hava kalitesi** API key gerektirmeden
57
58
  - 💱 **TCMB döviz kurları** tek komutla
@@ -71,6 +72,8 @@ Türkiye'de toplu taşıma verileri onlarca farklı belediye sitesi, API ve veri
71
72
  | **İzmir** | ESHOT (GTFS Açık Veri) | ✅ | ✅ | — | ✅ |
72
73
  | **Trabzon** | Trabzon Büyükşehir Belediyesi | ✅ | — | — | ✅ |
73
74
  | **Samsun** | Samulaş | ✅ | ✅ | — | ✅ |
75
+ | **Mersin** | Mersin Büyükşehir Belediyesi | ✅ | — | — | ✅ |
76
+ | **Kayseri** | Sadece Nöbetçi Eczane | — | — | — | — |
74
77
 
75
78
  > Yeni şehir entegrasyonları için [yol haritasına](#-yol-haritası) bakın.
76
79
 
@@ -78,13 +81,18 @@ Türkiye'de toplu taşıma verileri onlarca farklı belediye sitesi, API ve veri
78
81
 
79
82
  ## ✨ Özellikler
80
83
 
81
- ### 🚌 Toplu Taşıma (8 Şehir)
84
+ ### 🚌 Toplu Taşıma (9 Şehir)
82
85
  - Hat numarası veya adıyla arama
83
86
  - Durak listesi ve sıralı güzergah görüntüleme
84
87
  - Sefer saatleri (gün tipi ve yöne göre)
85
88
  - Durak bazlı geçen hat ve zaman sorgulama
86
89
  - Birden fazla sonuçta interaktif seçim menüsü
87
90
 
91
+ ### 💊 Sağlık & Nöbetçi Eczane
92
+ - **İzmir** ve **Kayseri** için nöbetçi eczane sorgulama
93
+ - İzmir genel eczane arama ve lokasyon bilgisi
94
+ - Telefon numarası ve harita bağlantısı gösterimi
95
+
88
96
  ### 📍 Canlı Araç Takibi
89
97
  - **İstanbul (IETT):** Anlık araç konumu, yön, yakın durak bilgisi
90
98
  - **Bursa (Burulaş):** Plaka, hız, doluluk oranı gösterimi
@@ -185,6 +193,9 @@ turkiyem sehir adana # Şehri Adana olarak ayarla
185
193
  turkiyem sehir antalya # Şehri Antalya olarak ayarla
186
194
  turkiyem sehir bursa # Şehri Bursa olarak ayarla
187
195
  turkiyem sehir izmir # Şehri İzmir olarak ayarla
196
+ turkiyem sehir samsun # Şehri Samsun olarak ayarla
197
+ turkiyem sehir mersin # Şehri Mersin olarak ayarla
198
+ turkiyem sehir kayseri # Şehri Kayseri olarak ayarla
188
199
  ```
189
200
 
190
201
  > 💡 `hat` ve `durak` komutları her zaman seçili şehre göre çalışır.
@@ -219,10 +230,26 @@ turkiyem hat 34
219
230
  # Trabzon — Hat bilgisi + kalkış ve dönüş yönlü sefer saatleri
220
231
  turkiyem sehir trabzon
221
232
  turkiyem hat 103
233
+
234
+ # Samsun (Samulaş) — Hat bilgisi + duraklar + kalkış saatleri
235
+ turkiyem sehir samsun
236
+ turkiyem hat E1
237
+
238
+ # Mersin — Hat bilgisi + kalkış saatleri
239
+ turkiyem sehir mersin
240
+ turkiyem hat 11M # veya 'merkez' yazarak hat seçimi yapabilirsiniz
222
241
  ```
223
242
 
224
243
  > Birden fazla eşleşen hat varsa interaktif bir seçim menüsü sunulur.
225
244
 
245
+ ### Sağlık & Nöbetçi Eczane (İzmir / Kayseri)
246
+
247
+ ```bash
248
+ turkiyem eczane nobetci # Seçili şehirdeki tüm nöbetçi eczaneleri listeler
249
+ turkiyem eczane nobetci bornova # Seçili şehirde "bornova" ilçesi için arar
250
+ turkiyem eczane ara yusuf # İzmir'de adı/adresi "yusuf" olan tüm eczaneleri getirir
251
+ ```
252
+
226
253
  ### Durak Sorgulama
227
254
 
228
255
  ```bash
@@ -314,6 +341,10 @@ turkiyem temizle # Cache ve yapılandırmayı sıfırla
314
341
  | [Burulaş (Bursakart)](https://www.bursakart.com.tr) | Hat / durak / canlı konum | Bursa | Kamu API |
315
342
  | [ESHOT GTFS](https://acikveri.bizizmir.com) | Hat / durak / sefer saatleri | İzmir | İzmir Açık Veri Lisansı |
316
343
  | [Trabzon Büyükşehir](https://ulasim.trabzon.bel.tr) | Hat / sefer saatleri | Trabzon | Kamu verisi |
344
+ | [Samulaş](https://samulas.com.tr) | Hat / durak / sefer saatleri | Samsun | Kamu verisi |
345
+ | [Mersin Büyükşehir](https://ulasim.mersin.bel.tr) | Hat / sefer saatleri | Mersin | Kamu API |
346
+ | [İzmir BB Açık Veri](https://acikveri.bizizmir.com) | Eczane Bilgileri | İzmir | İzmir Açık Veri Lisansı |
347
+ | [Kayseri BB Açık Veri](https://acikveri.kayseri.bel.tr) | Nöbetçi Eczaneler | Kayseri | Kamu API |
317
348
  | [Open-Meteo](https://open-meteo.com) | Hava durumu, hava kalitesi | Tüm dünya | CC BY 4.0 |
318
349
  | [TCMB](https://www.tcmb.gov.tr) | Döviz kurları | — | Kamu verisi |
319
350
 
@@ -470,11 +501,11 @@ Detaylı yol haritası için [`TODO.md`](./TODO.md) dosyasına bakın.
470
501
  |---------|-------|
471
502
  | Kocaeli GTFS Verileri | 📋 Planlandı |
472
503
  | Konya GTFS Verileri | 📋 Planlandı |
473
- | Mersin Ulaşım Tarifeleri | 📋 Planlandı |
474
- | Samsun Otobüs Bilgileri | 📋 Planlandı |
504
+ | Mersin Ulaşım Tarifeleri | Tamamlandı |
505
+ | Samsun Otobüs Bilgileri | Tamamlandı |
475
506
  | Trabzon Ulaşım Bilgileri | ✅ Tamamlandı |
476
- | İzmir Nöbetçi Eczane | 📋 Planlandı |
477
- | Kayseri Nöbetçi Eczane | 📋 Planlandı |
507
+ | İzmir Nöbetçi Eczane | Tamamlandı |
508
+ | Kayseri Nöbetçi Eczane | Tamamlandı |
478
509
  | e-Nabız / e-Sağlık | 📋 Planlandı |
479
510
 
480
511
  ---
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "turkiyem",
3
- "version": "1.9.0",
3
+ "version": "1.10.0",
4
4
  "description": "Türkiye Toplu Taşıma ve Deprem CLI aracı - AFAD deprem verileri, EGO hat saatleri ve IETT SOAP/GTFS bilgileri",
5
5
  "type": "module",
6
6
  "main": "./src/index.js",
@@ -2,157 +2,50 @@ import chalk from 'chalk';
2
2
  import prompts from 'prompts';
3
3
  import { printBanner } from '../utils/banner.js';
4
4
  import { getCity } from '../utils/config.js';
5
- import { sehirSec } from './sehir.js';
6
- import { hatSorgula, hatCanliSorgula } from './hat.js';
7
- import { depremSon24, deprem7Gun, depremBuyukluk } from './deprem.js';
8
- import { havaGuncel, havaSaatlik, havaKalitesi } from './hava.js';
9
- import { dovizKurlari } from './doviz.js';
10
- import { durakSorgula } from './durak.js';
11
5
 
12
6
  function printSessionHeader() {
13
7
  const city = getCity();
14
8
  const cityLabel = city ? chalk.green.bold(city) : chalk.yellow('seçilmedi');
15
9
  console.log('');
16
10
  console.log(chalk.gray('─'.repeat(60)));
17
- console.log(chalk.gray(` 🏙️ Aktif şehir: ${cityLabel} │ ${chalk.gray('Çıkmak için: Ctrl+C veya "Çıkış"')}`));
11
+ console.log(chalk.gray(` 🏙️ Aktif şehir: ${cityLabel} │ ${chalk.gray('Çıkmak için: Ctrl+C veya "exit"')}`));
18
12
  console.log(chalk.gray('─'.repeat(60)));
19
13
  console.log('');
20
14
  }
21
15
 
22
16
  export async function showMenu() {
23
17
  printBanner();
24
- console.log(chalk.white.bold(' 🇹🇷 Sürekli oturum modu — İşlem bitince otomatik menüye döner.\n'));
18
+ console.log(chalk.white.bold(' 🇹🇷 Sürekli oturum modu — Komutları direkt yazabilirsiniz (Örn: hat 500T, deprem son24)\n'));
19
+ console.log(chalk.gray(' Tüm komutları görmek için "help" yazabilirsiniz.\n'));
25
20
 
26
21
  // REPL loop — kullanıcı çıkış seçene kadar devam et
27
22
  while (true) {
28
23
  printSessionHeader();
29
24
 
30
- const response = await prompts({
31
- type: 'select',
32
- name: 'action',
33
- message: 'Ne yapmak istersin?',
34
- choices: [
35
- { title: '🚌 Toplu Taşıma (Hat Sorgula)', value: 'hat' },
36
- { title: '📍 Canlı Araç Takibi', value: 'canli' },
37
- { title: '🚏 Durak Sorgula', value: 'durak' },
38
- { title: '🌍 Deprem Bilgileri', value: 'deprem' },
39
- { title: '⛅ Hava Durumu', value: 'hava' },
40
- { title: '💱 Döviz Kurları (TCMB)', value: 'doviz' },
41
- { title: '⚙️ Şehir Değiştir', value: 'sehir' },
42
- { title: '❌ Çıkış', value: 'exit' }
43
- ]
25
+ const { cmd } = await prompts({
26
+ type: 'text',
27
+ name: 'cmd',
28
+ message: chalk.cyan('turkiyem >')
44
29
  });
45
30
 
46
- // Ctrl+C veya Çıkış
47
- if (!response.action || response.action === 'exit') {
31
+ if (cmd === undefined || cmd.trim().toLowerCase() === 'exit' || cmd.trim().toLowerCase() === 'çıkış') {
48
32
  console.log('');
49
33
  console.log(chalk.cyan(' Görüşmek üzere! 🇹🇷👋'));
50
34
  console.log('');
51
35
  break;
52
36
  }
53
37
 
38
+ const args = cmd.trim().split(' ').filter(Boolean);
39
+
40
+ if (args.length === 0) {
41
+ continue;
42
+ }
43
+
54
44
  try {
55
- switch (response.action) {
56
- case 'hat': {
57
- const { hatNo } = await prompts({
58
- type: 'text',
59
- name: 'hatNo',
60
- message: 'Hat numarasını/adını girin:'
61
- });
62
- if (hatNo) await hatSorgula(hatNo);
63
- break;
64
- }
65
- case 'canli': {
66
- const { hatNo } = await prompts({
67
- type: 'text',
68
- name: 'hatNo',
69
- message: 'Canlı takip için hat numarasını girin:'
70
- });
71
- if (hatNo) await hatCanliSorgula(hatNo, {});
72
- break;
73
- }
74
- case 'durak': {
75
- const { stopId } = await prompts({
76
- type: 'text',
77
- name: 'stopId',
78
- message: 'Durak numarasını/adını girin:'
79
- });
80
- if (stopId) await durakSorgula(stopId);
81
- break;
82
- }
83
- case 'deprem': {
84
- const { subAction } = await prompts({
85
- type: 'select',
86
- name: 'subAction',
87
- message: 'Hangi deprem verisi?',
88
- choices: [
89
- { title: '🕐 Son 24 Saat', value: 'son24' },
90
- { title: '📅 Son 7 Gün', value: '7gun' },
91
- { title: '📊 Büyüklüğe Göre Filtrele', value: 'buyukluk' },
92
- { title: '↩ Geri', value: 'back' }
93
- ]
94
- });
95
- if (subAction === 'son24') await depremSon24();
96
- else if (subAction === '7gun') await deprem7Gun();
97
- else if (subAction === 'buyukluk') {
98
- const { deger } = await prompts({
99
- type: 'text',
100
- name: 'deger',
101
- message: 'Minimum büyüklük değeri (ör: 4.0):'
102
- });
103
- if (deger) await depremBuyukluk(deger);
104
- }
105
- break;
106
- }
107
- case 'hava': {
108
- const { subAction } = await prompts({
109
- type: 'select',
110
- name: 'subAction',
111
- message: 'Hangi hava verisi?',
112
- choices: [
113
- { title: '🌡️ Güncel Hava', value: 'guncel' },
114
- { title: '⏱️ Saatlik Tahmin', value: 'saatlik' },
115
- { title: '🏭 Hava Kalitesi', value: 'kalite' },
116
- { title: '↩ Geri', value: 'back' }
117
- ]
118
- });
119
- if (subAction === 'back') break;
120
- const { konum } = await prompts({
121
- type: 'text',
122
- name: 'konum',
123
- message: 'Şehir adı veya koordinat (boş bırakırsan seçili şehir):'
124
- });
125
- const loc = konum || undefined;
126
- if (subAction === 'guncel') await havaGuncel(loc);
127
- else if (subAction === 'saatlik') await havaSaatlik(loc, 2);
128
- else if (subAction === 'kalite') await havaKalitesi(loc);
129
- break;
130
- }
131
- case 'doviz':
132
- await dovizKurlari({ tum: false });
133
- break;
134
- case 'sehir': {
135
- const { sehir } = await prompts({
136
- type: 'select',
137
- name: 'sehir',
138
- message: 'Hangi şehri seçmek istersiniz?',
139
- choices: [
140
- { title: 'Ankara', value: 'ankara' },
141
- { title: 'İstanbul', value: 'istanbul' },
142
- { title: 'Adana', value: 'adana' },
143
- { title: 'Antalya', value: 'antalya' },
144
- { title: 'Bursa', value: 'bursa' },
145
- { title: 'İzmir', value: 'izmir' },
146
- { title: 'Trabzon', value: 'trabzon' },
147
- { title: 'Samsun', value: 'samsun' }
148
- ]
149
- });
150
- if (sehir) sehirSec(sehir);
151
- break;
152
- }
153
- }
45
+ const { spawnSync } = await import('node:child_process');
46
+ spawnSync(process.argv[0], [process.argv[1], ...args], { stdio: 'inherit' });
154
47
  } catch (err) {
155
- console.log(chalk.red(` Hata: ${err.message}`));
48
+ console.log(chalk.red(`\n Komut çalıştırılamadı: ${err.message}`));
156
49
  }
157
50
  }
158
51
  }