yokatlas-api-wrapper 1.0.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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Cem
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,238 @@
1
+ # yokatlas-api-wrapper
2
+
3
+ Bu proje, YÖK Atlas'ın tercih kılavuzu JSON API'sine Node.js ortamından doğrudan, hızlı ve güvenilir bir şekilde erişim sağlamak amacıyla geliştirilmiş, TypeScript tabanlı resmî olmayan bir sarmalayıcı (wrapper) kütüphanedir. Herhangi bir dış bağımlılığa veya ikili (binary) dosyaya ihtiyaç duymadan HTTP üzerinden güncel verileri çeker.
4
+
5
+ ## Kurulum
6
+
7
+ Projeyi Node.js projenize dahil etmek için:
8
+
9
+ ```bash
10
+ npm install yokatlas-api-wrapper
11
+ ```
12
+
13
+ ## Kullanım Başlangıcı
14
+
15
+ Modül tamamen statik bir sınıf üzerinden çalışır; örnekleme (instantiation) gerekmez. CommonJS ve ECMAScript Modules (ESM) yapıları tam olarak desteklenmektedir.
16
+
17
+ ```typescript
18
+ import { YokAtlas } from 'yokatlas-api-wrapper';
19
+
20
+ // Boğaziçi'nde sayısal tüm programlar (akıllı arama: serbest yazım otomatik ID'ye çözülür)
21
+ const sayfa = await YokAtlas.search({ puanTuru: 'SAY', universite: 'boğaziçi' }, { size: 20 });
22
+
23
+ console.log(`Toplam: ${sayfa.totalElements}`);
24
+ for (const program of sayfa.content) {
25
+ console.log(`${program.universiteAdi} — ${program.birimAdi} | ${program.current.minPuan} (${program.current.basariSirasi})`);
26
+ }
27
+
28
+ // Tek bir program (kılavuz kodu ile)
29
+ const program = await YokAtlas.getProgram(102210277);
30
+ if (program) {
31
+ console.log(program.current, program.history);
32
+ }
33
+ ```
34
+
35
+ ### Net Sihirbazı (son yerleşen kişinin netleri)
36
+
37
+ ```typescript
38
+ import { YokAtlas } from 'yokatlas-api-wrapper';
39
+
40
+ const sayfa = await YokAtlas.searchNetler({
41
+ universite: 'boğaziçi',
42
+ program: 'bilgisayar mühendisliği',
43
+ });
44
+
45
+ for (const net of sayfa.content) {
46
+ console.log(`${net.yil}: TYT Mat ${net.tytMatNet} / AYT Fizik ${net.aytFizNet}`);
47
+ }
48
+ ```
49
+
50
+ ### Akıllı arama (fuzzy Türkçe eşleşme)
51
+
52
+ `universite`, `program` ve `il` alanları serbest yazımı kabul eder; Türkçe karakter normalizasyonu ve fuzzy eşleşme ile en yakın kayda çözülür — büyük/küçük harf, ünlü noktalama (İ/I, Ş/S...) ve küçük yazım hataları önemli değildir.
53
+
54
+ ```typescript
55
+ import { YokAtlas } from 'yokatlas-api-wrapper';
56
+
57
+ await YokAtlas.search({ universite: 'ODTÜ', il: 'ankara' });
58
+ await YokAtlas.search({ universite: 'bogazici' }); // "Boğaziçi" ile eşleşir
59
+
60
+ // Lookup kaydının kendisini almak istiyorsanız:
61
+ const uni = await YokAtlas.findUniversity('boğazici');
62
+ console.log(uni.universiteId, uni.universiteAdi);
63
+ ```
64
+
65
+ Eşleşme bulunamazsa `YokAtlasLookupError` fırlatılır ve en yakın 3 öneriyi içerir.
66
+
67
+ ## API Referansı ve Fonksiyonlar
68
+
69
+ Aşağıdaki metotlar `YokAtlas` sınıfı üzerinden statik olarak erişilebilir durumdadır:
70
+
71
+ ### 1. Temel Arama
72
+
73
+ - **`YokAtlas.search(filters?, options?)`**: Tercih kılavuzunda program arar, sayfalanmış `SearchPage<Program>` döner.
74
+ - **`YokAtlas.searchNetler(filters?, options?)`**: Net Sihirbazı'nı sorgular, sayfalanmış `SearchPage<Net>` döner.
75
+ - **`YokAtlas.getProgram(kilavuzKodu)`**: Tek bir programı ÖSYM kılavuz kodundan getirir; bulunamazsa `null` döner.
76
+ - **`YokAtlas.getPrograms(kilavuzKodlari, { concurrency? })`**: Birden çok programı sınırlı eşzamanlılıkla getirir; her kod bağımsız `fulfilled`/`rejected` sonucuyla döner (biri başarısız olursa diğerlerini etkilemez).
77
+ - **`YokAtlas.searchAllPages(filters?, options?)`**: `search()`'ü otomatik olarak sayfa sayfa dolaşıp tüm sonuçları düz bir `Program[]` dizisine toplar (`maxPages` güvenlik sınırıyla).
78
+
79
+ ### 2. Lookup Tabloları
80
+
81
+ - **`YokAtlas.listUniversities()`**: Tüm üniversiteleri (ID + ad) döner.
82
+ - **`YokAtlas.listProgramGroups()`**: Tüm program gruplarını (ID + ad + puan türü) döner.
83
+ - **`YokAtlas.listCities()`**: Tüm illeri (kod + ad) döner.
84
+ - **`YokAtlas.findUniversity(name)` / `findProgramGroup(name)` / `findCity(name)`**: Serbest yazılmış bir adı fuzzy eşleştirerek ilgili lookup kaydına çözer.
85
+ - **`YokAtlas.refreshLookups()`**: Lookup önbelleğini zorla yeniler.
86
+ - **`YokAtlas.clearCache()`**: Lookup önbelleğini boşaltır.
87
+ - **`YokAtlas.getCacheStatus()`**: Önbelleğin dolu olup olmadığını, ne zaman çekildiğini ve kaç kayıt içerdiğini döner.
88
+
89
+ ### 3. Kısayol Aramalar
90
+
91
+ Sık kullanılan filtre kombinasyonları için okunabilirlik kısayolları:
92
+
93
+ - **`YokAtlas.searchByUniversity(universiteAdi, filters?, options?)`**
94
+ - **`YokAtlas.searchByProgram(programAdi, filters?, options?)`**
95
+ - **`YokAtlas.searchByCity(ilAdi, filters?, options?)`**
96
+ - **`YokAtlas.searchLisans(filters?, options?)`**: Sadece lisans (4 yıllık) programları.
97
+ - **`YokAtlas.searchOnlisans(filters?, options?)`**: Sadece ön lisans (2 yıllık) programları.
98
+ - **`YokAtlas.searchBurslu(filters?, options?)`**: Sadece ücretsiz/tam burslu programlar.
99
+ - **`YokAtlas.searchByScoreRange({ min?, max? }, filters?, options?)`**: Belirli bir başarı sırası aralığı.
100
+
101
+ ```typescript
102
+ const programlar = await YokAtlas.searchByUniversity('İTÜ', { puanTuru: 'SAY' });
103
+ const hukukProgramlari = await YokAtlas.searchByProgram('hukuk', { universiteTuru: 'DEVLET' });
104
+ const tumIstanbul = await YokAtlas.searchAllPages({ il: 'istanbul', puanTuru: 'EA' });
105
+ ```
106
+
107
+ ### 4. Türetilmiş / Çevrimdışı Analiz Yardımcıları
108
+
109
+ Bu metotlar ekstra bir ağ isteği yapmaz; zaten çekilmiş `Program` nesneleri üzerinde çalışır.
110
+
111
+ - **`YokAtlas.estimateAdmission(program, basariSirasi)`**: Kullanıcının kendi başarı sırasını programın güncel yıl kesme sırasıyla karşılaştırıp `"kesine yakın" | "olası" | "sınırda" | "zayıf" | "belirsiz"` şeklinde kaba bir yerleşme tahmini üretir.
112
+ - **`YokAtlas.compare(programA, programB)`**: İki programı güncel yıl rekabet düzeyi (başarı sırası) ve kontenjan farkı açısından karşılaştırır.
113
+ - **`YokAtlas.getTrend(program)`**: Programın `history` + `current` verisindeki başarı sırası dizisine bakarak `"yükseliyor" | "düşüyor" | "sabit" | "belirsiz"` eğilimini kestirir.
114
+ - **`YokAtlas.groupBy(programs, keyFn)`**: Bir program dizisini verilen anahtar fonksiyonuna göre gruplar (örn. şehre, üniversite türüne).
115
+ - **`YokAtlas.sortByScore(programs, direction?)`**: Bir program dizisini güncel yıl başarı sırasına göre sıralar.
116
+ - **`YokAtlas.formatSummary(program)`**: Bir programı tek satırlık okunur bir özet metnine çevirir (log/konsol için).
117
+
118
+ ```typescript
119
+ const boğaziçiBilgisayar = await YokAtlas.getProgram(102210277);
120
+ if (boğaziçiBilgisayar) {
121
+ const tahmin = YokAtlas.estimateAdmission(boğaziçiBilgisayar, 950);
122
+ console.log(tahmin.verdict, tahmin.message);
123
+
124
+ const trend = YokAtlas.getTrend(boğaziçiBilgisayar);
125
+ console.log(trend.direction, trend.message);
126
+ }
127
+
128
+ const tumProgramlar = await YokAtlas.searchAllPages({ il: 'izmir' });
129
+ const sehreGoreGrupla = YokAtlas.groupBy(tumProgramlar, (p) => p.universiteAdi);
130
+ const enIyiden = YokAtlas.sortByScore(tumProgramlar, 'asc');
131
+ console.log(tumProgramlar.map(YokAtlas.formatSummary).join('\n'));
132
+ ```
133
+
134
+ ### 5. Yapılandırma
135
+
136
+ ```typescript
137
+ import { YokAtlas } from 'yokatlas-api-wrapper';
138
+
139
+ YokAtlas.configure({
140
+ timeoutMs: 60_000,
141
+ maxRetries: 3,
142
+ lookupCacheTtlMs: 600_000, // 10 dakika
143
+ userAgent: 'kendi-uygulamam/1.0',
144
+ });
145
+ ```
146
+
147
+ | Alan | Varsayılan | Açıklama |
148
+ |---|---|---|
149
+ | `baseUrl` | `https://yokatlas.yok.gov.tr` | API kökü |
150
+ | `timeoutMs` | `30000` | HTTP zaman aşımı (ms) |
151
+ | `maxRetries` | `2` | Ağ hatalarında (bağlantı kopması vb.) yeniden deneme sayısı |
152
+ | `lookupCacheTtlMs` | `3600000` | Üniversite/program/il lookup önbelleği ömrü (ms), `0` = sonsuz |
153
+ | `userAgent` | `yokatlas-api-wrapper/1.0` | User-Agent başlığı |
154
+
155
+ ## Filtreler
156
+
157
+ ### `search()` — `SearchFilters`
158
+
159
+ | Alan | Tip | Açıklama |
160
+ |---|---|---|
161
+ | `puanTuru` | `"SAY" \| "SÖZ" \| "EA" \| "DİL" \| "TYT"` | Puan türü |
162
+ | `universite` / `universiteId` | `string \| string[]` / `number[]` | Üniversite (akıllı veya ID) |
163
+ | `program` / `birimGrupId` | `string \| string[]` / `number[]` | Program grubu |
164
+ | `il` / `ilKodu` | `string \| string[]` / `number[]` | İl |
165
+ | `birimTuruId` | `number` | 46 = LİSANS, 47 = ÖNLİSANS |
166
+ | `universiteTuru` | `"DEVLET" \| "VAKIF"` | Üniversite türü |
167
+ | `bursOraniId` | `number` | 0 = Ücretsiz/Burslu |
168
+ | `ogrenimTuruId` | `number` | Örgün/İkinci öğretim |
169
+ | `kilavuzKodu` | `number` | Tek programa filtre |
170
+ | `minBasariSirasi` / `maxBasariSirasi` | `number` | Başarı sırası aralığı |
171
+
172
+ > Akıllı (string) alanlar ile ID alanları aynı anda verilmemelidir — biri seçilir.
173
+
174
+ ### `searchNetler()` — `NetFilters`
175
+
176
+ `SearchFilters`'in aksine `universiteId`/`birimGrupId` **tekildir** — Net Sihirbazı endpoint'i liste kabul etmez. Ayrıca `universite`/`program` de tekildir (liste değil).
177
+
178
+ ## Yapı
179
+
180
+ Bir `Program` 4 yıllık veri taşır:
181
+
182
+ ```typescript
183
+ program.current // YearlyStats: en güncel yıl
184
+ program.history // YearlyStats[]: 3 önceki yıl (yeni → eski)
185
+ ```
186
+
187
+ `YearlyStats` alanları: `year, kontenjan, yerlesen, kontenjanObs, kontenjanY34, prof, doc, dou, ogrGor, arGor, kpss1, kpss2, minPuan, basariSirasi`.
188
+
189
+ ## Sabitler ve Etiketler
190
+
191
+ Sık kullanılan ID'ler ve okunur Türkçe etiket çeviricileri `src/constants.ts` altında dışa aktarılır:
192
+
193
+ ```typescript
194
+ import { BIRIM_TURU, getPuanTuruLabel, getBirimTuruLabel, getUniversiteTuruLabel } from 'yokatlas-api-wrapper';
195
+
196
+ BIRIM_TURU.LISANS; // 46
197
+ BIRIM_TURU.ONLISANS; // 47
198
+
199
+ getPuanTuruLabel('SAY'); // "Sayısal"
200
+ getBirimTuruLabel('ONLISANS'); // "Ön Lisans"
201
+ getUniversiteTuruLabel('VAKIF'); // "Vakıf Üniversitesi"
202
+ ```
203
+
204
+ ## Hata Yönetimi
205
+
206
+ Kütüphane, ayırt edilebilir hata sınıfları fırlatır (hepsi `YokAtlasError`'dan türer):
207
+
208
+ - **`YokAtlasValidationError`**: Geçersiz bir parametre verildiğinde (örn. sayısal olmayan kılavuz kodu).
209
+ - **`YokAtlasAPIError`**: Ağ isteği başarısız olduğunda, YÖK Atlas sunucusu HTTP hata kodu döndüğünde veya cevap JSON olarak parse edilemediğinde (`status` ve `body` alanlarını taşır).
210
+ - **`YokAtlasNotFoundError`**: Sunucu 404 döndüğünde (`YokAtlasAPIError`'dan türer).
211
+ - **`YokAtlasRateLimitError`**: Sunucu oran sınırlama (418/429) döndüğünde (`YokAtlasAPIError`'dan türer).
212
+ - **`YokAtlasLookupError`**: Akıllı arama bir isim/kayıt çözemediğinde (`kind` ve `suggestions` alanlarını taşır).
213
+
214
+ ```typescript
215
+ import { YokAtlas, YokAtlasLookupError, YokAtlasAPIError } from 'yokatlas-api-wrapper';
216
+
217
+ try {
218
+ await YokAtlas.search({ universite: 'var olmayan bir üniversite' });
219
+ } catch (e) {
220
+ if (e instanceof YokAtlasLookupError) {
221
+ console.log('Bulunamadı:', e.message, e.suggestions);
222
+ } else if (e instanceof YokAtlasAPIError) {
223
+ console.log('API hatası:', e.message, e.status);
224
+ }
225
+ }
226
+ ```
227
+
228
+ ## Geliştirme
229
+
230
+ ```bash
231
+ npm install
232
+ npm run build
233
+ npm test
234
+ ```
235
+
236
+ ## Lisans
237
+
238
+ MIT