nobetci-eczane-api 1.0.0 → 1.0.2

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/dist/index.d.mts CHANGED
@@ -130,7 +130,7 @@ interface NearbyOptions {
130
130
  interface EczaneAPIOptions {
131
131
  /** Eczaneler.ORG v2 REST API Anahtarı */
132
132
  apiKey: string;
133
- /** Özel API Base URL (Varsayılan: https://eczaneler.org/api/v2) */
133
+ /** Özel API Base URL (Varsayılan: https://api.eczaneler.org/api/v2) */
134
134
  baseUrl?: string;
135
135
  /** İstek zaman aşımı süresi milisaniye cinsinden (varsayılan: 10000ms - 10s) */
136
136
  timeout?: number;
package/dist/index.d.ts CHANGED
@@ -130,7 +130,7 @@ interface NearbyOptions {
130
130
  interface EczaneAPIOptions {
131
131
  /** Eczaneler.ORG v2 REST API Anahtarı */
132
132
  apiKey: string;
133
- /** Özel API Base URL (Varsayılan: https://eczaneler.org/api/v2) */
133
+ /** Özel API Base URL (Varsayılan: https://api.eczaneler.org/api/v2) */
134
134
  baseUrl?: string;
135
135
  /** İstek zaman aşımı süresi milisaniye cinsinden (varsayılan: 10000ms - 10s) */
136
136
  timeout?: number;
package/dist/index.js CHANGED
@@ -56,7 +56,7 @@ var TimeoutError = class extends EczaneAPIError {
56
56
  };
57
57
 
58
58
  // src/client.ts
59
- var DEFAULT_BASE_URL = "https://eczaneler.org/api/v2";
59
+ var DEFAULT_BASE_URL = "https://api.eczaneler.org/api/v2";
60
60
  var DEFAULT_TIMEOUT = 1e4;
61
61
  var EczaneAPI = class {
62
62
  apiKey;
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/errors.ts","../src/client.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["/**\n * Nöbetçi Eczane API Özel Hata Sınıfları\n */\n\nexport class EczaneAPIError extends Error {\n public readonly status: number;\n public readonly code?: string;\n public readonly details?: unknown;\n\n constructor(message: string, status: number = 500, code?: string, details?: unknown) {\n super(message);\n this.name = 'EczaneAPIError';\n this.status = status;\n this.code = code;\n this.details = details;\n\n Object.setPrototypeOf(this, new.target.prototype);\n }\n}\n\nexport class AuthenticationError extends EczaneAPIError {\n constructor(message: string = 'Geçersiz veya eksik API anahtarı (X-Api-Key).') {\n super(message, 401, 'UNAUTHORIZED');\n this.name = 'AuthenticationError';\n }\n}\n\nexport class ForbiddenError extends EczaneAPIError {\n constructor(message: string = 'Erişim engellendi. IP adresiniz whitelist listesinde olmayabilir veya yetkisiz istek.') {\n super(message, 403, 'FORBIDDEN');\n this.name = 'ForbiddenError';\n }\n}\n\nexport class NotFoundError extends EczaneAPIError {\n constructor(message: string = 'İstenen kaynak veya eczane kaydı bulunamadı.') {\n super(message, 404, 'NOT_FOUND');\n this.name = 'NotFoundError';\n }\n}\n\nexport class RateLimitError extends EczaneAPIError {\n public readonly resetInSeconds?: number;\n\n constructor(message: string = 'API istek limiti aşıldı. Lütfen bir süre sonra tekrar deneyiniz.', resetInSeconds?: number) {\n super(message, 429, 'RATE_LIMIT_EXCEEDED');\n this.name = 'RateLimitError';\n this.resetInSeconds = resetInSeconds;\n }\n}\n\nexport class InvalidRequestError extends EczaneAPIError {\n constructor(message: string = 'Geçersiz istek parametreleri veya koordinat verisi.', details?: unknown) {\n super(message, 400, 'BAD_REQUEST', details);\n this.name = 'InvalidRequestError';\n }\n}\n\nexport class TimeoutError extends EczaneAPIError {\n constructor(message: string = 'İstek zaman aşımına uğradı.') {\n super(message, 408, 'REQUEST_TIMEOUT');\n this.name = 'TimeoutError';\n }\n}\n","import {\n EczaneAPIOptions,\n PaginationOptions,\n NearbyOptions,\n ApiResponse,\n Pharmacy,\n City,\n District,\n AccountInfo,\n WhitelistUpdateResponse\n} from './types';\nimport {\n EczaneAPIError,\n AuthenticationError,\n ForbiddenError,\n NotFoundError,\n RateLimitError,\n InvalidRequestError,\n TimeoutError\n} from './errors';\n\nconst DEFAULT_BASE_URL = 'https://eczaneler.org/api/v2';\nconst DEFAULT_TIMEOUT = 10000;\n\n/**\n * Eczaneler.ORG v2 REST API İstemcisi\n */\nexport class EczaneAPI {\n private readonly apiKey: string;\n private readonly baseUrl: string;\n private readonly timeout: number;\n private readonly customHeaders: Record<string, string>;\n\n /**\n * Yeni bir EczaneAPI istemcisi örneği oluşturur\n * @param options Yapılandırma ayarları\n * \n * @example\n * ```typescript\n * import { EczaneAPI } from 'nobetci-eczane-api';\n * \n * const api = new EczaneAPI({\n * apiKey: 'SENIN_API_ANAHTARIN'\n * });\n * ```\n */\n constructor(options: EczaneAPIOptions | string) {\n if (typeof options === 'string') {\n this.apiKey = options;\n this.baseUrl = DEFAULT_BASE_URL;\n this.timeout = DEFAULT_TIMEOUT;\n this.customHeaders = {};\n } else {\n if (!options?.apiKey) {\n throw new AuthenticationError('API anahtarı (apiKey) zorunludur.');\n }\n this.apiKey = options.apiKey;\n this.baseUrl = (options.baseUrl || DEFAULT_BASE_URL).replace(/\\/+$/, '');\n this.timeout = options.timeout ?? DEFAULT_TIMEOUT;\n this.customHeaders = options.headers || {};\n }\n }\n\n /**\n * Türkiye genelinde o gün nöbetçi olan tüm eczaneleri listeler\n * \n * @param options Sayfalama ve limit ayarları (?page=1&limit=25)\n * @returns Sayfalanmış nöbetçi eczane listesi\n * \n * @example\n * ```typescript\n * const result = await api.getSentryPharmacies({ page: 1, limit: 50 });\n * console.log(`Toplam ${result.pagination?.total} nöbetçi eczane bulundu.`);\n * ```\n */\n public async getSentryPharmacies(options?: PaginationOptions): Promise<ApiResponse<Pharmacy[]>> {\n const query = this.buildPaginationQuery(options);\n return this.request<ApiResponse<Pharmacy[]>>(`/pharmacies/sentry-pharmacies${query}`, {\n method: 'GET',\n signal: options?.signal\n });\n }\n\n /**\n * Belirtilen ildeki nöbetçi eczaneleri listeler\n * \n * @param city İl adı / slug'ı (örn: \"istanbul\", \"ankara\") VEYA Plaka/Şehir ID (örn: 34, 6)\n * @param options Sayfalama ve limit ayarları\n * @returns İldeki nöbetçi eczane listesi\n * \n * @example\n * ```typescript\n * // Şehir ID (34 - İstanbul) ile nöbetçileri çekme\n * const result = await api.getSentryByCity(34, { limit: 50 });\n * \n * // Slug ile çekme\n * const izmir = await api.getSentryByCity('izmir');\n * ```\n */\n public async getSentryByCity(\n city: string | number,\n options?: PaginationOptions\n ): Promise<ApiResponse<Pharmacy[]>> {\n if (!city) {\n throw new InvalidRequestError('Şehir bilgisi (city slug veya ID) zorunludur.');\n }\n const query = this.buildPaginationQuery(options);\n return this.request<ApiResponse<Pharmacy[]>>(`/pharmacies/sentry-city-list/${encodeURIComponent(city)}${query}`, {\n method: 'GET',\n signal: options?.signal\n });\n }\n\n /**\n * Belirtilen ilçedeki nöbetçi eczaneleri listeler\n * \n * @param city İl slug veya ID (örn: \"istanbul\" veya 34)\n * @param district İlçe slug veya ID (örn: \"kadikoy\" veya 440)\n * @param options Sayfalama ve limit ayarları\n * @returns İlçedeki nöbetçi eczane listesi\n * \n * @example\n * ```typescript\n * const result = await api.getSentryByDistrict(34, 440);\n * // Veya slug ile:\n * const result2 = await api.getSentryByDistrict('istanbul', 'kadikoy');\n * ```\n */\n public async getSentryByDistrict(\n city: string | number,\n district: string | number,\n options?: PaginationOptions\n ): Promise<ApiResponse<Pharmacy[]>> {\n if (!city || !district) {\n throw new InvalidRequestError('İl ve ilçe parametreleri zorunludur.');\n }\n const query = this.buildPaginationQuery(options);\n return this.request<ApiResponse<Pharmacy[]>>(\n `/pharmacies/sentry-district-list/${encodeURIComponent(city)}/${encodeURIComponent(district)}${query}`,\n {\n method: 'GET',\n signal: options?.signal\n }\n );\n }\n\n /**\n * Coğrafi koordinatlara (enlem / boylam) göre en yakın eczaneleri mesafeye göre sıralı getirir\n * \n * @param options Enlem (lat), boylam (lon), isSentry ve limit ayarları\n * @returns En yakından uzağa sıralanmış eczane listesi\n * \n * @example\n * ```typescript\n * const result = await api.getNearby({\n * lat: 41.0082,\n * lon: 28.9784,\n * isSentry: true,\n * limit: 10\n * });\n * ```\n */\n public async getNearby(options: NearbyOptions): Promise<ApiResponse<Pharmacy[]>> {\n if (typeof options?.lat !== 'number' || typeof options?.lon !== 'number') {\n throw new InvalidRequestError('Enlem (lat) ve boylam (lon) sayısal değer olarak girilmelidir.');\n }\n\n const payload = {\n lat: options.lat,\n lon: options.lon,\n is_sentry: options.isSentry === false ? 0 : 1,\n limit: options.limit ? Math.min(Math.max(1, options.limit), 50) : 10,\n ...(options.radius ? { radius: options.radius } : {})\n };\n\n return this.request<ApiResponse<Pharmacy[]>>('/pharmacies/pharmacies-nearby', {\n method: 'POST',\n body: JSON.stringify(payload),\n headers: {\n 'Content-Type': 'application/json'\n },\n signal: options?.signal\n });\n }\n\n /**\n * Desteklenen tüm il listesini döner\n * \n * @example\n * ```typescript\n * const { data: cities } = await api.getCities();\n * ```\n */\n public async getCities(signal?: AbortSignal): Promise<ApiResponse<City[]>> {\n return this.request<ApiResponse<City[]>>('/pharmacies/cities', {\n method: 'GET',\n signal\n });\n }\n\n /**\n * Belirtilen ile ait ilçe listesini döner\n * \n * @param cityId İl ID (örn: 34 - İstanbul)\n * \n * @example\n * ```typescript\n * const { data: districts } = await api.getDistricts(34);\n * ```\n */\n public async getDistricts(cityId: number, signal?: AbortSignal): Promise<ApiResponse<District[]>> {\n if (!cityId) {\n throw new InvalidRequestError('Geçerli bir cityId belirtilmelidir.');\n }\n return this.request<ApiResponse<District[]>>(`/pharmacies/districts?city_id=${encodeURIComponent(cityId)}`, {\n method: 'GET',\n signal\n });\n }\n\n /**\n * API anahtarınıza ait kalan kullanım, kota ve yetki bilgilerini döner\n * \n * @example\n * ```typescript\n * const account = await api.getAccountInfo();\n * console.log(`Kalan süre: ${account.remaining_days} gün`);\n * ```\n */\n public async getAccountInfo(signal?: AbortSignal): Promise<AccountInfo> {\n return this.request<AccountInfo>('/pharmacies/account-info', {\n method: 'GET',\n signal\n });\n }\n\n /**\n * Dinamik IP Whitelist tanımını günceller\n * \n * @param ips İzin verilecek IP adresi veya maskesi (örn: \"5.132.*\" veya \"195.175.20.10\")\n * \n * @example\n * ```typescript\n * const res = await api.updateWhitelist('5.132.*');\n * ```\n */\n public async updateWhitelist(ips: string, signal?: AbortSignal): Promise<WhitelistUpdateResponse> {\n if (!ips || typeof ips !== 'string') {\n throw new InvalidRequestError('Geçerli bir IP adresi veya deseni (ips) girilmelidir.');\n }\n\n return this.request<WhitelistUpdateResponse>('/update-whitelist', {\n method: 'POST',\n body: JSON.stringify({ ips }),\n headers: {\n 'Content-Type': 'application/json'\n },\n signal\n });\n }\n\n /**\n * Türkiye'deki tüm eczaneleri (nöbetçi olmayanlar dahil +30.000) sayfalı olarak döner (Premium Servis)\n * \n * @param options Sayfalama ve limit ayarları\n * \n * @example\n * ```typescript\n * const result = await api.getAllPharmacies({ page: 1, limit: 50 });\n * ```\n */\n public async getAllPharmacies(options?: PaginationOptions): Promise<ApiResponse<Pharmacy[]>> {\n const query = this.buildPaginationQuery(options);\n return this.request<ApiResponse<Pharmacy[]>>(`/pharmacies/all-pharmacies${query}`, {\n method: 'GET',\n signal: options?.signal\n });\n }\n\n /**\n * Merkezi HTTP İstek Yürütücüsü (Native fetch)\n */\n private async request<T>(endpoint: string, init: RequestInit): Promise<T> {\n const url = `${this.baseUrl}${endpoint.startsWith('/') ? endpoint : `/${endpoint}`}`;\n\n const headers: Record<string, string> = {\n 'Accept': 'application/json',\n 'X-Api-Key': this.apiKey,\n ...this.customHeaders,\n ...(init.headers as Record<string, string> || {})\n };\n\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), this.timeout);\n\n // Dışarıdan iletilen signal varsa bağla\n if (init.signal) {\n init.signal.addEventListener('abort', () => controller.abort());\n }\n\n try {\n const response = await fetch(url, {\n ...init,\n headers,\n signal: controller.signal\n });\n\n clearTimeout(timeoutId);\n\n // Yanıtı ayrıştır\n let data: any;\n const contentType = response.headers.get('content-type') || '';\n if (contentType.includes('application/json')) {\n data = await response.json();\n } else {\n data = { message: await response.text() };\n }\n\n if (!response.ok) {\n this.handleHttpError(response.status, data);\n }\n\n return data as T;\n } catch (error: any) {\n clearTimeout(timeoutId);\n\n if (error instanceof EczaneAPIError) {\n throw error;\n }\n\n if (error.name === 'AbortError') {\n throw new TimeoutError(`İstek ${this.timeout}ms içinde yanıt vermedi (Zaman Aşımı).`);\n }\n\n throw new EczaneAPIError(\n error.message || 'API servisine bağlanırken beklenmedik bir hata oluştu.',\n 500,\n 'NETWORK_ERROR',\n error\n );\n }\n }\n\n /**\n * HTTP Hata Durumlarını Özelleştirilmiş Hata Sınıflarına Çevirir\n */\n private handleHttpError(status: number, body: any): never {\n const message = body?.message || body?.error || `HTTP ${status} Hatası`;\n const details = body?.details || body;\n\n switch (status) {\n case 400:\n throw new InvalidRequestError(message, details);\n case 401:\n throw new AuthenticationError(message);\n case 403:\n throw new ForbiddenError(message);\n case 404:\n throw new NotFoundError(message);\n case 429:\n throw new RateLimitError(message, body?.reset_in_seconds);\n default:\n throw new EczaneAPIError(message, status, 'API_ERROR', details);\n }\n }\n\n /**\n * Sayfalama query string oluşturucu\n */\n private buildPaginationQuery(options?: PaginationOptions): string {\n if (!options) return '';\n const params = new URLSearchParams();\n\n if (options.page && options.page > 1) {\n params.append('page', options.page.toString());\n }\n if (options.limit) {\n const limit = Math.min(Math.max(1, options.limit), 50);\n params.append('limit', limit.toString());\n }\n\n const qs = params.toString();\n return qs ? `?${qs}` : '';\n }\n}\n"]}
1
+ {"version":3,"sources":["../src/errors.ts","../src/client.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["/**\n * Nöbetçi Eczane API Özel Hata Sınıfları\n */\n\nexport class EczaneAPIError extends Error {\n public readonly status: number;\n public readonly code?: string;\n public readonly details?: unknown;\n\n constructor(message: string, status: number = 500, code?: string, details?: unknown) {\n super(message);\n this.name = 'EczaneAPIError';\n this.status = status;\n this.code = code;\n this.details = details;\n\n Object.setPrototypeOf(this, new.target.prototype);\n }\n}\n\nexport class AuthenticationError extends EczaneAPIError {\n constructor(message: string = 'Geçersiz veya eksik API anahtarı (X-Api-Key).') {\n super(message, 401, 'UNAUTHORIZED');\n this.name = 'AuthenticationError';\n }\n}\n\nexport class ForbiddenError extends EczaneAPIError {\n constructor(message: string = 'Erişim engellendi. IP adresiniz whitelist listesinde olmayabilir veya yetkisiz istek.') {\n super(message, 403, 'FORBIDDEN');\n this.name = 'ForbiddenError';\n }\n}\n\nexport class NotFoundError extends EczaneAPIError {\n constructor(message: string = 'İstenen kaynak veya eczane kaydı bulunamadı.') {\n super(message, 404, 'NOT_FOUND');\n this.name = 'NotFoundError';\n }\n}\n\nexport class RateLimitError extends EczaneAPIError {\n public readonly resetInSeconds?: number;\n\n constructor(message: string = 'API istek limiti aşıldı. Lütfen bir süre sonra tekrar deneyiniz.', resetInSeconds?: number) {\n super(message, 429, 'RATE_LIMIT_EXCEEDED');\n this.name = 'RateLimitError';\n this.resetInSeconds = resetInSeconds;\n }\n}\n\nexport class InvalidRequestError extends EczaneAPIError {\n constructor(message: string = 'Geçersiz istek parametreleri veya koordinat verisi.', details?: unknown) {\n super(message, 400, 'BAD_REQUEST', details);\n this.name = 'InvalidRequestError';\n }\n}\n\nexport class TimeoutError extends EczaneAPIError {\n constructor(message: string = 'İstek zaman aşımına uğradı.') {\n super(message, 408, 'REQUEST_TIMEOUT');\n this.name = 'TimeoutError';\n }\n}\n","import {\n EczaneAPIOptions,\n PaginationOptions,\n NearbyOptions,\n ApiResponse,\n Pharmacy,\n City,\n District,\n AccountInfo,\n WhitelistUpdateResponse\n} from './types';\nimport {\n EczaneAPIError,\n AuthenticationError,\n ForbiddenError,\n NotFoundError,\n RateLimitError,\n InvalidRequestError,\n TimeoutError\n} from './errors';\n\nconst DEFAULT_BASE_URL = 'https://api.eczaneler.org/api/v2';\nconst DEFAULT_TIMEOUT = 10000;\n\n/**\n * Eczaneler.ORG v2 REST API İstemcisi\n */\nexport class EczaneAPI {\n private readonly apiKey: string;\n private readonly baseUrl: string;\n private readonly timeout: number;\n private readonly customHeaders: Record<string, string>;\n\n /**\n * Yeni bir EczaneAPI istemcisi örneği oluşturur\n * @param options Yapılandırma ayarları\n * \n * @example\n * ```typescript\n * import { EczaneAPI } from 'nobetci-eczane-api';\n * \n * const api = new EczaneAPI({\n * apiKey: 'SENIN_API_ANAHTARIN'\n * });\n * ```\n */\n constructor(options: EczaneAPIOptions | string) {\n if (typeof options === 'string') {\n this.apiKey = options;\n this.baseUrl = DEFAULT_BASE_URL;\n this.timeout = DEFAULT_TIMEOUT;\n this.customHeaders = {};\n } else {\n if (!options?.apiKey) {\n throw new AuthenticationError('API anahtarı (apiKey) zorunludur.');\n }\n this.apiKey = options.apiKey;\n this.baseUrl = (options.baseUrl || DEFAULT_BASE_URL).replace(/\\/+$/, '');\n this.timeout = options.timeout ?? DEFAULT_TIMEOUT;\n this.customHeaders = options.headers || {};\n }\n }\n\n /**\n * Türkiye genelinde o gün nöbetçi olan tüm eczaneleri listeler\n * \n * @param options Sayfalama ve limit ayarları (?page=1&limit=25)\n * @returns Sayfalanmış nöbetçi eczane listesi\n * \n * @example\n * ```typescript\n * const result = await api.getSentryPharmacies({ page: 1, limit: 50 });\n * console.log(`Toplam ${result.pagination?.total} nöbetçi eczane bulundu.`);\n * ```\n */\n public async getSentryPharmacies(options?: PaginationOptions): Promise<ApiResponse<Pharmacy[]>> {\n const query = this.buildPaginationQuery(options);\n return this.request<ApiResponse<Pharmacy[]>>(`/pharmacies/sentry-pharmacies${query}`, {\n method: 'GET',\n signal: options?.signal\n });\n }\n\n /**\n * Belirtilen ildeki nöbetçi eczaneleri listeler\n * \n * @param city İl adı / slug'ı (örn: \"istanbul\", \"ankara\") VEYA Plaka/Şehir ID (örn: 34, 6)\n * @param options Sayfalama ve limit ayarları\n * @returns İldeki nöbetçi eczane listesi\n * \n * @example\n * ```typescript\n * // Şehir ID (34 - İstanbul) ile nöbetçileri çekme\n * const result = await api.getSentryByCity(34, { limit: 50 });\n * \n * // Slug ile çekme\n * const izmir = await api.getSentryByCity('izmir');\n * ```\n */\n public async getSentryByCity(\n city: string | number,\n options?: PaginationOptions\n ): Promise<ApiResponse<Pharmacy[]>> {\n if (!city) {\n throw new InvalidRequestError('Şehir bilgisi (city slug veya ID) zorunludur.');\n }\n const query = this.buildPaginationQuery(options);\n return this.request<ApiResponse<Pharmacy[]>>(`/pharmacies/sentry-city-list/${encodeURIComponent(city)}${query}`, {\n method: 'GET',\n signal: options?.signal\n });\n }\n\n /**\n * Belirtilen ilçedeki nöbetçi eczaneleri listeler\n * \n * @param city İl slug veya ID (örn: \"istanbul\" veya 34)\n * @param district İlçe slug veya ID (örn: \"kadikoy\" veya 440)\n * @param options Sayfalama ve limit ayarları\n * @returns İlçedeki nöbetçi eczane listesi\n * \n * @example\n * ```typescript\n * const result = await api.getSentryByDistrict(34, 440);\n * // Veya slug ile:\n * const result2 = await api.getSentryByDistrict('istanbul', 'kadikoy');\n * ```\n */\n public async getSentryByDistrict(\n city: string | number,\n district: string | number,\n options?: PaginationOptions\n ): Promise<ApiResponse<Pharmacy[]>> {\n if (!city || !district) {\n throw new InvalidRequestError('İl ve ilçe parametreleri zorunludur.');\n }\n const query = this.buildPaginationQuery(options);\n return this.request<ApiResponse<Pharmacy[]>>(\n `/pharmacies/sentry-district-list/${encodeURIComponent(city)}/${encodeURIComponent(district)}${query}`,\n {\n method: 'GET',\n signal: options?.signal\n }\n );\n }\n\n /**\n * Coğrafi koordinatlara (enlem / boylam) göre en yakın eczaneleri mesafeye göre sıralı getirir\n * \n * @param options Enlem (lat), boylam (lon), isSentry ve limit ayarları\n * @returns En yakından uzağa sıralanmış eczane listesi\n * \n * @example\n * ```typescript\n * const result = await api.getNearby({\n * lat: 41.0082,\n * lon: 28.9784,\n * isSentry: true,\n * limit: 10\n * });\n * ```\n */\n public async getNearby(options: NearbyOptions): Promise<ApiResponse<Pharmacy[]>> {\n if (typeof options?.lat !== 'number' || typeof options?.lon !== 'number') {\n throw new InvalidRequestError('Enlem (lat) ve boylam (lon) sayısal değer olarak girilmelidir.');\n }\n\n const payload = {\n lat: options.lat,\n lon: options.lon,\n is_sentry: options.isSentry === false ? 0 : 1,\n limit: options.limit ? Math.min(Math.max(1, options.limit), 50) : 10,\n ...(options.radius ? { radius: options.radius } : {})\n };\n\n return this.request<ApiResponse<Pharmacy[]>>('/pharmacies/pharmacies-nearby', {\n method: 'POST',\n body: JSON.stringify(payload),\n headers: {\n 'Content-Type': 'application/json'\n },\n signal: options?.signal\n });\n }\n\n /**\n * Desteklenen tüm il listesini döner\n * \n * @example\n * ```typescript\n * const { data: cities } = await api.getCities();\n * ```\n */\n public async getCities(signal?: AbortSignal): Promise<ApiResponse<City[]>> {\n return this.request<ApiResponse<City[]>>('/pharmacies/cities', {\n method: 'GET',\n signal\n });\n }\n\n /**\n * Belirtilen ile ait ilçe listesini döner\n * \n * @param cityId İl ID (örn: 34 - İstanbul)\n * \n * @example\n * ```typescript\n * const { data: districts } = await api.getDistricts(34);\n * ```\n */\n public async getDistricts(cityId: number, signal?: AbortSignal): Promise<ApiResponse<District[]>> {\n if (!cityId) {\n throw new InvalidRequestError('Geçerli bir cityId belirtilmelidir.');\n }\n return this.request<ApiResponse<District[]>>(`/pharmacies/districts?city_id=${encodeURIComponent(cityId)}`, {\n method: 'GET',\n signal\n });\n }\n\n /**\n * API anahtarınıza ait kalan kullanım, kota ve yetki bilgilerini döner\n * \n * @example\n * ```typescript\n * const account = await api.getAccountInfo();\n * console.log(`Kalan süre: ${account.remaining_days} gün`);\n * ```\n */\n public async getAccountInfo(signal?: AbortSignal): Promise<AccountInfo> {\n return this.request<AccountInfo>('/pharmacies/account-info', {\n method: 'GET',\n signal\n });\n }\n\n /**\n * Dinamik IP Whitelist tanımını günceller\n * \n * @param ips İzin verilecek IP adresi veya maskesi (örn: \"5.132.*\" veya \"195.175.20.10\")\n * \n * @example\n * ```typescript\n * const res = await api.updateWhitelist('5.132.*');\n * ```\n */\n public async updateWhitelist(ips: string, signal?: AbortSignal): Promise<WhitelistUpdateResponse> {\n if (!ips || typeof ips !== 'string') {\n throw new InvalidRequestError('Geçerli bir IP adresi veya deseni (ips) girilmelidir.');\n }\n\n return this.request<WhitelistUpdateResponse>('/update-whitelist', {\n method: 'POST',\n body: JSON.stringify({ ips }),\n headers: {\n 'Content-Type': 'application/json'\n },\n signal\n });\n }\n\n /**\n * Türkiye'deki tüm eczaneleri (nöbetçi olmayanlar dahil +30.000) sayfalı olarak döner (Premium Servis)\n * \n * @param options Sayfalama ve limit ayarları\n * \n * @example\n * ```typescript\n * const result = await api.getAllPharmacies({ page: 1, limit: 50 });\n * ```\n */\n public async getAllPharmacies(options?: PaginationOptions): Promise<ApiResponse<Pharmacy[]>> {\n const query = this.buildPaginationQuery(options);\n return this.request<ApiResponse<Pharmacy[]>>(`/pharmacies/all-pharmacies${query}`, {\n method: 'GET',\n signal: options?.signal\n });\n }\n\n /**\n * Merkezi HTTP İstek Yürütücüsü (Native fetch)\n */\n private async request<T>(endpoint: string, init: RequestInit): Promise<T> {\n const url = `${this.baseUrl}${endpoint.startsWith('/') ? endpoint : `/${endpoint}`}`;\n\n const headers: Record<string, string> = {\n 'Accept': 'application/json',\n 'X-Api-Key': this.apiKey,\n ...this.customHeaders,\n ...(init.headers as Record<string, string> || {})\n };\n\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), this.timeout);\n\n // Dışarıdan iletilen signal varsa bağla\n if (init.signal) {\n init.signal.addEventListener('abort', () => controller.abort());\n }\n\n try {\n const response = await fetch(url, {\n ...init,\n headers,\n signal: controller.signal\n });\n\n clearTimeout(timeoutId);\n\n // Yanıtı ayrıştır\n let data: any;\n const contentType = response.headers.get('content-type') || '';\n if (contentType.includes('application/json')) {\n data = await response.json();\n } else {\n data = { message: await response.text() };\n }\n\n if (!response.ok) {\n this.handleHttpError(response.status, data);\n }\n\n return data as T;\n } catch (error: any) {\n clearTimeout(timeoutId);\n\n if (error instanceof EczaneAPIError) {\n throw error;\n }\n\n if (error.name === 'AbortError') {\n throw new TimeoutError(`İstek ${this.timeout}ms içinde yanıt vermedi (Zaman Aşımı).`);\n }\n\n throw new EczaneAPIError(\n error.message || 'API servisine bağlanırken beklenmedik bir hata oluştu.',\n 500,\n 'NETWORK_ERROR',\n error\n );\n }\n }\n\n /**\n * HTTP Hata Durumlarını Özelleştirilmiş Hata Sınıflarına Çevirir\n */\n private handleHttpError(status: number, body: any): never {\n const message = body?.message || body?.error || `HTTP ${status} Hatası`;\n const details = body?.details || body;\n\n switch (status) {\n case 400:\n throw new InvalidRequestError(message, details);\n case 401:\n throw new AuthenticationError(message);\n case 403:\n throw new ForbiddenError(message);\n case 404:\n throw new NotFoundError(message);\n case 429:\n throw new RateLimitError(message, body?.reset_in_seconds);\n default:\n throw new EczaneAPIError(message, status, 'API_ERROR', details);\n }\n }\n\n /**\n * Sayfalama query string oluşturucu\n */\n private buildPaginationQuery(options?: PaginationOptions): string {\n if (!options) return '';\n const params = new URLSearchParams();\n\n if (options.page && options.page > 1) {\n params.append('page', options.page.toString());\n }\n if (options.limit) {\n const limit = Math.min(Math.max(1, options.limit), 50);\n params.append('limit', limit.toString());\n }\n\n const qs = params.toString();\n return qs ? `?${qs}` : '';\n }\n}\n"]}
package/dist/index.mjs CHANGED
@@ -52,7 +52,7 @@ var TimeoutError = class extends EczaneAPIError {
52
52
  };
53
53
 
54
54
  // src/client.ts
55
- var DEFAULT_BASE_URL = "https://eczaneler.org/api/v2";
55
+ var DEFAULT_BASE_URL = "https://api.eczaneler.org/api/v2";
56
56
  var DEFAULT_TIMEOUT = 1e4;
57
57
  var EczaneAPI = class {
58
58
  apiKey;
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/errors.ts","../src/client.ts"],"names":[],"mappings":"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","file":"index.mjs","sourcesContent":["/**\n * Nöbetçi Eczane API Özel Hata Sınıfları\n */\n\nexport class EczaneAPIError extends Error {\n public readonly status: number;\n public readonly code?: string;\n public readonly details?: unknown;\n\n constructor(message: string, status: number = 500, code?: string, details?: unknown) {\n super(message);\n this.name = 'EczaneAPIError';\n this.status = status;\n this.code = code;\n this.details = details;\n\n Object.setPrototypeOf(this, new.target.prototype);\n }\n}\n\nexport class AuthenticationError extends EczaneAPIError {\n constructor(message: string = 'Geçersiz veya eksik API anahtarı (X-Api-Key).') {\n super(message, 401, 'UNAUTHORIZED');\n this.name = 'AuthenticationError';\n }\n}\n\nexport class ForbiddenError extends EczaneAPIError {\n constructor(message: string = 'Erişim engellendi. IP adresiniz whitelist listesinde olmayabilir veya yetkisiz istek.') {\n super(message, 403, 'FORBIDDEN');\n this.name = 'ForbiddenError';\n }\n}\n\nexport class NotFoundError extends EczaneAPIError {\n constructor(message: string = 'İstenen kaynak veya eczane kaydı bulunamadı.') {\n super(message, 404, 'NOT_FOUND');\n this.name = 'NotFoundError';\n }\n}\n\nexport class RateLimitError extends EczaneAPIError {\n public readonly resetInSeconds?: number;\n\n constructor(message: string = 'API istek limiti aşıldı. Lütfen bir süre sonra tekrar deneyiniz.', resetInSeconds?: number) {\n super(message, 429, 'RATE_LIMIT_EXCEEDED');\n this.name = 'RateLimitError';\n this.resetInSeconds = resetInSeconds;\n }\n}\n\nexport class InvalidRequestError extends EczaneAPIError {\n constructor(message: string = 'Geçersiz istek parametreleri veya koordinat verisi.', details?: unknown) {\n super(message, 400, 'BAD_REQUEST', details);\n this.name = 'InvalidRequestError';\n }\n}\n\nexport class TimeoutError extends EczaneAPIError {\n constructor(message: string = 'İstek zaman aşımına uğradı.') {\n super(message, 408, 'REQUEST_TIMEOUT');\n this.name = 'TimeoutError';\n }\n}\n","import {\n EczaneAPIOptions,\n PaginationOptions,\n NearbyOptions,\n ApiResponse,\n Pharmacy,\n City,\n District,\n AccountInfo,\n WhitelistUpdateResponse\n} from './types';\nimport {\n EczaneAPIError,\n AuthenticationError,\n ForbiddenError,\n NotFoundError,\n RateLimitError,\n InvalidRequestError,\n TimeoutError\n} from './errors';\n\nconst DEFAULT_BASE_URL = 'https://eczaneler.org/api/v2';\nconst DEFAULT_TIMEOUT = 10000;\n\n/**\n * Eczaneler.ORG v2 REST API İstemcisi\n */\nexport class EczaneAPI {\n private readonly apiKey: string;\n private readonly baseUrl: string;\n private readonly timeout: number;\n private readonly customHeaders: Record<string, string>;\n\n /**\n * Yeni bir EczaneAPI istemcisi örneği oluşturur\n * @param options Yapılandırma ayarları\n * \n * @example\n * ```typescript\n * import { EczaneAPI } from 'nobetci-eczane-api';\n * \n * const api = new EczaneAPI({\n * apiKey: 'SENIN_API_ANAHTARIN'\n * });\n * ```\n */\n constructor(options: EczaneAPIOptions | string) {\n if (typeof options === 'string') {\n this.apiKey = options;\n this.baseUrl = DEFAULT_BASE_URL;\n this.timeout = DEFAULT_TIMEOUT;\n this.customHeaders = {};\n } else {\n if (!options?.apiKey) {\n throw new AuthenticationError('API anahtarı (apiKey) zorunludur.');\n }\n this.apiKey = options.apiKey;\n this.baseUrl = (options.baseUrl || DEFAULT_BASE_URL).replace(/\\/+$/, '');\n this.timeout = options.timeout ?? DEFAULT_TIMEOUT;\n this.customHeaders = options.headers || {};\n }\n }\n\n /**\n * Türkiye genelinde o gün nöbetçi olan tüm eczaneleri listeler\n * \n * @param options Sayfalama ve limit ayarları (?page=1&limit=25)\n * @returns Sayfalanmış nöbetçi eczane listesi\n * \n * @example\n * ```typescript\n * const result = await api.getSentryPharmacies({ page: 1, limit: 50 });\n * console.log(`Toplam ${result.pagination?.total} nöbetçi eczane bulundu.`);\n * ```\n */\n public async getSentryPharmacies(options?: PaginationOptions): Promise<ApiResponse<Pharmacy[]>> {\n const query = this.buildPaginationQuery(options);\n return this.request<ApiResponse<Pharmacy[]>>(`/pharmacies/sentry-pharmacies${query}`, {\n method: 'GET',\n signal: options?.signal\n });\n }\n\n /**\n * Belirtilen ildeki nöbetçi eczaneleri listeler\n * \n * @param city İl adı / slug'ı (örn: \"istanbul\", \"ankara\") VEYA Plaka/Şehir ID (örn: 34, 6)\n * @param options Sayfalama ve limit ayarları\n * @returns İldeki nöbetçi eczane listesi\n * \n * @example\n * ```typescript\n * // Şehir ID (34 - İstanbul) ile nöbetçileri çekme\n * const result = await api.getSentryByCity(34, { limit: 50 });\n * \n * // Slug ile çekme\n * const izmir = await api.getSentryByCity('izmir');\n * ```\n */\n public async getSentryByCity(\n city: string | number,\n options?: PaginationOptions\n ): Promise<ApiResponse<Pharmacy[]>> {\n if (!city) {\n throw new InvalidRequestError('Şehir bilgisi (city slug veya ID) zorunludur.');\n }\n const query = this.buildPaginationQuery(options);\n return this.request<ApiResponse<Pharmacy[]>>(`/pharmacies/sentry-city-list/${encodeURIComponent(city)}${query}`, {\n method: 'GET',\n signal: options?.signal\n });\n }\n\n /**\n * Belirtilen ilçedeki nöbetçi eczaneleri listeler\n * \n * @param city İl slug veya ID (örn: \"istanbul\" veya 34)\n * @param district İlçe slug veya ID (örn: \"kadikoy\" veya 440)\n * @param options Sayfalama ve limit ayarları\n * @returns İlçedeki nöbetçi eczane listesi\n * \n * @example\n * ```typescript\n * const result = await api.getSentryByDistrict(34, 440);\n * // Veya slug ile:\n * const result2 = await api.getSentryByDistrict('istanbul', 'kadikoy');\n * ```\n */\n public async getSentryByDistrict(\n city: string | number,\n district: string | number,\n options?: PaginationOptions\n ): Promise<ApiResponse<Pharmacy[]>> {\n if (!city || !district) {\n throw new InvalidRequestError('İl ve ilçe parametreleri zorunludur.');\n }\n const query = this.buildPaginationQuery(options);\n return this.request<ApiResponse<Pharmacy[]>>(\n `/pharmacies/sentry-district-list/${encodeURIComponent(city)}/${encodeURIComponent(district)}${query}`,\n {\n method: 'GET',\n signal: options?.signal\n }\n );\n }\n\n /**\n * Coğrafi koordinatlara (enlem / boylam) göre en yakın eczaneleri mesafeye göre sıralı getirir\n * \n * @param options Enlem (lat), boylam (lon), isSentry ve limit ayarları\n * @returns En yakından uzağa sıralanmış eczane listesi\n * \n * @example\n * ```typescript\n * const result = await api.getNearby({\n * lat: 41.0082,\n * lon: 28.9784,\n * isSentry: true,\n * limit: 10\n * });\n * ```\n */\n public async getNearby(options: NearbyOptions): Promise<ApiResponse<Pharmacy[]>> {\n if (typeof options?.lat !== 'number' || typeof options?.lon !== 'number') {\n throw new InvalidRequestError('Enlem (lat) ve boylam (lon) sayısal değer olarak girilmelidir.');\n }\n\n const payload = {\n lat: options.lat,\n lon: options.lon,\n is_sentry: options.isSentry === false ? 0 : 1,\n limit: options.limit ? Math.min(Math.max(1, options.limit), 50) : 10,\n ...(options.radius ? { radius: options.radius } : {})\n };\n\n return this.request<ApiResponse<Pharmacy[]>>('/pharmacies/pharmacies-nearby', {\n method: 'POST',\n body: JSON.stringify(payload),\n headers: {\n 'Content-Type': 'application/json'\n },\n signal: options?.signal\n });\n }\n\n /**\n * Desteklenen tüm il listesini döner\n * \n * @example\n * ```typescript\n * const { data: cities } = await api.getCities();\n * ```\n */\n public async getCities(signal?: AbortSignal): Promise<ApiResponse<City[]>> {\n return this.request<ApiResponse<City[]>>('/pharmacies/cities', {\n method: 'GET',\n signal\n });\n }\n\n /**\n * Belirtilen ile ait ilçe listesini döner\n * \n * @param cityId İl ID (örn: 34 - İstanbul)\n * \n * @example\n * ```typescript\n * const { data: districts } = await api.getDistricts(34);\n * ```\n */\n public async getDistricts(cityId: number, signal?: AbortSignal): Promise<ApiResponse<District[]>> {\n if (!cityId) {\n throw new InvalidRequestError('Geçerli bir cityId belirtilmelidir.');\n }\n return this.request<ApiResponse<District[]>>(`/pharmacies/districts?city_id=${encodeURIComponent(cityId)}`, {\n method: 'GET',\n signal\n });\n }\n\n /**\n * API anahtarınıza ait kalan kullanım, kota ve yetki bilgilerini döner\n * \n * @example\n * ```typescript\n * const account = await api.getAccountInfo();\n * console.log(`Kalan süre: ${account.remaining_days} gün`);\n * ```\n */\n public async getAccountInfo(signal?: AbortSignal): Promise<AccountInfo> {\n return this.request<AccountInfo>('/pharmacies/account-info', {\n method: 'GET',\n signal\n });\n }\n\n /**\n * Dinamik IP Whitelist tanımını günceller\n * \n * @param ips İzin verilecek IP adresi veya maskesi (örn: \"5.132.*\" veya \"195.175.20.10\")\n * \n * @example\n * ```typescript\n * const res = await api.updateWhitelist('5.132.*');\n * ```\n */\n public async updateWhitelist(ips: string, signal?: AbortSignal): Promise<WhitelistUpdateResponse> {\n if (!ips || typeof ips !== 'string') {\n throw new InvalidRequestError('Geçerli bir IP adresi veya deseni (ips) girilmelidir.');\n }\n\n return this.request<WhitelistUpdateResponse>('/update-whitelist', {\n method: 'POST',\n body: JSON.stringify({ ips }),\n headers: {\n 'Content-Type': 'application/json'\n },\n signal\n });\n }\n\n /**\n * Türkiye'deki tüm eczaneleri (nöbetçi olmayanlar dahil +30.000) sayfalı olarak döner (Premium Servis)\n * \n * @param options Sayfalama ve limit ayarları\n * \n * @example\n * ```typescript\n * const result = await api.getAllPharmacies({ page: 1, limit: 50 });\n * ```\n */\n public async getAllPharmacies(options?: PaginationOptions): Promise<ApiResponse<Pharmacy[]>> {\n const query = this.buildPaginationQuery(options);\n return this.request<ApiResponse<Pharmacy[]>>(`/pharmacies/all-pharmacies${query}`, {\n method: 'GET',\n signal: options?.signal\n });\n }\n\n /**\n * Merkezi HTTP İstek Yürütücüsü (Native fetch)\n */\n private async request<T>(endpoint: string, init: RequestInit): Promise<T> {\n const url = `${this.baseUrl}${endpoint.startsWith('/') ? endpoint : `/${endpoint}`}`;\n\n const headers: Record<string, string> = {\n 'Accept': 'application/json',\n 'X-Api-Key': this.apiKey,\n ...this.customHeaders,\n ...(init.headers as Record<string, string> || {})\n };\n\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), this.timeout);\n\n // Dışarıdan iletilen signal varsa bağla\n if (init.signal) {\n init.signal.addEventListener('abort', () => controller.abort());\n }\n\n try {\n const response = await fetch(url, {\n ...init,\n headers,\n signal: controller.signal\n });\n\n clearTimeout(timeoutId);\n\n // Yanıtı ayrıştır\n let data: any;\n const contentType = response.headers.get('content-type') || '';\n if (contentType.includes('application/json')) {\n data = await response.json();\n } else {\n data = { message: await response.text() };\n }\n\n if (!response.ok) {\n this.handleHttpError(response.status, data);\n }\n\n return data as T;\n } catch (error: any) {\n clearTimeout(timeoutId);\n\n if (error instanceof EczaneAPIError) {\n throw error;\n }\n\n if (error.name === 'AbortError') {\n throw new TimeoutError(`İstek ${this.timeout}ms içinde yanıt vermedi (Zaman Aşımı).`);\n }\n\n throw new EczaneAPIError(\n error.message || 'API servisine bağlanırken beklenmedik bir hata oluştu.',\n 500,\n 'NETWORK_ERROR',\n error\n );\n }\n }\n\n /**\n * HTTP Hata Durumlarını Özelleştirilmiş Hata Sınıflarına Çevirir\n */\n private handleHttpError(status: number, body: any): never {\n const message = body?.message || body?.error || `HTTP ${status} Hatası`;\n const details = body?.details || body;\n\n switch (status) {\n case 400:\n throw new InvalidRequestError(message, details);\n case 401:\n throw new AuthenticationError(message);\n case 403:\n throw new ForbiddenError(message);\n case 404:\n throw new NotFoundError(message);\n case 429:\n throw new RateLimitError(message, body?.reset_in_seconds);\n default:\n throw new EczaneAPIError(message, status, 'API_ERROR', details);\n }\n }\n\n /**\n * Sayfalama query string oluşturucu\n */\n private buildPaginationQuery(options?: PaginationOptions): string {\n if (!options) return '';\n const params = new URLSearchParams();\n\n if (options.page && options.page > 1) {\n params.append('page', options.page.toString());\n }\n if (options.limit) {\n const limit = Math.min(Math.max(1, options.limit), 50);\n params.append('limit', limit.toString());\n }\n\n const qs = params.toString();\n return qs ? `?${qs}` : '';\n }\n}\n"]}
1
+ {"version":3,"sources":["../src/errors.ts","../src/client.ts"],"names":[],"mappings":"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","file":"index.mjs","sourcesContent":["/**\n * Nöbetçi Eczane API Özel Hata Sınıfları\n */\n\nexport class EczaneAPIError extends Error {\n public readonly status: number;\n public readonly code?: string;\n public readonly details?: unknown;\n\n constructor(message: string, status: number = 500, code?: string, details?: unknown) {\n super(message);\n this.name = 'EczaneAPIError';\n this.status = status;\n this.code = code;\n this.details = details;\n\n Object.setPrototypeOf(this, new.target.prototype);\n }\n}\n\nexport class AuthenticationError extends EczaneAPIError {\n constructor(message: string = 'Geçersiz veya eksik API anahtarı (X-Api-Key).') {\n super(message, 401, 'UNAUTHORIZED');\n this.name = 'AuthenticationError';\n }\n}\n\nexport class ForbiddenError extends EczaneAPIError {\n constructor(message: string = 'Erişim engellendi. IP adresiniz whitelist listesinde olmayabilir veya yetkisiz istek.') {\n super(message, 403, 'FORBIDDEN');\n this.name = 'ForbiddenError';\n }\n}\n\nexport class NotFoundError extends EczaneAPIError {\n constructor(message: string = 'İstenen kaynak veya eczane kaydı bulunamadı.') {\n super(message, 404, 'NOT_FOUND');\n this.name = 'NotFoundError';\n }\n}\n\nexport class RateLimitError extends EczaneAPIError {\n public readonly resetInSeconds?: number;\n\n constructor(message: string = 'API istek limiti aşıldı. Lütfen bir süre sonra tekrar deneyiniz.', resetInSeconds?: number) {\n super(message, 429, 'RATE_LIMIT_EXCEEDED');\n this.name = 'RateLimitError';\n this.resetInSeconds = resetInSeconds;\n }\n}\n\nexport class InvalidRequestError extends EczaneAPIError {\n constructor(message: string = 'Geçersiz istek parametreleri veya koordinat verisi.', details?: unknown) {\n super(message, 400, 'BAD_REQUEST', details);\n this.name = 'InvalidRequestError';\n }\n}\n\nexport class TimeoutError extends EczaneAPIError {\n constructor(message: string = 'İstek zaman aşımına uğradı.') {\n super(message, 408, 'REQUEST_TIMEOUT');\n this.name = 'TimeoutError';\n }\n}\n","import {\n EczaneAPIOptions,\n PaginationOptions,\n NearbyOptions,\n ApiResponse,\n Pharmacy,\n City,\n District,\n AccountInfo,\n WhitelistUpdateResponse\n} from './types';\nimport {\n EczaneAPIError,\n AuthenticationError,\n ForbiddenError,\n NotFoundError,\n RateLimitError,\n InvalidRequestError,\n TimeoutError\n} from './errors';\n\nconst DEFAULT_BASE_URL = 'https://api.eczaneler.org/api/v2';\nconst DEFAULT_TIMEOUT = 10000;\n\n/**\n * Eczaneler.ORG v2 REST API İstemcisi\n */\nexport class EczaneAPI {\n private readonly apiKey: string;\n private readonly baseUrl: string;\n private readonly timeout: number;\n private readonly customHeaders: Record<string, string>;\n\n /**\n * Yeni bir EczaneAPI istemcisi örneği oluşturur\n * @param options Yapılandırma ayarları\n * \n * @example\n * ```typescript\n * import { EczaneAPI } from 'nobetci-eczane-api';\n * \n * const api = new EczaneAPI({\n * apiKey: 'SENIN_API_ANAHTARIN'\n * });\n * ```\n */\n constructor(options: EczaneAPIOptions | string) {\n if (typeof options === 'string') {\n this.apiKey = options;\n this.baseUrl = DEFAULT_BASE_URL;\n this.timeout = DEFAULT_TIMEOUT;\n this.customHeaders = {};\n } else {\n if (!options?.apiKey) {\n throw new AuthenticationError('API anahtarı (apiKey) zorunludur.');\n }\n this.apiKey = options.apiKey;\n this.baseUrl = (options.baseUrl || DEFAULT_BASE_URL).replace(/\\/+$/, '');\n this.timeout = options.timeout ?? DEFAULT_TIMEOUT;\n this.customHeaders = options.headers || {};\n }\n }\n\n /**\n * Türkiye genelinde o gün nöbetçi olan tüm eczaneleri listeler\n * \n * @param options Sayfalama ve limit ayarları (?page=1&limit=25)\n * @returns Sayfalanmış nöbetçi eczane listesi\n * \n * @example\n * ```typescript\n * const result = await api.getSentryPharmacies({ page: 1, limit: 50 });\n * console.log(`Toplam ${result.pagination?.total} nöbetçi eczane bulundu.`);\n * ```\n */\n public async getSentryPharmacies(options?: PaginationOptions): Promise<ApiResponse<Pharmacy[]>> {\n const query = this.buildPaginationQuery(options);\n return this.request<ApiResponse<Pharmacy[]>>(`/pharmacies/sentry-pharmacies${query}`, {\n method: 'GET',\n signal: options?.signal\n });\n }\n\n /**\n * Belirtilen ildeki nöbetçi eczaneleri listeler\n * \n * @param city İl adı / slug'ı (örn: \"istanbul\", \"ankara\") VEYA Plaka/Şehir ID (örn: 34, 6)\n * @param options Sayfalama ve limit ayarları\n * @returns İldeki nöbetçi eczane listesi\n * \n * @example\n * ```typescript\n * // Şehir ID (34 - İstanbul) ile nöbetçileri çekme\n * const result = await api.getSentryByCity(34, { limit: 50 });\n * \n * // Slug ile çekme\n * const izmir = await api.getSentryByCity('izmir');\n * ```\n */\n public async getSentryByCity(\n city: string | number,\n options?: PaginationOptions\n ): Promise<ApiResponse<Pharmacy[]>> {\n if (!city) {\n throw new InvalidRequestError('Şehir bilgisi (city slug veya ID) zorunludur.');\n }\n const query = this.buildPaginationQuery(options);\n return this.request<ApiResponse<Pharmacy[]>>(`/pharmacies/sentry-city-list/${encodeURIComponent(city)}${query}`, {\n method: 'GET',\n signal: options?.signal\n });\n }\n\n /**\n * Belirtilen ilçedeki nöbetçi eczaneleri listeler\n * \n * @param city İl slug veya ID (örn: \"istanbul\" veya 34)\n * @param district İlçe slug veya ID (örn: \"kadikoy\" veya 440)\n * @param options Sayfalama ve limit ayarları\n * @returns İlçedeki nöbetçi eczane listesi\n * \n * @example\n * ```typescript\n * const result = await api.getSentryByDistrict(34, 440);\n * // Veya slug ile:\n * const result2 = await api.getSentryByDistrict('istanbul', 'kadikoy');\n * ```\n */\n public async getSentryByDistrict(\n city: string | number,\n district: string | number,\n options?: PaginationOptions\n ): Promise<ApiResponse<Pharmacy[]>> {\n if (!city || !district) {\n throw new InvalidRequestError('İl ve ilçe parametreleri zorunludur.');\n }\n const query = this.buildPaginationQuery(options);\n return this.request<ApiResponse<Pharmacy[]>>(\n `/pharmacies/sentry-district-list/${encodeURIComponent(city)}/${encodeURIComponent(district)}${query}`,\n {\n method: 'GET',\n signal: options?.signal\n }\n );\n }\n\n /**\n * Coğrafi koordinatlara (enlem / boylam) göre en yakın eczaneleri mesafeye göre sıralı getirir\n * \n * @param options Enlem (lat), boylam (lon), isSentry ve limit ayarları\n * @returns En yakından uzağa sıralanmış eczane listesi\n * \n * @example\n * ```typescript\n * const result = await api.getNearby({\n * lat: 41.0082,\n * lon: 28.9784,\n * isSentry: true,\n * limit: 10\n * });\n * ```\n */\n public async getNearby(options: NearbyOptions): Promise<ApiResponse<Pharmacy[]>> {\n if (typeof options?.lat !== 'number' || typeof options?.lon !== 'number') {\n throw new InvalidRequestError('Enlem (lat) ve boylam (lon) sayısal değer olarak girilmelidir.');\n }\n\n const payload = {\n lat: options.lat,\n lon: options.lon,\n is_sentry: options.isSentry === false ? 0 : 1,\n limit: options.limit ? Math.min(Math.max(1, options.limit), 50) : 10,\n ...(options.radius ? { radius: options.radius } : {})\n };\n\n return this.request<ApiResponse<Pharmacy[]>>('/pharmacies/pharmacies-nearby', {\n method: 'POST',\n body: JSON.stringify(payload),\n headers: {\n 'Content-Type': 'application/json'\n },\n signal: options?.signal\n });\n }\n\n /**\n * Desteklenen tüm il listesini döner\n * \n * @example\n * ```typescript\n * const { data: cities } = await api.getCities();\n * ```\n */\n public async getCities(signal?: AbortSignal): Promise<ApiResponse<City[]>> {\n return this.request<ApiResponse<City[]>>('/pharmacies/cities', {\n method: 'GET',\n signal\n });\n }\n\n /**\n * Belirtilen ile ait ilçe listesini döner\n * \n * @param cityId İl ID (örn: 34 - İstanbul)\n * \n * @example\n * ```typescript\n * const { data: districts } = await api.getDistricts(34);\n * ```\n */\n public async getDistricts(cityId: number, signal?: AbortSignal): Promise<ApiResponse<District[]>> {\n if (!cityId) {\n throw new InvalidRequestError('Geçerli bir cityId belirtilmelidir.');\n }\n return this.request<ApiResponse<District[]>>(`/pharmacies/districts?city_id=${encodeURIComponent(cityId)}`, {\n method: 'GET',\n signal\n });\n }\n\n /**\n * API anahtarınıza ait kalan kullanım, kota ve yetki bilgilerini döner\n * \n * @example\n * ```typescript\n * const account = await api.getAccountInfo();\n * console.log(`Kalan süre: ${account.remaining_days} gün`);\n * ```\n */\n public async getAccountInfo(signal?: AbortSignal): Promise<AccountInfo> {\n return this.request<AccountInfo>('/pharmacies/account-info', {\n method: 'GET',\n signal\n });\n }\n\n /**\n * Dinamik IP Whitelist tanımını günceller\n * \n * @param ips İzin verilecek IP adresi veya maskesi (örn: \"5.132.*\" veya \"195.175.20.10\")\n * \n * @example\n * ```typescript\n * const res = await api.updateWhitelist('5.132.*');\n * ```\n */\n public async updateWhitelist(ips: string, signal?: AbortSignal): Promise<WhitelistUpdateResponse> {\n if (!ips || typeof ips !== 'string') {\n throw new InvalidRequestError('Geçerli bir IP adresi veya deseni (ips) girilmelidir.');\n }\n\n return this.request<WhitelistUpdateResponse>('/update-whitelist', {\n method: 'POST',\n body: JSON.stringify({ ips }),\n headers: {\n 'Content-Type': 'application/json'\n },\n signal\n });\n }\n\n /**\n * Türkiye'deki tüm eczaneleri (nöbetçi olmayanlar dahil +30.000) sayfalı olarak döner (Premium Servis)\n * \n * @param options Sayfalama ve limit ayarları\n * \n * @example\n * ```typescript\n * const result = await api.getAllPharmacies({ page: 1, limit: 50 });\n * ```\n */\n public async getAllPharmacies(options?: PaginationOptions): Promise<ApiResponse<Pharmacy[]>> {\n const query = this.buildPaginationQuery(options);\n return this.request<ApiResponse<Pharmacy[]>>(`/pharmacies/all-pharmacies${query}`, {\n method: 'GET',\n signal: options?.signal\n });\n }\n\n /**\n * Merkezi HTTP İstek Yürütücüsü (Native fetch)\n */\n private async request<T>(endpoint: string, init: RequestInit): Promise<T> {\n const url = `${this.baseUrl}${endpoint.startsWith('/') ? endpoint : `/${endpoint}`}`;\n\n const headers: Record<string, string> = {\n 'Accept': 'application/json',\n 'X-Api-Key': this.apiKey,\n ...this.customHeaders,\n ...(init.headers as Record<string, string> || {})\n };\n\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), this.timeout);\n\n // Dışarıdan iletilen signal varsa bağla\n if (init.signal) {\n init.signal.addEventListener('abort', () => controller.abort());\n }\n\n try {\n const response = await fetch(url, {\n ...init,\n headers,\n signal: controller.signal\n });\n\n clearTimeout(timeoutId);\n\n // Yanıtı ayrıştır\n let data: any;\n const contentType = response.headers.get('content-type') || '';\n if (contentType.includes('application/json')) {\n data = await response.json();\n } else {\n data = { message: await response.text() };\n }\n\n if (!response.ok) {\n this.handleHttpError(response.status, data);\n }\n\n return data as T;\n } catch (error: any) {\n clearTimeout(timeoutId);\n\n if (error instanceof EczaneAPIError) {\n throw error;\n }\n\n if (error.name === 'AbortError') {\n throw new TimeoutError(`İstek ${this.timeout}ms içinde yanıt vermedi (Zaman Aşımı).`);\n }\n\n throw new EczaneAPIError(\n error.message || 'API servisine bağlanırken beklenmedik bir hata oluştu.',\n 500,\n 'NETWORK_ERROR',\n error\n );\n }\n }\n\n /**\n * HTTP Hata Durumlarını Özelleştirilmiş Hata Sınıflarına Çevirir\n */\n private handleHttpError(status: number, body: any): never {\n const message = body?.message || body?.error || `HTTP ${status} Hatası`;\n const details = body?.details || body;\n\n switch (status) {\n case 400:\n throw new InvalidRequestError(message, details);\n case 401:\n throw new AuthenticationError(message);\n case 403:\n throw new ForbiddenError(message);\n case 404:\n throw new NotFoundError(message);\n case 429:\n throw new RateLimitError(message, body?.reset_in_seconds);\n default:\n throw new EczaneAPIError(message, status, 'API_ERROR', details);\n }\n }\n\n /**\n * Sayfalama query string oluşturucu\n */\n private buildPaginationQuery(options?: PaginationOptions): string {\n if (!options) return '';\n const params = new URLSearchParams();\n\n if (options.page && options.page > 1) {\n params.append('page', options.page.toString());\n }\n if (options.limit) {\n const limit = Math.min(Math.max(1, options.limit), 50);\n params.append('limit', limit.toString());\n }\n\n const qs = params.toString();\n return qs ? `?${qs}` : '';\n }\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nobetci-eczane-api",
3
- "version": "1.0.0",
3
+ "version": "1.0.2",
4
4
  "description": "Türkiye ve KKTC güncel nöbetçi eczane verilerine REST API üzerinden erişim sağlayan resmi TypeScript & JavaScript SDK.",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.mjs",
@@ -40,7 +40,7 @@
40
40
  "kktc-nobetci-eczaneler",
41
41
  "eczane"
42
42
  ],
43
- "author": "Mehmet Erdoğan <contact@eczaneler.org>",
43
+ "author": "Mehmet Erdoğan <mehmeterdogan080@gmail.com>",
44
44
  "homepage": "https://eczaneler.org/nobetci-eczane-api",
45
45
  "repository": {
46
46
  "type": "git",