مكتبة Node.js (Node SDK)
مكتبة Node.js (Node SDK)
حزمة @navvo/sdk الرسمية هي عميل من جهة الخادم بلغة TypeScript/JavaScript
لخدمة Navvo على الويب. وهي مكتوبة بأنواع محدّدة، وتعيد المحاولة تلقائيًا، وبلا
تبعيات وقت التشغيل — تستخدم دالة fetch المدمجة (Node 18+). تأتي ببناء مزدوج
ESM + CJS مع أنواع .d.ts كاملة. لا تحتوي على واجهة خرائط ولا عرض بلاطات
— لعرض خريطة في المتصفح استخدم خرائط Navvo.
يتطلّب: Node 18+ · عنوان الأساس: https://navvo.io/api/v1
التثبيت
npm install @navvo/sdk
# أو: pnpm add @navvo/sdk / yarn add @navvo/sdk
المصادقة
تُرسَل كل طلبات الاستدعاء عبر ترويسة x-api-key. يُقرأ المفتاح من متغيّر البيئة
NAVVO_API_KEY افتراضيًا، أو مرّره صراحةً:
import { NavvoClient } from "@navvo/sdk";
const navvo = NavvoClient.fromEnv(); // يستخدم $NAVVO_API_KEY
const navvo2 = new NavvoClient({ apiKey: "nvvo_your_key_here" });
لا تضع المكتبة المفتاح في الرابط أبدًا — باستثناء styleUrl() التي تبني
رابط نمط خريطة يُجلب من المتصفح، حيث يجب تمرير المفتاح كـ ?api_key= (لا يمكن
للمتصفحات إضافة ترويسات على طلبات النمط/البلاطات).
بداية سريعة
import { NavvoClient } from "@navvo/sdk";
const navvo = new NavvoClient();
// ترميز جغرافي أمامي — تُحوَّل الإحداثيات النصية إلى أرقام تلقائيًا
const hits = await navvo.geocode("مستشفى العبدلي، عمّان", { limit: 5 });
console.log(hits[0].lat, hits[0].lng, hits[0].displayName);
// خطّط مسارًا — تمرّر { lat, lng } والمكتبة تُسلسل lon/lat على الشبكة
const plan = await navvo.route({
locations: [
{ lat: 31.95, lng: 35.91, name: "A" },
{ lat: 31.99, lng: 35.95, name: "B" },
],
costing: "auto",
});
const trip = plan.engine?.data?.trip;
console.log("الوقت المتوقّع بالثواني:", trip?.summary?.time);
// فُكّ خطّ المرحلة (polyline6) إلى نقاط
const line = NavvoClient.decodePolyline(trip?.legs?.[0]?.shape ?? "");
// بيانات حيّة وفق الظروف
const wx = await navvo.weatherPoint(31.95, 35.91);
const inc = await navvo.incidents({ bbox: { west: 35.85, south: 31.9, east: 35.99, north: 31.99 }, limit: 10 });
الإحداثيات — لن تنقلب أبدًا
تمرّر النقاط دائمًا كـ { lat, lng } (وهو LatLng). تتولّى المكتبة كل اختلافات
صيغة الشبكة: { lon, lat } لـ route()/trafficRoute()، و{ lat, lon }
لحمولات تمرير المسارات، ومعاملات lat/lon منفصلة للترميز العكسي،
وwest,south,east,north لـ BBox، و[lng, lat] لـ GeoJSON، وصيغة WKT
POINT(lng lat) لمركز المكان (فُكّها عبر parseWktPoint(place.center) أو
NavvoClient.routeTargetFor(place)).
إعادة المحاولة والأخطاء
تُعاد المحاولة على الأعطال العابرة (5xx، 408، 429/الحصّة، انقطاعات الشبكة)
بتراجع أُسّي مع تشويش كامل، مع احترام Retry-After؛ ولا يُعاد على أخطاء العميل
(400/401/403/404). كل الأخطاء ترث من NavvoError:
import {
NavvoRateLimitError,
NavvoForbiddenError,
NavvoServiceUnavailableError,
} from "@navvo/sdk";
try {
const r = await navvo.geocode("مستشفى العبدلي، عمّان");
} catch (e) {
if (e instanceof NavvoRateLimitError) {
console.warn("تجاوز الحدّ، أعد المحاولة بعد", e.retryAfter, "ثانية");
} else if (e instanceof NavvoForbiddenError) {
console.error("مشكلة نطاق/حصّة:", e.reason ?? e.message);
} else if (e instanceof NavvoServiceUnavailableError) {
console.error("محرّك الترميز معطّل مؤقتًا — استخدم بديلًا");
} else {
throw e;
}
}
يُفكّ غلاف الترميز/المسارات ({ provider, available, data }) من أجلك تلقائيًا —
ويصير الجسم available:false خطأً من نوع NavvoServiceUnavailableError —
ويُعيد slug مكان غير معروف القيمة null (قيمة فارغة ناعمة، وليست خطأً).
ألغِ أي استدعاء عبر AbortSignal:
const ac = new AbortController();
const p = navvo.list({ category: "cafe" }, { signal: ac.signal });
setTimeout(() => ac.abort(), 1000);
البحث
تُعيد search() استجابة /search بأنواع محدّدة، بما فيها queryId الذي تشير إليه أحداث النقر اللاحقة:
const res = await navvo.search("صيدلية", {
near: { lat: 31.95, lng: 35.91 }, // رتّب الأماكن الأقرب أولًا
originType: "device", // "map" عندما تكون near مركز الخريطة (انحياز أضعف للمسافة)
radiusKm: 3, sort: "distance", // كلاهما يحتاج near
openNow: true, minRating: 4,
amenities: ["wheelchair-accessible-entrance"],
facets: ["category", "amenities"], // res.facets.category و res.facets.amenities
highlight: true, // items[].highlight.nameEn / nameAr
});
res.queryId; // لاستخدامه مع sendSearchEvent()
res.places?.items; // قد تحمل imageUrl و distanceKm و highlight و promoted
res.didYouMean; res.suggestions; // عند انعدام النتائج فقط: تصحيح إملائي وأماكن شائعة
await navvo.search("rumi caf", { mode: "typeahead" }); // أثناء الكتابة
await navvo.search("مكان هادئ للعمل مع قهوة جيدة", { semantic: "on" }); // المطابقة حسب المعنى
await navvo.search("صيدلية", { analytics: false }); // أبقِ هذا الاستدعاء خارج التحليلات
await navvo.suggestions("صيد", { limit: 6 }); // GET /search/suggestions
await navvo.similar({ slug: "jordan-museum-994700", limit: 6 }); // GET /search/similar ← { items, source }
مع مفتاح API لا تعمل المطابقة حسب المعنى إلا مع semantic: "on"، ولا تعمل أبدًا مع mode: "typeahead"، وتكون قيمة res.index.mode هي "hybrid" عندما تُسهم فيها. وابتداءً من الإصدار 0.2.1 تُرسل الحزمة الترويسة X-Navvo-Source: sdk مع كل طلبات البحث والاقتراحات والأماكن المشابهة والأحداث، فتميّز تحليلات البحث حركة الحزمة عن غيرها. راجع البحث.
تصل الإبرازات مُهرَّبة بترميز HTML، والكلمات المطابقة محاطة بالوسم <em>. وتقسم parseHighlight() الإبراز إلى مقاطع { text, match }، فتعرضها نصًّا في أيّ صيغة إخراج بدل الوثوق بالسلسلة على أنها ترميز.
مرشّح السعر وتفاصيل النتيجة
منذ الإصدار 0.3.0 يحتفظ price بالأماكن التي تقع في أي من مستويات السعر المحدَّدة: 1 حتى 5 دنانير للشخص، و2 من 5 إلى 10، و3 من 10 إلى 20، و4 أكثر من ذلك. ويمكن أيضًا أن يحمل كل عنصر مكان ما تعرضه قائمة النتائج، ويغيب كل حقل من هذه الحقول إذا لم تتوفّر بياناته للمكان:
const res = await navvo.search("مقهى", { near: { lat: 31.95, lng: 35.91 }, price: [1, 2] });
for (const p of res.places?.items ?? []) {
console.log(p.nameEn, p.categoryName, p.priceRange, p.priceLevel, p.reviewCount);
console.log(p.address, p.area, p.highlights);
if (p.hours) console.log(p.hours.state, p.hours.closesAt, p.hours.opensAt, p.hours.opensDay); // اليوم، بتوقيت الأردن
}
await navvo.similar({ slug: "jordan-museum-994700", locale: "ar" }); // categoryName و address بالعربية
تكون قيمة hours.state إما "open" أو "closing" (يغلق خلال 45 دقيقة) أو "closed". ويدلّ hours.alwaysOpen على مكان مفتوح على مدار الساعة، وhours.hoursMayVary على عطلة رسمية. ويرمي المستوى الواقع خارج 1–4 الخطأ NavvoConfigError قبل إرسال أي شيء. والأنواع مُصدَّرة باسمَي SearchPriceLevel وSearchPlaceHours. راجع تفاصيل النتيجة.
النقرات والتحويلات
لترى نسبة النقر والتحويلات لمشروعك في بوابة المطوّرين، أرسل معرّف جلسة مع البحث، واحدًا لكلّ جلسة مستخدم وفقط إذا وافق مستخدمك على ذلك. ثم أبلِغ عمّا فتحه المستخدم:
import { createSearchSessionId } from "@navvo/sdk";
const session = createSearchSessionId();
const res = await navvo.search("rumi cafe", { session, near: userLocation });
const place = res.places!.items[0]!;
const position = (res.places!.page - 1) * res.places!.limit + 1; // يبدأ من 1 عبر الصفحات
await navvo.sendSearchEvent({ queryId: res.queryId!, type: "click", placeId: place.id, position });
await navvo.sendSearchEvent({ queryId: res.queryId!, type: "conversion", name: "directions", placeId: place.id, position });
- تُقبل الأحداث خلال 7 أيام من البحث، وفقط إذا حمل البحث معرّف جلسة، وفقط بمفتاح API نفسه.
- ترسل
sendSearchEvents()عدّة أحداث معًا، على دفعات من 20. وأسماء التحويلات هيdirectionsوnavigateوsaveوcallوwebsiteوshare. - ترمي
search()الخطأNavvoConfigErrorلمعرّف جلسة لا يطابق^[A-Za-z0-9_-]{16,64}$أو يحتوي على 6 أرقام متتالية؛ أمّاcreateSearchSessionId()فتولّد دائمًا معرّفًا صالحًا.
راجع أحداث البحث لمعرفة ما يُقبل ولماذا قد يُرفض حدث.
خريطة الدوال
| المجال | الدوال |
|---|---|
| البلاطات والإعداد | styles, styleUrl, mapConfig |
| البحث والترميز | search, suggestions, similar, sendSearchEvent, sendSearchEvents, geocode, reverseGeocode, geocodeBatch, reverseGeocodeBatch |
| الأماكن | list, iterate, place, thumb, placeCategories, facets, hours, popularTimes, attributes, reviewsSummary, photos, nearby, reachable |
| المسارات | route, simpleRoute, matrix, isochrone, mapMatch, routingOptimize, routingProfiles |
| التحسين | optimizeHealth, optimize, reoptimize, binpack, roster, submitJob, job, waitForJob |
| حركة المرور والحوادث | trafficRoute, trafficSummary, incidents, incidentTypes, reportIncident, roadEdits, routeRisk |
| الطقس وجودة الهواء | weatherPoint, weatherForecast, weatherCities, airQualityCities |
| الشحن الكهربائي والنقل | evStations, transitStops, gbfs |
تقابل كل دالة نقطة النهاية الموثّقة في مرجع الواجهة. تُعيد
geocode كائنات بأنواع محدّدة مع تحليل الحقول الشائعة والحفاظ على الحمولة الكاملة
في .raw. يتطلّب تحسين المسارات (optimize، submitJob، …) نطاق optimize
الاختياري؛ راجع تحسين المسارات.
مكتبة بايثون (Python SDK)
ثبّت واستخدم عميل بايثون الرسمي navvo لخدمات الترميز الجغرافي والمسارات والأماكن وحركة المرور والمزيد من جهة الخادم.
مكتبة Go (Go SDK)
ثبّت واستخدم عميل Go الرسمي github.com/navvo/navvo-go لخدمات الترميز الجغرافي والمسارات والأماكن وحركة المرور والمركبات الكهربائية والنقل العام والمزيد من جهة الخادم.