@dz-delivery/core

中文文档
0.1.11发布于 2026/11/01MITTypeScriptESM + CJS零依赖构建来源已验证

Unified SDK for Algerian delivery carriers (Yalidine, ZRExpress, Maystro, Ecotrack/DHD, GuepEx, NoEST, E-com, MDM, Elogistia) — SDK livraison Algérie : créer, suivre et tarifer des colis, wilayas et communes. TypeScript, Node.js.

原始使用文档
文档目录6 节
  1. Install
  2. Usage
  3. Methods
  4. Options
  5. Errors
  6. Development

@dz-delivery/core — Algerian delivery SDK for TypeScript / Node.js

npm CI License: MIT

One API for Algerian delivery carriers — Yalidine, GuepEx, ZRExpress, Maystro, Ecotrack (DHD, Anderson, World Express, …), NoEST, E-com Delivery, MDM, Elogistia. Create parcels, track shipments, quote fees and list wilayas / communes / stop desks with the same code for every carrier.

🇩🇿 SDK livraison Algérie : un seul code pour créer, suivre et tarifer vos colis chez tous les transporteurs. Docs : https://developing-off.github.io/dz-delivery/ · PHP / Laravel : dz-delivery/sdk

Implements the shared contract in docs/CONTRACT.md; carrier-specific mappings are in docs/PROVIDERS.md.

Yalidine ZRExpress Maystro Delivery Ecotrack NoEST E-com Delivery MDM Express Elogistia

Logos are trademarks of their respective owners, shown only to indicate which carriers the SDK works with. dz-delivery is an independent open-source project, not affiliated with or endorsed by these companies.

ProviderKeyStatus
ZRExpresszrexpress✅ contrat unifié (create, track, fees, locations, stop desks, list, cancel, health) + extras (bulk, labels, webhooks)
Yalidineyalidine✅ contrat unifié (mapping checked against the developer docs, see PROVIDERS.md)
Maystro Deliverymaystro✅ createParcel, track, getFees, getWilayas, getCommunes, getStopDesks, listParcels, cancelParcel — extra getLabels (PDF bordereaux) on MaystroProvider
Ecotrack (DHD, Conexlog, …)ecotrack✅ contrat unifié — one provider for every courier on the Ecotrack platform (courier or baseUrl)
NoESTnoest✅ contrat unifié — listParcels throws NOT_SUPPORTED (no list endpoint)
E-com Deliveryecom✅ contrat unifié, including listParcels
MDM Expressmdm✅ contrat unifié (products from the MDM catalog, storeId) — cancelParcel throws NOT_SUPPORTED
Elogistiaelogistia✅ createParcel, track, getFees, getWilayas, getCommunes — getStopDesks / listParcels / cancelParcel throw NOT_SUPPORTED
  • ESM + CommonJS, bundled type definitions
  • Node.js ≥ 18 (uses global fetch), no runtime dependencies

Install

npm install @dz-delivery/core

Usage

import { createClient, createZRExpress, isShippingError } from '@dz-delivery/core';

const zr = createClient('zrexpress', {
  apiKey: process.env.ZREXPRESS_API_KEY!,
  tenant: process.env.ZREXPRESS_TENANT!,
});
// Extras ZR (bulk / labels / typed provider): createZRExpress({ apiKey, tenant })
// Webhooks: verifyZRExpressWebhook(rawBody, headers, secret) — see docs/ZREXPRESS.md

const yalidine = createClient('yalidine', {
  apiId: process.env.YALIDINE_API_ID!,
  apiToken: process.env.YALIDINE_API_TOKEN!,
  fromWilayaId: 16, // origin wilaya, required by Yalidine to create parcels / quote fees
  // GuepEx (same API): import { GUEPEX_DEFAULT_BASE_URL } and set baseUrl: GUEPEX_DEFAULT_BASE_URL
});

const maystro = createClient('maystro', {
  apiToken: process.env.MAYSTRO_API_TOKEN!, // sent as `Authorization: Token <apiToken>`
});
// track / cancelParcel take Parcel.id or the tracking number. For Maystro webhooks:
// mapMaystroStatus(payload.status) → 'delivered' for 41

const dhd = createClient('ecotrack', {
  token: process.env.ECOTRACK_TOKEN!, // sent as `Authorization: Bearer <token>`
  courier: 'dhd',                     // or baseUrl: 'https://<tenant>.ecotrack.dz'
  // autoValidate: true,              // hand orders to the courier right after creation
});

// Locations
const wilayas = await zr.getWilayas();           // [{ id, name, code: '16', raw }]
const communes = await zr.getCommunes(16);       // provider id or official code 1–58

// Fees
const quote = await zr.getFees({ toWilayaId: 16, isStopDesk: false });
// { deliveryFee: 400, stopDeskFee: 250, currency: 'DZD', raw }

// Create a parcel (ids, official codes or names are accepted)
const parcel = await zr.createParcel({
  recipientName: 'Mohamed Amine',
  phone: '0550 12 34 56',          // normalized to the carrier's format
  address: 'Cité 221 lots, n°98',
  wilayaName: 'Alger',
  communeName: 'Bab Ezzouar',
  productName: 'T-shirt',
  price: 2500,                     // amount collected from the recipient (DZD)
  orderId: 'ORDER-1001',
});
// { id, trackingNumber: 'DZ-AL-…', status: 'pending', provider: 'zrexpress', raw }

// Track
const { parcel: current, events } = await zr.track(parcel.trackingNumber);
// events are sorted oldest first: [{ status: 'pending', label: 'Commande reçue', at: '2025-…+00:00' }, …]

// Cancel (tracking number or internal id)
await zr.cancelParcel(parcel.trackingNumber);

Methods

Every provider implements ShippingProvider:

MethodReturns
createParcel(input: ParcelInput)Promise<Parcel>
track(trackingNumber)Promise<{ parcel, events }>
getFees(query: FeeQuery)Promise<FeeQuote>
getWilayas()Promise<Location[]> (cached per client)
getCommunes(wilayaId)Promise<Location[]> (cached per client)
getStopDesks({ wilayaId, communeId? })Promise<StopDesk[]> — id is the stopDeskId to send (ZRExpress hubs: prefer wilaya-only; Yalidine centers; Maystro needs communeId; Ecotrack communes with a stop desk). Optional fields: phone, openingHours, lat, lng, type.
listParcels(query?)Promise<ParcelListPage> — paginated account parcels + unified status (ZRExpress via parcels/search, Maystro via GET /api/stores/orders/ — 20 per page, filters applied client-side —, E-com via GET /colis, MDM via parcels/search; others NOT_SUPPORTED for now). No event history — use track().
cancelParcel(trackingNumberOrId)Promise<void>
healthCheck()Promise<{ ok: true, provider, latencyMs }> — authenticated connectivity probe (wilayas listing, cache bypassed)

Statuses are unified: pending | created | in_transit | delivered | returned | cancelled | unknown. An unmapped native status never throws — it maps to unknown and the native label stays in TrackingEvent.label / raw.

Options

OptionDefaultDescription
baseUrlcarrier defaultOverride the API base URL (sandbox, proxy).
timeoutMs15000HTTP timeout.
includeRawtrueAttach the native response as raw on every returned model.
fetchglobalThis.fetchCustom fetch implementation (tests, proxies).

Provider credentials: zrexpress → apiKey, tenant; yalidine → apiId, apiToken (+ fromWilayaId or fromWilayaName); maystro → apiToken; ecotrack → token + exactly one of courier (dhd, anderson, worldexpress, 48hrexpress, ecorapid, conexlog, msmgo, packers, rocketdelivery; alias andersondelivery) or baseUrl (any tenant, https only), optional autoValidate; noest → apiToken, userGuid, optional autoValidate; ecom → apiKey, apiToken, optional autoValidate.

Errors

Every failure is a ShippingError with a normalized code:

try {
  await zr.track('DZ-UNKNOWN');
} catch (err) {
  if (isShippingError(err)) {
    err.code;       // 'NOT_FOUND' | 'AUTH_FAILED' | 'VALIDATION_ERROR' | 'RATE_LIMITED' | 'NOT_SUPPORTED' | 'PROVIDER_ERROR' | 'NETWORK_ERROR' | 'UNKNOWN'
    err.httpStatus; // 404
    err.details;    // e.g. [{ field: 'phone', message: '…' }] for validation errors
    err.raw;        // native error body
  }
}

Input is validated before any HTTP call (VALIDATION_ERROR), and wilaya/commune names that cannot be resolved throw NOT_FOUND.

Development

npm install
npm test          # vitest — mocked fetch, no network
npm run typecheck
npm run build     # tsup → dist/ (ESM + CJS + .d.ts)

Tests replay the shared fixtures in docs/fixtures/ (also used by the PHP package), so both implementations produce the same output for the same native responses.

A runnable example lives in examples/ts/quickstart.ts.

版本与发布记录

@dz-delivery/core 共发布 12 个版本,首次发布于 2026/10/20;过去 12 个月发布了 12 个版本。最新版本附带 npm provenance 构建来源证明,可追溯到公开的 CI 构建记录。

版本发布日期距今
0.1.11latest2026/11/012 天前
0.1.102026/10/313 天前
0.1.92026/10/304 天前
0.1.82026/10/2410 天前
0.1.72026/10/2112 天前
0.1.32026/10/2112 天前

关于 @dz-delivery/core 的常见问题

@dz-delivery/core 是什么?

针对阿尔及利亚快递公司(Yalidine、zreexpress、Maystro、Ecotrack/DHD、GuepEx、NoEST、E-com、MDM、Elogistia)的统一SDK -适用于阿尔及利亚的运输公司(alidine、zreexpress、Maystro、Ecotrack/DHD、GuepEx、NoEST、E-com、MDM、Elogistia)。打印稿,node . js。

如何安装 @dz-delivery/core?

在项目目录运行 npm install @dz-delivery/core,或使用 pnpm add / yarn add / bun add。

@dz-delivery/core 支持 TypeScript 吗?

支持。包内自带 TypeScript 类型声明(package.json 声明了 types 入口),安装后即可获得类型提示,无需再安装 @types 包。

@dz-delivery/core 支持 ESM 还是 CommonJS?

同时提供 ES Module 与 CommonJS 入口,import 和 require() 都可以使用,打包工具会自动选择合适的版本。

@dz-delivery/core 需要什么版本的 Node.js?

package.json 的 engines 字段要求 Node.js >=18。版本不符时 npm 默认只给出警告,开启 engine-strict 后会拒绝安装。

@dz-delivery/core 可以商用吗?

@dz-delivery/core 使用 MIT 许可。宽松许可:允许商业使用、修改和再分发,通常只需在分发时保留原版权与许可声明。以上为概括,不构成法律意见,请以许可原文为准。

@dz-delivery/core 还在维护吗?

最新版本 0.1.11 发布于 2026/11/01(2 天前);至今共发布 12 个版本,其中过去 12 个月发布了 12 个;首次发布于 2026/10/20。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。