UNPKG

@salla.sa/twilight-components

Version:
136 lines (135 loc) 6.04 kB
/*! * Crafted with ❤ by Salla */ /** * API Service for salla-bullet-delivery component * Uses Salla's shipping API and scope API for delivery location management */ const API_LOG_PREFIX = 'BulletDeliveryAPI'; const validId = (id) => { const n = id == null ? Number.NaN : Number(id); return !Number.isNaN(n) && n !== 0; }; async function withApiErrorHandling(fn, fallback, logLabel) { try { return await fn(); } catch (error) { console.error(`${API_LOG_PREFIX}: ${logLabel}`, error); return fallback; } } /** Uses country code from API (e.g. 'SA'). */ export const isSaudiArabia = (countryCode) => String(countryCode).toUpperCase() === 'SA'; /** * Fast Delivery API Service * Uses Salla's shipping API and scopes API. Branch and address data are used as returned by the API (no mapping). */ export const bulletDeliveryAPI = { /** * Get available countries from Salla shipping API * @param forBranch - when true, use for_branch=1 (e.g. for pickup/branches tab) */ async getCountries(forBranch = false) { return withApiErrorHandling(async () => { const data = (await salla.api.request("shipping/countries", { params: { for_branch: forBranch ? 1 : 0 } }))?.data ?? []; return data.map((c) => ({ id: c.id, code: c.code, name: c.name, has_regions: isSaudiArabia(c.code) })); }, [], 'Error getting countries'); }, /** * Get regions for a country from Salla shipping API * Endpoint: GET /shipping/countries/<COUNTRY_ID>/region */ async getRegions(countryId) { if (!validId(countryId)) { console.warn(`${API_LOG_PREFIX}: getRegions called without valid country_id`); return []; } return withApiErrorHandling(async () => { const data = (await salla.api.request(`shipping/countries/${countryId}/regions`))?.data ?? []; return data.map((r) => ({ id: r.id, name: r.name, code: r.code, country_id: Number(countryId) })); }, [], 'Error fetching regions'); }, /** * Get cities from Salla shipping API * @param regionId - Optional; when provided (e.g. for SA), cities are filtered by region */ async getCities(countryId, regionId) { if (!validId(countryId)) { console.warn(`${API_LOG_PREFIX}: getCities called without valid country_id`); return []; } return withApiErrorHandling(async () => { const params = { for_branch: 0, country_id: countryId }; if (regionId) params.region_id = regionId; const data = (await salla.api.request("shipping/cities", { params }))?.data ?? []; return data.map((c) => ({ id: c.id, name: c.name, country_id: countryId, ...(c.region_id != null && { region_id: c.region_id }) })); }, [], 'Error fetching cities'); }, /** * Get districts from Salla shipping API */ async getDistricts(cityId) { if (!validId(cityId)) { console.warn(`${API_LOG_PREFIX}: getDistricts called without valid city_id`); return []; } return withApiErrorHandling(async () => { const raw = (await salla.api.request("shipping/districts", { params: { for_branch: 0, city_id: cityId } }))?.data; const list = Array.isArray(raw) ? raw : (Array.isArray(raw?.districts) ? raw.districts : []); return list.map((d) => ({ id: d.id, name: d.name, name_en: d.name_en, city_id: cityId })); }, [], 'Error fetching districts'); }, async getSavedAddresses() { return withApiErrorHandling(async () => { const data = (await salla.api.request("address"))?.data; return Array.isArray(data) ? data : []; }, [], 'Error fetching user addresses'); }, async getBranches({ query, lat, lng, country_id, per_page = 20 } = {}) { return withApiErrorHandling(async () => { const params = { per_page }; if (query?.trim().length >= 2) params.query = query; if (lat) params.lat = lat; if (lng) params.lng = lng; if (country_id) params.country_id = country_id; const res = await salla.api.request("branches", { params }); return (Array.isArray(res?.data) ? res.data : []); }, [], 'Error fetching branches'); }, async saveAddressLocation(payload) { return withApiErrorHandling(async () => { const res = await salla.api.request('address/location', { ...payload, for_allocation: true }, 'post'); const data = res?.data ?? res; const address = typeof data === 'object' && data != null && 'id' in data ? data : undefined; return { success: true, address }; }, { success: false }, 'Error saving address/location'); }, async setDeliveryScope(scopeId) { return withApiErrorHandling(async () => { await salla.scope.change({ id: scopeId }); salla.storage.set("scope", { ...(salla.storage.get("scope") || {}), id: scopeId }); return true; }, false, 'Error setting delivery scope'); }, async allocateScope(payload) { const errMsg = (d) => d?.error?.message ?? d?.message ?? 'Failed to allocate scope'; try { const response = await salla.api.request("scopes/allocation", payload, 'post'); // SDK resolves with { data } and throws on non-2xx; any resolved value is success const data = response?.data ?? response; return { success: true, data: data }; } catch (error) { console.error(`${API_LOG_PREFIX}: Error allocating scope`, error); const err = error; return { success: false, error: err?.response?.data != null ? errMsg(err.response.data) : (err?.message ?? 'Unknown error') }; } }, }; export default bulletDeliveryAPI;