shipflow 0.3.0 → 0.3.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.
@@ -2,12 +2,11 @@ import {
2
2
  APIError,
3
3
  BaseCarrierAdapter,
4
4
  HttpClient,
5
- UnsupportedOperationError,
6
5
  ValidationError,
7
6
  WebhookVerificationError,
8
7
  validateCreateShipmentInput,
9
8
  validatePickupRequest
10
- } from "../../index-qnxj8bct.js";
9
+ } from "../../index-8cpdcbsf.js";
11
10
 
12
11
  // src/carriers/aymakan/services.ts
13
12
  var AymakanService = {
@@ -204,13 +203,14 @@ function mapTrackingEvent(event) {
204
203
  };
205
204
  }
206
205
  function mapTrackingResult(data) {
207
- const events = data.tracking_info.map(mapTrackingEvent);
208
- const latestEvent = events.length ? [...events].sort((a, b) => b.timestamp.getTime() - a.timestamp.getTime())[0] : undefined;
206
+ const events = (data.tracking_info ?? []).map(mapTrackingEvent);
207
+ const sortedEvents = events.length ? [...events].sort((a, b) => b.timestamp.getTime() - a.timestamp.getTime()) : [];
208
+ const mostRecentRecognizedEvent = sortedEvents.find((e) => e.status !== "unknown");
209
209
  let status;
210
- if (latestEvent && latestEvent.status !== "unknown") {
211
- status = latestEvent.status;
210
+ if (mostRecentRecognizedEvent) {
211
+ status = mostRecentRecognizedEvent.status;
212
212
  } else {
213
- status = mapAymakanStatus(data.status) ?? mapAymakanStatusLabel(data.status) ?? latestEvent?.status ?? "unknown";
213
+ status = mapAymakanStatus(data.status) ?? mapAymakanStatusLabel(data.status) ?? "unknown";
214
214
  }
215
215
  return {
216
216
  trackingNumber: data.tracking_number,
@@ -266,12 +266,6 @@ function timingSafeEqual(a, b) {
266
266
  }
267
267
  function parseAymakanWebhook(payload, options) {
268
268
  const { headers = {}, queryParams = {}, config } = options ?? {};
269
- if (!payload || typeof payload !== "object" || !("tracking_number" in payload) || !("status" in payload)) {
270
- throw new ValidationError("Invalid webhook payload: missing required fields", {
271
- raw: payload
272
- });
273
- }
274
- const data = payload;
275
269
  if (config?.authHeader && config?.authValue) {
276
270
  const lowerKey = config.authHeader.toLowerCase();
277
271
  const headerValue = Object.entries(headers).find(([k]) => k.toLowerCase() === lowerKey)?.[1];
@@ -289,6 +283,12 @@ function parseAymakanWebhook(payload, options) {
289
283
  });
290
284
  }
291
285
  }
286
+ if (!payload || typeof payload !== "object" || !("tracking_number" in payload) || !("status" in payload)) {
287
+ throw new ValidationError("Invalid webhook payload: missing required fields", {
288
+ raw: payload
289
+ });
290
+ }
291
+ const data = payload;
292
292
  const eventType = data.event ?? "status_update";
293
293
  const timestamp = new Date(data.date_time);
294
294
  if (Number.isNaN(timestamp.getTime())) {
@@ -312,6 +312,22 @@ function parseAymakanWebhook(payload, options) {
312
312
  // src/carriers/aymakan/adapter.ts
313
313
  var AYMAKAN_SANDBOX_URL = "https://dev-api.aymakan.com.sa/v2";
314
314
  var AYMAKAN_PRODUCTION_URL = "https://api.aymakan.net/v2";
315
+ function extractNestedMessage(value) {
316
+ if (typeof value === "string")
317
+ return value;
318
+ if (value && typeof value === "object") {
319
+ const obj = value;
320
+ if (typeof obj.message === "string")
321
+ return obj.message;
322
+ if (typeof obj.response === "string")
323
+ return obj.response;
324
+ }
325
+ return;
326
+ }
327
+ function joinFieldErrors(errors) {
328
+ const parts = Object.values(errors).flat().filter((v) => typeof v === "string");
329
+ return parts.length ? parts.join("; ") : undefined;
330
+ }
315
331
  function aymakanErrorExtractor(json) {
316
332
  if (!json || typeof json !== "object") {
317
333
  return { hasError: false };
@@ -322,7 +338,7 @@ function aymakanErrorExtractor(json) {
322
338
  if (!hasError) {
323
339
  return { hasError: false };
324
340
  }
325
- const message = typeof obj.message === "string" && obj.message || typeof obj.response === "string" && obj.response || typeof obj.error === "string" && obj.error || undefined;
341
+ const message = typeof obj.message === "string" && obj.message || typeof obj.response === "string" && obj.response || typeof obj.error === "string" && obj.error || extractNestedMessage(obj.error) || (hasValidationErrors ? joinFieldErrors(obj.errors) : undefined) || undefined;
326
342
  return {
327
343
  hasError: true,
328
344
  message,
@@ -337,7 +353,9 @@ class AymakanAdapter extends BaseCarrierAdapter {
337
353
  errorOpts = { errorExtractor: aymakanErrorExtractor };
338
354
  citiesCache = null;
339
355
  citiesCacheTime = 0;
356
+ citiesFetchFailedAt = 0;
340
357
  static CITIES_CACHE_TTL = 60 * 60 * 1000;
358
+ static CITIES_FAILURE_COOLDOWN = 60 * 1000;
341
359
  constructor(config) {
342
360
  super(config);
343
361
  this.http = new HttpClient({
@@ -352,13 +370,20 @@ class AymakanAdapter extends BaseCarrierAdapter {
352
370
  return this.config.mode === "production" ? AYMAKAN_PRODUCTION_URL : AYMAKAN_SANDBOX_URL;
353
371
  }
354
372
  async ensureCitiesLoaded() {
355
- if (this.citiesCache && Date.now() - this.citiesCacheTime < AymakanAdapter.CITIES_CACHE_TTL) {
373
+ const now = Date.now();
374
+ if (this.citiesCache && now - this.citiesCacheTime < AymakanAdapter.CITIES_CACHE_TTL) {
375
+ return;
376
+ }
377
+ if (now - this.citiesFetchFailedAt < AymakanAdapter.CITIES_FAILURE_COOLDOWN) {
378
+ if (!this.citiesCache)
379
+ this.citiesCache = [];
356
380
  return;
357
381
  }
358
382
  try {
359
383
  this.citiesCache = await this.getCities();
360
- this.citiesCacheTime = Date.now();
384
+ this.citiesCacheTime = now;
361
385
  } catch {
386
+ this.citiesFetchFailedAt = now;
362
387
  if (!this.citiesCache)
363
388
  this.citiesCache = [];
364
389
  }
@@ -387,9 +412,11 @@ class AymakanAdapter extends BaseCarrierAdapter {
387
412
  const alMatch = this.citiesCache.find((c) => c.nameAr && AymakanAdapter.normalizeArabic(c.nameAr) === withoutAl);
388
413
  if (alMatch)
389
414
  return alMatch.nameEn;
390
- const containsEn = this.citiesCache.find((c) => c.nameEn.toLowerCase().includes(lower) || lower.includes(c.nameEn.toLowerCase()));
391
- if (containsEn)
392
- return containsEn.nameEn;
415
+ if (lower.length >= 3) {
416
+ const containsEn = this.citiesCache.find((c) => c.nameEn.toLowerCase().includes(lower));
417
+ if (containsEn)
418
+ return containsEn.nameEn;
419
+ }
393
420
  return trimmed;
394
421
  }
395
422
  resolveCitiesInInput(input) {
@@ -452,7 +479,8 @@ class AymakanAdapter extends BaseCarrierAdapter {
452
479
  async updateDeliveryAddress(trackingNumber, address) {
453
480
  await this.ensureCitiesLoaded();
454
481
  const resolvedCity = this.resolveCity(address.city);
455
- const response = await this.http.post(`/shipping/update_delivery_address/${encodeURIComponent(trackingNumber)}`, {
482
+ const response = await this.http.post("/shipping/update/delivery_address", {
483
+ tracking: trackingNumber,
456
484
  delivery_name: address.name,
457
485
  delivery_email: address.email,
458
486
  delivery_city: resolvedCity,
@@ -460,9 +488,9 @@ class AymakanAdapter extends BaseCarrierAdapter {
460
488
  delivery_neighbourhood: address.neighbourhood,
461
489
  delivery_postcode: address.postalCode,
462
490
  delivery_country: address.countryCode,
463
- delivery_phone: address.phone
464
- });
465
- return response.success;
491
+ delivery_phone: sanitizePhone(address.phone)
492
+ }, this.errorOpts);
493
+ return response.success === true;
466
494
  }
467
495
  async track(trackingNumber) {
468
496
  const results = await this.trackMultiple([trackingNumber]);
@@ -528,7 +556,7 @@ class AymakanAdapter extends BaseCarrierAdapter {
528
556
  return response.data.cities.map(mapCity);
529
557
  }
530
558
  async getTimeSlots(_city, date) {
531
- const response = await this.http.get(`/time_slots/${date}`);
559
+ const response = await this.http.get(`/time_slots/${encodeURIComponent(date)}`, this.errorOpts);
532
560
  if (!response.success || response.error || !response.data?.slots) {
533
561
  const msg = response.message ?? "No slots available";
534
562
  throw new APIError(msg, { carrier: "aymakan", raw: response });
@@ -571,7 +599,7 @@ class AymakanAdapter extends BaseCarrierAdapter {
571
599
  return list.map(mapPickupResponse);
572
600
  }
573
601
  async getCities() {
574
- const response = await this.http.get("/cities");
602
+ const response = await this.http.get("/cities", this.errorOpts);
575
603
  if (!response.success) {
576
604
  throw new APIError("Failed to get cities", {
577
605
  carrier: "aymakan",
@@ -581,7 +609,7 @@ class AymakanAdapter extends BaseCarrierAdapter {
581
609
  return response.data.cities.map(mapCity);
582
610
  }
583
611
  async getDropoffLocations() {
584
- const response = await this.http.get("/dropoff_locations");
612
+ const response = await this.http.get("/dropoff_locations", this.errorOpts);
585
613
  if (!response.success) {
586
614
  throw new APIError("Failed to get dropoff locations", {
587
615
  carrier: "aymakan",
@@ -682,14 +710,11 @@ class AymakanAdapter extends BaseCarrierAdapter {
682
710
  }
683
711
  async deleteCustomerAddress(id) {
684
712
  const response = await this.http.delete("/address/delete", { body: { id }, errorExtractor: aymakanErrorExtractor });
685
- return response.success;
713
+ return response.success === true;
686
714
  }
687
715
  parseWebhook(payload, options) {
688
716
  return parseAymakanWebhook(payload, options);
689
717
  }
690
- getRates() {
691
- throw new UnsupportedOperationError("aymakan", "getRates");
692
- }
693
718
  }
694
719
  export {
695
720
  parseAymakanWebhook,
@@ -699,4 +724,4 @@ export {
699
724
  AymakanAdapter
700
725
  };
701
726
 
702
- //# debugId=52369388ABAA8E1964756E2164756E21
727
+ //# debugId=30143D4A5E00F51C64756E2164756E21
@@ -3,10 +3,10 @@
3
3
  "sources": ["../src/carriers/aymakan/services.ts", "../src/carriers/aymakan/mappers.ts", "../src/carriers/aymakan/adapter.ts"],
4
4
  "sourcesContent": [
5
5
  "// file: src/carriers/aymakan/services.ts\n/**\n * Aymakan Service Type Codes\n * Use these constants for type-safe service selection.\n */\n\nexport const AymakanService = {\n /** Default ecommerce service */\n ECOMMERCE: \"ONP\",\n /** Documents or banking docs service */\n DOCUMENTS: \"DOC\",\n /** Same day delivery service */\n SAME_DAY: \"SDD\",\n /** Reverse pickup service */\n REVERSE_PICKUP: \"RVP\",\n /** Exchange service */\n EXCHANGE: \"EXH\",\n /** Lockers service */\n LOCKERS: \"LOC\",\n /** Heavy and bulky service */\n HEAVY: \"BLK\",\n /** Pallet service */\n PALLET: \"PLT\",\n /** Import express (International) */\n IMPORT_EXPRESS: \"IPX\",\n /** Export express (International) */\n EXPORT_EXPRESS: \"EPX\",\n} as const;\n\nexport type AymakanServiceType =\n (typeof AymakanService)[keyof typeof AymakanService];\n\n/**\n * Aymakan Status Codes\n * Maps carrier-specific codes to our unified status.\n */\nexport const AymakanStatusCodes = {\n // Core lifecycle\n \"AY-0001\": \"created\", // Shipment created / AWB created at origin\n \"AY-0002\": \"picked_up\", // Collected from collection point\n \"AY-0003\": \"at_warehouse\", // Received at hub\n \"AY-0004\": \"out_for_delivery\", // Out for final destination\n \"AY-0005\": \"delivered\", // Delivered to customer\n \"AY-0006\": \"exception\", // Not delivered (failed attempt)\n\n // Warehouse / transfer\n \"AY-0026\": \"at_warehouse\", // Received at [City] Warehouse\n \"AY-0027\": \"in_transit\", // Transferred to destination city\n \"AY-0028\": \"in_transit\", // In transit between hubs\n\n // Pending / rescheduled (delivery was attempted but rescheduled)\n \"AY-0032\": \"pending\", // Pending — future delivery / rescheduled\n\n // Terminal states\n \"AY-0007\": \"returned\", // Returned to shipper\n \"AY-0008\": \"cancelled\", // Cancelled\n \"AY-0009\": \"returned\", // Return to origin\n} as const;\n",
6
- "// file: src/carriers/aymakan/mappers.ts\n/**\n * Aymakan Data Mappers\n * Transform between unified ShipFlow types and Aymakan API formats.\n */\n\nimport { ValidationError, WebhookVerificationError } from \"../../core/errors\";\nimport type {\n Address,\n City,\n CreateShipmentInput,\n CustomerAddress,\n Pickup,\n PickupRequest,\n Shipment,\n ShipmentStatus,\n TrackingEvent,\n TrackingResult,\n WebhookConfig,\n WebhookEvent,\n} from \"../../core/types\";\nimport { AymakanService, AymakanStatusCodes } from \"./services\";\nimport type {\n AymakanAddressRequest,\n AymakanCity,\n AymakanCreateShipmentRequest,\n AymakanNationalAddressRequest,\n AymakanPickupRequest,\n AymakanPickupResponse,\n AymakanShipmentResponse,\n AymakanTrackingEvent,\n AymakanTrackShipmentData,\n AymakanWebhookPayload,\n} from \"./types\";\n\n// ============================================================================\n// STATUS MAPPING\n// ============================================================================\n\nexport function mapAymakanStatus(statusCode: string): ShipmentStatus | undefined {\n const mapped =\n AymakanStatusCodes[statusCode as keyof typeof AymakanStatusCodes];\n return mapped as ShipmentStatus | undefined;\n}\n\n/**\n * The /track endpoint's top-level `status` is a human-readable English label\n * (e.g. \"Received at Warehouse\") rather than an AY code, so `mapAymakanStatus`\n * can never resolve it. This map recovers a real unified status from that label\n * when there are no tracking events to derive it from. Keys are compared\n * case-insensitively.\n */\nconst AymakanStatusLabels: Record<string, ShipmentStatus> = {\n \"awb created at origin\": \"created\",\n \"shipment created\": \"created\",\n \"collected from collection point\": \"picked_up\",\n collected: \"picked_up\",\n \"picked up\": \"picked_up\",\n \"received at hub\": \"at_warehouse\",\n \"received at warehouse\": \"at_warehouse\",\n \"out for delivery\": \"out_for_delivery\",\n \"out for final destination\": \"out_for_delivery\",\n delivered: \"delivered\",\n \"shipment is delivered\": \"delivered\",\n \"transferred to destination city\": \"in_transit\",\n \"in transit\": \"in_transit\",\n \"not delivered\": \"exception\",\n \"failed attempt\": \"exception\",\n pending: \"pending\",\n \"future delivery\": \"pending\",\n returned: \"returned\",\n \"returned to shipper\": \"returned\",\n \"return to origin\": \"returned\",\n cancelled: \"cancelled\",\n canceled: \"cancelled\",\n};\n\n/**\n * Map a human-readable Aymakan status label to a unified status.\n * Returns undefined for unrecognized labels.\n */\nexport function mapAymakanStatusLabel(\n label: string,\n): ShipmentStatus | undefined {\n return AymakanStatusLabels[label.trim().toLowerCase()];\n}\n\n// ============================================================================\n// REQUEST MAPPERS\n// ============================================================================\n\nfunction mapNationalAddress(\n addr?: Address[\"nationalAddress\"],\n): AymakanNationalAddressRequest | undefined {\n if (!addr) return undefined;\n return {\n short_code: addr.shortCode,\n building_number: addr.buildingNumber,\n street_name: addr.streetName,\n district: addr.district,\n additional_number: addr.additionalNumber,\n };\n}\n\n/** Strip non-digit characters from phone numbers (Aymakan requires digits only) */\nfunction sanitizePhone(phone: string): string {\n return phone.replace(/\\D/g, '');\n}\n\n/** Set of valid Aymakan service type codes */\nconst VALID_AYMAKAN_SERVICE_TYPES = new Set(\n Object.values(AymakanService) as string[],\n);\n\n/**\n * Resolve service type to a valid Aymakan code.\n * Returns undefined for unknown values so the API uses its default (ONP/ecommerce).\n */\nfunction resolveServiceType(serviceType?: string): string | undefined {\n if (!serviceType) return undefined;\n if (VALID_AYMAKAN_SERVICE_TYPES.has(serviceType)) return serviceType;\n return undefined;\n}\n\nexport function mapCreateShipmentRequest(\n input: CreateShipmentInput,\n): AymakanCreateShipmentRequest {\n const firstParcel = input.parcels[0];\n const totalPieces = input.parcels.reduce((sum, p) => sum + p.pieces, 0);\n const totalWeight = input.parcels.reduce(\n (sum, p) =>\n sum +\n (p.weight.unit === \"lb\" ? p.weight.value * 0.453592 : p.weight.value),\n 0,\n );\n const totalItems = input.parcels.reduce(\n (sum, p) => sum + (p.itemsCount ?? p.pieces),\n 0,\n );\n\n // COD (collected from the buyer on delivery) and declared/customs value are\n // distinct concepts and must never be conflated. Declared value comes solely\n // from input.declaredValue; COD comes solely from input.cod.\n const codEnabled = input.cod?.enabled === true;\n const declaredValueCurrency = input.declaredValue?.currency ?? \"SAR\";\n\n return {\n requested_by: input.options?.requestedBy ?? input.shipper.name,\n declared_value: input.declaredValue?.amount ?? 0,\n declared_value_currency: declaredValueCurrency,\n reference: input.reference,\n customer_tracking: input.options?.customerTracking,\n service_type: resolveServiceType(input.serviceType),\n is_cod: codEnabled ? 1 : 0,\n cod_amount: codEnabled ? input.cod?.amount : undefined,\n fulfilment_customer_name: input.options?.fulfilmentCustomerName,\n // Top-level currency prefers the COD currency when COD is enabled (it's the\n // amount actually collected), otherwise the declared-value currency.\n currency: codEnabled\n ? (input.cod?.currency ?? \"SAR\")\n : declaredValueCurrency,\n\n // Delivery (consignee)\n delivery_name: input.consignee.name,\n delivery_email: input.consignee.email,\n delivery_city: input.consignee.city,\n delivery_address: input.consignee.line1,\n delivery_neighbourhood:\n input.consignee.neighbourhood ?? input.consignee.state,\n delivery_postcode: input.consignee.postalCode,\n delivery_country: input.consignee.countryCode,\n delivery_phone: sanitizePhone(input.consignee.phone),\n delivery_description: input.consignee.description,\n delivery_national_address: mapNationalAddress(\n input.consignee.nationalAddress,\n ),\n\n // Collection (shipper)\n collection_name: input.shipper.company ?? input.shipper.name,\n collection_email: input.shipper.email,\n collection_city: input.shipper.city,\n collection_address: input.shipper.line1,\n collection_neighbourhood:\n input.shipper.neighbourhood ?? input.shipper.state,\n collection_postcode: input.shipper.postalCode,\n collection_country: input.shipper.countryCode,\n collection_phone: sanitizePhone(input.shipper.phone),\n collection_description: input.shipper.description,\n collection_national_address: mapNationalAddress(\n input.shipper.nationalAddress,\n ),\n\n // Parcel details\n weight: totalWeight,\n length: firstParcel?.dimensions?.length,\n width: firstParcel?.dimensions?.width,\n height: firstParcel?.dimensions?.height,\n pieces: totalPieces,\n items_count: totalItems,\n is_insured: input.options?.isInsured ? 1 : 0,\n\n // International\n international_metadata: input.options?.internationalMetadata\n ? {\n document_id: input.options.internationalMetadata.documentId,\n tax_identification_number: input.options.internationalMetadata.taxId,\n invoice_number: input.options.internationalMetadata.invoiceNumber,\n invoice_date: input.options.internationalMetadata.invoiceDate,\n }\n : undefined,\n };\n}\n\nexport function mapPickupRequest(input: PickupRequest): AymakanPickupRequest {\n return {\n reference: input.trackingNumbers?.[0],\n pickup_date: input.date,\n time_slot: input.timeSlot,\n city: input.city,\n contact_name: input.contactName,\n contact_phone: input.contactPhone,\n address: input.address,\n shipments: input.shipmentCount,\n };\n}\n\nexport function mapCustomerAddressRequest(\n addr: CustomerAddress,\n): AymakanAddressRequest {\n return {\n title: addr.title,\n name: addr.name,\n email: addr.email,\n city: addr.city,\n address: addr.address,\n neighbourhood: addr.neighbourhood,\n postcode: addr.postalCode ?? \"\",\n phone: addr.phone,\n description: addr.description ?? \"\",\n };\n}\n\n// ============================================================================\n// RESPONSE MAPPERS\n// ============================================================================\n\nexport function mapShipmentResponse(data: AymakanShipmentResponse): Shipment {\n // Parse cod_amount: API returns string like \"150.00\", we need number\n const codAmount =\n data.cod_amount != null\n ? typeof data.cod_amount === \"string\"\n ? parseFloat(data.cod_amount)\n : data.cod_amount\n : undefined;\n\n return {\n carrier: \"aymakan\",\n trackingNumber: data.tracking_number,\n customerTracking: data.customer_tracking ?? undefined,\n reference: data.reference ?? undefined,\n status: mapAymakanStatus(data.status) ?? \"created\",\n statusLabel: data.status_label,\n labelUrl: data.label || undefined,\n pdfLabelUrl: data.pdf_label || undefined,\n // Emit a defined COD amount whenever we parsed a real number. A COD of 0\n // means \"no cash collected\", so surface it as undefined, but never let NaN\n // logic on a falsy 0 drop an otherwise valid value.\n codAmount:\n codAmount != null && !Number.isNaN(codAmount) && codAmount !== 0\n ? codAmount\n : undefined,\n declaredValue: data.declared_value,\n currency: data.currency,\n createdAt: new Date(data.created_at),\n raw: data,\n };\n}\n\n/**\n * Parse an Aymakan timestamp. Top-level fields are ISO 8601 (with `T`/`Z`), but\n * `tracking_info[].created_at` values are space-separated \"YYYY-MM-DD HH:MM:SS\"\n * strings in Saudi local time (UTC+3) with no timezone marker. `new Date()`\n * would parse those in the host's local timezone, so normalize to +03:00.\n */\nfunction parseAymakanDate(value: string): Date {\n if (/[TZ]|[+-]\\d{2}:?\\d{2}$/.test(value)) {\n return new Date(value);\n }\n return new Date(`${value.replace(\" \", \"T\")}+03:00`);\n}\n\nexport function mapTrackingEvent(event: AymakanTrackingEvent): TrackingEvent {\n return {\n timestamp: parseAymakanDate(event.created_at),\n statusCode: event.status_code,\n status: mapAymakanStatus(event.status_code) ?? \"unknown\",\n description: event.description,\n descriptionArabic: event.description_ar ?? undefined,\n };\n}\n\nexport function mapTrackingResult(\n data: AymakanTrackShipmentData,\n): TrackingResult {\n const events = data.tracking_info.map(mapTrackingEvent);\n\n // The top-level `status` field is a human-readable label on the /track\n // endpoint (e.g. \"Received at Warehouse\") and an AY code on /by_reference.\n // Derive the unified status from the most recent tracking event (whose\n // status_code is always an AY code), falling back to mapping the top-level\n // status. The fallback tries the AY-code map first (handles /by_reference)\n // and then the human-label map (handles /track), so a real state is recovered\n // even when there are no events, then \"unknown\".\n const latestEvent = events.length\n ? [...events].sort(\n (a, b) => b.timestamp.getTime() - a.timestamp.getTime(),\n )[0]\n : undefined;\n let status: ShipmentStatus;\n if (latestEvent && latestEvent.status !== \"unknown\") {\n status = latestEvent.status;\n } else {\n status =\n mapAymakanStatus(data.status) ??\n mapAymakanStatusLabel(data.status) ??\n latestEvent?.status ??\n \"unknown\";\n }\n\n return {\n trackingNumber: data.tracking_number,\n carrier: \"aymakan\",\n reference: data.reference ?? undefined,\n status,\n statusLabel: data.status_label,\n events,\n deliveryDate: data.delivery_date ? new Date(data.delivery_date) : undefined,\n pickupDate: data.pickup_date ? new Date(data.pickup_date) : undefined,\n receivedAt: data.received_at ? new Date(data.received_at) : undefined,\n codAmount: data.cod_amount\n ? Number.isNaN(parseFloat(data.cod_amount))\n ? undefined\n : parseFloat(data.cod_amount)\n : undefined,\n weight: Number.isNaN(parseFloat(data.weight))\n ? undefined\n : parseFloat(data.weight),\n pieces: data.pieces,\n raw: data,\n };\n}\n\nexport function mapCity(city: AymakanCity): City {\n return {\n nameEn: city.city_en,\n nameAr: city.city_ar,\n };\n}\n\nexport function mapPickupResponse(data: AymakanPickupResponse[\"data\"]): Pickup {\n return {\n id: data.id,\n carrier: \"aymakan\",\n status: (\n [\"pending\", \"processing\", \"completed\", \"cancelled\"] as const\n ).includes(data.status as Pickup[\"status\"])\n ? (data.status as Pickup[\"status\"])\n : \"pending\",\n date: data.pickup_date,\n timeSlot: data.time_slot,\n city: data.city,\n contactName: data.contact_name,\n contactPhone: data.contact_phone,\n address: data.address,\n shipmentCount: data.shipments,\n warehouseId: data.warehouse_id,\n warehouseName: data.warehouse_name,\n createdAt: new Date(data.created_at),\n raw: data,\n };\n}\n\n// ============================================================================\n// WEBHOOK MAPPER\n// ============================================================================\n\n/**\n * Timing-safe string comparison to prevent timing attacks on auth tokens.\n */\nfunction timingSafeEqual(a: string, b: string): boolean {\n const encoder = new TextEncoder();\n const bufA = encoder.encode(a);\n const bufB = encoder.encode(b);\n if (bufA.byteLength !== bufB.byteLength) return false;\n // Use crypto.subtle-compatible constant-time compare\n let mismatch = 0;\n for (let i = 0; i < bufA.byteLength; i++) {\n mismatch |= bufA[i]! ^ bufB[i]!;\n }\n return mismatch === 0;\n}\n\nexport function parseAymakanWebhook(\n payload: unknown,\n options?: {\n headers?: Record<string, string>;\n queryParams?: Record<string, string>;\n config?: WebhookConfig;\n },\n): WebhookEvent {\n const { headers = {}, queryParams = {}, config } = options ?? {};\n\n // Validate required fields\n if (\n !payload ||\n typeof payload !== \"object\" ||\n !(\"tracking_number\" in payload) ||\n !(\"status\" in payload)\n ) {\n throw new ValidationError(\n \"Invalid webhook payload: missing required fields\",\n {\n raw: payload,\n },\n );\n }\n\n const data = payload as AymakanWebhookPayload;\n\n // Verify auth via header (case-insensitive lookup, timing-safe comparison)\n if (config?.authHeader && config?.authValue) {\n const lowerKey = config.authHeader.toLowerCase();\n const headerValue = Object.entries(headers).find(\n ([k]) => k.toLowerCase() === lowerKey,\n )?.[1];\n if (!headerValue || !timingSafeEqual(headerValue, config.authValue)) {\n throw new WebhookVerificationError(\"Invalid webhook auth header\", {\n carrier: \"aymakan\",\n });\n }\n }\n\n // Verify auth via query param (timing-safe comparison)\n if (config?.authQueryParam && config?.authQueryValue) {\n const paramValue = queryParams[config.authQueryParam];\n if (!paramValue || !timingSafeEqual(paramValue, config.authQueryValue)) {\n throw new WebhookVerificationError(\"Invalid webhook auth query param\", {\n carrier: \"aymakan\",\n });\n }\n }\n\n const eventType = data.event ?? \"status_update\";\n\n // Validate timestamp\n const timestamp = new Date(data.date_time);\n if (Number.isNaN(timestamp.getTime())) {\n throw new ValidationError(\n \"Invalid webhook payload: invalid date_time value\",\n { raw: data.date_time },\n );\n }\n\n return {\n carrier: \"aymakan\",\n eventType,\n trackingNumber: data.tracking_number,\n reference: data.reference ?? undefined,\n // `status` is a core field present on every webhook regardless of event\n // type, so map it even for weight_update events. Consumers can still branch\n // on `eventType` to detect weight updates.\n status: mapAymakanStatus(data.status) ?? \"unknown\",\n statusCode: data.status,\n statusLabel: data.status_label,\n reasonCode: data.reason_code ?? undefined,\n reasonLabel: data.reason_en ?? undefined,\n timestamp,\n raw: data,\n };\n}\n",
7
- "// file: src/carriers/aymakan/adapter.ts\n/**\n * Aymakan Carrier Adapter\n * Full implementation of the CarrierAdapter interface for Aymakan API.\n */\n\nimport {\n APIError,\n UnsupportedOperationError,\n ValidationError,\n} from \"../../core/errors\";\nimport { HttpClient } from \"../../core/http\";\nimport {\n validateCreateShipmentInput,\n validatePickupRequest,\n} from \"../../core/schemas\";\nimport type {\n Address,\n CarrierConfig,\n City,\n CreateShipmentInput,\n CustomerAddress,\n Pickup,\n PickupRequest,\n Shipment,\n TimeSlot,\n TrackingResult,\n WebhookConfig,\n WebhookEvent,\n} from \"../../core/types\";\nimport { BaseCarrierAdapter } from \"../base\";\nimport {\n mapCity,\n mapCreateShipmentRequest,\n mapCustomerAddressRequest,\n mapPickupRequest,\n mapPickupResponse,\n mapShipmentResponse,\n mapTrackingResult,\n parseAymakanWebhook,\n} from \"./mappers\";\nimport type {\n AymakanAddressResponse,\n AymakanCancelResponse,\n AymakanCitiesResponse,\n AymakanCreateShipmentResponse,\n AymakanPickupResponse,\n AymakanTrackResponse,\n} from \"./types\";\n\nconst AYMAKAN_SANDBOX_URL = \"https://dev-api.aymakan.com.sa/v2\";\nconst AYMAKAN_PRODUCTION_URL = \"https://api.aymakan.net/v2\";\n\n/**\n * Aymakan returns logical errors inside a fake-200 envelope (HTTP 200 with an\n * error flag/message in the body). Without an extractor these are swallowed —\n * e.g. cancel endpoints would return `success: undefined` and the adapter would\n * report `false` with no reason. This extractor surfaces those as APIError.\n *\n * Recognised error shapes (all on a 200 body):\n * - `{ error: true, ... }` → Laravel/Aymakan error flag\n * - `{ success: false, ... }` → explicit failure flag\n * - `{ message }` / `{ response }` → human-readable error text\n * - `{ errors: { field: [...] } }` → Laravel field validation errors\n *\n * A bare `{ message }` is NOT treated as an error on its own (many success\n * envelopes carry a `message`); we only flag when `error`/`success:false` is\n * present, or validation `errors` exist.\n */\nfunction aymakanErrorExtractor(json: unknown): {\n hasError: boolean;\n message?: string;\n errors?: Record<string, string[]>;\n} {\n if (!json || typeof json !== \"object\") {\n return { hasError: false };\n }\n const obj = json as Record<string, unknown>;\n\n const hasValidationErrors =\n !!obj.errors &&\n typeof obj.errors === \"object\" &&\n Object.keys(obj.errors as object).length > 0;\n const hasError = obj.error === true || obj.success === false || hasValidationErrors;\n\n if (!hasError) {\n return { hasError: false };\n }\n\n const message =\n (typeof obj.message === \"string\" && obj.message) ||\n (typeof obj.response === \"string\" && obj.response) ||\n (typeof obj.error === \"string\" && obj.error) ||\n undefined;\n\n return {\n hasError: true,\n message,\n errors: hasValidationErrors\n ? (obj.errors as Record<string, string[]>)\n : undefined,\n };\n}\n\nexport interface AymakanConfig extends CarrierConfig {\n credentials: {\n apiKey: string;\n };\n}\n\nexport class AymakanAdapter extends BaseCarrierAdapter {\n readonly name = \"aymakan\";\n readonly supportedCountries = [\"SA\", \"AE\", \"BH\", \"KW\", \"OM\", \"QA\"];\n\n private http: HttpClient;\n\n /**\n * Shared options applied to every Aymakan http call so fake-200 error\n * envelopes surface as APIError instead of being silently swallowed.\n */\n private readonly errorOpts = { errorExtractor: aymakanErrorExtractor };\n\n /** Cached Aymakan cities list for city name resolution */\n private citiesCache: City[] | null = null;\n private citiesCacheTime = 0;\n /** Cache TTL: 1 hour */\n private static readonly CITIES_CACHE_TTL = 60 * 60 * 1000;\n\n constructor(config: AymakanConfig) {\n super(config);\n this.http = new HttpClient({\n baseUrl: this.getBaseUrl(),\n carrier: \"aymakan\",\n headers: {\n Authorization: config.credentials.apiKey,\n },\n });\n }\n\n protected getBaseUrl(): string {\n return this.config.mode === \"production\"\n ? AYMAKAN_PRODUCTION_URL\n : AYMAKAN_SANDBOX_URL;\n }\n\n // =========================================================================\n // CITY RESOLUTION\n // =========================================================================\n\n /**\n * Load cities list from Aymakan API and cache it.\n * Silently falls back to empty list on failure so shipments can still be attempted.\n */\n private async ensureCitiesLoaded(): Promise<void> {\n if (\n this.citiesCache &&\n Date.now() - this.citiesCacheTime < AymakanAdapter.CITIES_CACHE_TTL\n ) {\n return;\n }\n try {\n this.citiesCache = await this.getCities();\n this.citiesCacheTime = Date.now();\n } catch {\n if (!this.citiesCache) this.citiesCache = [];\n }\n }\n\n /**\n * Normalize Arabic text for comparison:\n * - Strip diacritics (tashkeel)\n * - Normalize alef variants (أ إ آ → ا)\n * - Normalize taa marbuta (ة → ه)\n * - Trim whitespace\n */\n private static normalizeArabic(text: string): string {\n return text\n .trim()\n .replace(/[\\u064B-\\u065F\\u0670]/g, \"\") // strip tashkeel\n .replace(/[أإآ]/g, \"ا\") // normalize alef\n .replace(/ة/g, \"ه\"); // normalize taa marbuta\n }\n\n /**\n * Resolve a user-input city name to the valid Aymakan English city name.\n *\n * Matching strategy (first match wins):\n * 1. Exact match on English name (case-insensitive)\n * 2. Exact match on Arabic name\n * 3. Normalized Arabic match (handles tashkeel, alef variants, taa marbuta)\n * 4. Match after stripping \"ال\" prefix from Arabic input\n * 5. Substring/contains match on English name (case-insensitive)\n *\n * Falls back to the original input if no match is found.\n */\n private resolveCity(inputCity: string): string {\n if (!this.citiesCache || this.citiesCache.length === 0) return inputCity;\n\n const trimmed = inputCity.trim();\n if (!trimmed) return inputCity;\n const lower = trimmed.toLowerCase();\n\n // 1. Exact English match (case-insensitive)\n const exactEn = this.citiesCache.find(\n (c) => c.nameEn.toLowerCase() === lower,\n );\n if (exactEn) return exactEn.nameEn;\n\n // 2. Exact Arabic match\n const exactAr = this.citiesCache.find((c) => c.nameAr === trimmed);\n if (exactAr) return exactAr.nameEn;\n\n // 3. Normalized Arabic match\n const normalizedInput = AymakanAdapter.normalizeArabic(trimmed);\n const normalizedAr = this.citiesCache.find(\n (c) =>\n c.nameAr &&\n AymakanAdapter.normalizeArabic(c.nameAr) === normalizedInput,\n );\n if (normalizedAr) return normalizedAr.nameEn;\n\n // 4. Arabic without \"ال\" prefix\n const withoutAl = normalizedInput.startsWith(\"ال\")\n ? normalizedInput.slice(2)\n : `ال${normalizedInput}`;\n const alMatch = this.citiesCache.find(\n (c) => c.nameAr && AymakanAdapter.normalizeArabic(c.nameAr) === withoutAl,\n );\n if (alMatch) return alMatch.nameEn;\n\n // 5. Contains match on English name (for partial matches like \"Riyadh\" in \"Riyadh City\")\n const containsEn = this.citiesCache.find(\n (c) =>\n c.nameEn.toLowerCase().includes(lower) ||\n lower.includes(c.nameEn.toLowerCase()),\n );\n if (containsEn) return containsEn.nameEn;\n\n // No match — return as-is and let the API return a validation error\n return trimmed;\n }\n\n /**\n * Resolve city names in a CreateShipmentInput to valid Aymakan city names.\n */\n private resolveCitiesInInput(\n input: CreateShipmentInput,\n ): CreateShipmentInput {\n return {\n ...input,\n shipper: {\n ...input.shipper,\n city: this.resolveCity(input.shipper.city),\n },\n consignee: {\n ...input.consignee,\n city: this.resolveCity(input.consignee.city),\n },\n };\n }\n\n // =========================================================================\n // SHIPPING\n // =========================================================================\n\n protected async executeCreateShipment(\n input: CreateShipmentInput,\n ): Promise<Shipment> {\n await this.ensureCitiesLoaded();\n const resolved = this.resolveCitiesInInput(input);\n const request = mapCreateShipmentRequest(resolved);\n const response = await this.http.post<AymakanCreateShipmentResponse>(\n \"/shipping/create\",\n request,\n this.errorOpts,\n );\n\n if (!response.success) {\n throw new APIError(\"Failed to create shipment\", {\n carrier: \"aymakan\",\n raw: response,\n });\n }\n\n return mapShipmentResponse(response.shipping);\n }\n\n async createBulkShipments(\n inputs: CreateShipmentInput[],\n ): Promise<Shipment[]> {\n // Nothing to create — avoid an empty request to the carrier.\n if (inputs.length === 0) return [];\n // Aymakan rejects batches larger than 30 (\"Only 30 shipments can be\n // created at a time.\"), so fail fast with a clear error before the request.\n if (inputs.length > 30) {\n throw new ValidationError(\n \"Aymakan bulk create accepts at most 30 shipments per request\",\n { raw: { count: inputs.length } },\n );\n }\n inputs.forEach(validateCreateShipmentInput);\n await this.ensureCitiesLoaded();\n const requests = inputs\n .map((i) => this.resolveCitiesInInput(i))\n .map(mapCreateShipmentRequest);\n const response = await this.http.post<{\n success: boolean;\n message?: string;\n bulk_awb?: string;\n total_shipments?: number;\n shipments: AymakanCreateShipmentResponse[\"shipping\"][];\n }>(\"/shipping/create/bulk_shipping\", { shipments: requests }, this.errorOpts);\n\n if (!response.success) {\n throw new APIError(\"Failed to create bulk shipments\", {\n carrier: \"aymakan\",\n raw: response,\n });\n }\n\n if (!Array.isArray(response.shipments)) {\n throw new APIError(\n \"Aymakan bulk create response is missing the shipments array\",\n { carrier: \"aymakan\", raw: response },\n );\n }\n\n return response.shipments.map(mapShipmentResponse);\n }\n\n async cancelShipment(trackingNumber: string): Promise<boolean> {\n // The errorExtractor surfaces fake-200 error envelopes as APIError, so a\n // real failure throws with the carrier's message rather than silently\n // returning false.\n const response = await this.http.post<AymakanCancelResponse>(\n \"/shipping/cancel\",\n {\n tracking: trackingNumber,\n },\n this.errorOpts,\n );\n return response.success === true;\n }\n\n async cancelByReference(reference: string): Promise<boolean> {\n const response = await this.http.post<AymakanCancelResponse>(\n \"/shipping/cancel_by_reference\",\n { reference },\n this.errorOpts,\n );\n return response.success === true;\n }\n\n async updateDeliveryAddress(\n trackingNumber: string,\n address: Address,\n ): Promise<boolean> {\n await this.ensureCitiesLoaded();\n const resolvedCity = this.resolveCity(address.city);\n const response = await this.http.post<{ success: boolean }>(\n `/shipping/update_delivery_address/${encodeURIComponent(trackingNumber)}`,\n {\n delivery_name: address.name,\n delivery_email: address.email,\n delivery_city: resolvedCity,\n delivery_address: address.line1,\n delivery_neighbourhood: address.neighbourhood,\n delivery_postcode: address.postalCode,\n delivery_country: address.countryCode,\n delivery_phone: address.phone,\n },\n );\n return response.success;\n }\n\n // =========================================================================\n // TRACKING\n // =========================================================================\n\n async track(trackingNumber: string): Promise<TrackingResult> {\n const results = await this.trackMultiple([trackingNumber]);\n const result = results[0];\n if (!result) {\n throw new APIError(\"Shipment not found\", { carrier: \"aymakan\" });\n }\n return result;\n }\n\n async trackMultiple(trackingNumbers: string[]): Promise<TrackingResult[]> {\n const ids = trackingNumbers.map(encodeURIComponent).join(\",\");\n const response = await this.http.get<AymakanTrackResponse>(\n `/shipping/track/${ids}`,\n this.errorOpts,\n );\n\n if (!response.success) {\n throw new APIError(\"Failed to track shipments\", {\n carrier: \"aymakan\",\n raw: response,\n });\n }\n\n if (!Array.isArray(response.data?.shipments)) {\n throw new APIError(\"Aymakan track response is missing data.shipments\", {\n carrier: \"aymakan\",\n raw: response,\n });\n }\n\n return response.data.shipments.map(mapTrackingResult);\n }\n\n async trackByReference(reference: string): Promise<TrackingResult> {\n const response = await this.http.get<AymakanTrackResponse>(\n `/shipping/by_reference/${encodeURIComponent(reference)}`,\n this.errorOpts,\n );\n\n const shipment = response.data?.shipments?.[0];\n if (!response.success || !shipment) {\n throw new APIError(\"Shipment not found\", {\n carrier: \"aymakan\",\n raw: response,\n });\n }\n\n return mapTrackingResult(shipment);\n }\n\n // =========================================================================\n // LABELS\n // =========================================================================\n\n async getLabel(\n trackingNumber: string,\n _format?: \"PDF\" | \"ZPL\" | \"PNG\",\n ): Promise<string> {\n // Note: this endpoint always returns a single PDF download URL, so the\n // requested `format` cannot be honored.\n const response = await this.http.get<{\n success: boolean;\n error?: boolean;\n message?: string;\n response?: string;\n data: { awb_url: string };\n }>(\n `/shipping/awb/tracking/${encodeURIComponent(trackingNumber)}`,\n this.errorOpts,\n );\n\n if (!response.success || !response.data?.awb_url) {\n const msg = response.message ?? response.response ?? \"Failed to get label\";\n throw new APIError(msg, { carrier: \"aymakan\", raw: response });\n }\n\n return response.data.awb_url;\n }\n\n async getBulkLabels(trackingNumbers: string[]): Promise<string> {\n // Documented as a GET with comma-separated tracking numbers in the path.\n const ids = trackingNumbers.map(encodeURIComponent).join(\",\");\n const response = await this.http.get<{\n success: boolean;\n error?: boolean;\n message?: string;\n response?: string;\n data: { bulk_awb_url: string };\n }>(`/shipping/bulk_awb/trackings/${ids}`, this.errorOpts);\n\n if (!response.success || !response.data?.bulk_awb_url) {\n const msg =\n response.message ?? response.response ?? \"Failed to get bulk labels\";\n throw new APIError(msg, { carrier: \"aymakan\", raw: response });\n }\n\n return response.data.bulk_awb_url;\n }\n\n // =========================================================================\n // PICKUPS\n // =========================================================================\n\n async getPickupCities(): Promise<City[]> {\n const response = await this.http.get<AymakanCitiesResponse>(\n \"/pickup_request/cities\",\n this.errorOpts,\n );\n\n if (!response.success) {\n throw new APIError(\"Failed to get pickup cities\", {\n carrier: \"aymakan\",\n raw: response,\n });\n }\n\n return response.data.cities.map(mapCity);\n }\n\n async getTimeSlots(_city: string, date: string): Promise<TimeSlot[]> {\n const response = await this.http.get<{\n success: boolean;\n error?: boolean;\n message?: string;\n data: {\n date: string;\n slots: Record<string, string>;\n };\n }>(`/time_slots/${date}`);\n\n // Aymakan returns error responses for invalid dates (past, Fridays, etc.)\n if (!response.success || response.error || !response.data?.slots) {\n const msg = response.message ?? \"No slots available\";\n throw new APIError(msg, { carrier: \"aymakan\", raw: response });\n }\n\n // data.slots is an object like { \"afternoon\": \"After Noon (02 PM - 06 PM)\" }\n return Object.entries(response.data.slots).map(([id, label]) => ({\n id,\n label,\n }));\n }\n\n async createPickup(input: PickupRequest): Promise<Pickup> {\n validatePickupRequest(input);\n await this.ensureCitiesLoaded();\n const resolvedInput = { ...input, city: this.resolveCity(input.city) };\n const request = mapPickupRequest(resolvedInput);\n const response = await this.http.post<AymakanPickupResponse>(\n \"/pickup_request/create\",\n request,\n this.errorOpts,\n );\n\n if (!response.success) {\n throw new APIError(\"Failed to create pickup\", {\n carrier: \"aymakan\",\n raw: response,\n });\n }\n\n return mapPickupResponse(response.data);\n }\n\n async cancelPickup(pickupId: string | number): Promise<boolean> {\n const response = await this.http.post<{ success: boolean }>(\n \"/pickup_request/cancel\",\n { pickup_request: Number(pickupId) },\n this.errorOpts,\n );\n return response.success === true;\n }\n\n async getPickupRequests(): Promise<Pickup[]> {\n // The list endpoint returns a Laravel paginated structure:\n // { success, data: { pickupRequests: { data: [...] } } }\n const response = await this.http.get<{\n success: boolean;\n data: { pickupRequests: { data: AymakanPickupResponse[\"data\"][] } };\n }>(\"/pickup_request/list\", this.errorOpts);\n\n if (!response.success) {\n throw new APIError(\"Failed to get pickup requests\", {\n carrier: \"aymakan\",\n raw: response,\n });\n }\n\n const list = response.data?.pickupRequests?.data;\n if (!Array.isArray(list)) {\n throw new APIError(\n \"Aymakan pickup list response is missing data.pickupRequests.data\",\n { carrier: \"aymakan\", raw: response },\n );\n }\n\n return list.map(mapPickupResponse);\n }\n\n // =========================================================================\n // CITIES & LOCATIONS\n // =========================================================================\n\n async getCities(): Promise<City[]> {\n const response = await this.http.get<AymakanCitiesResponse>(\"/cities\");\n\n if (!response.success) {\n throw new APIError(\"Failed to get cities\", {\n carrier: \"aymakan\",\n raw: response,\n });\n }\n\n return response.data.cities.map(mapCity);\n }\n\n async getDropoffLocations(): Promise<\n {\n id: string;\n name: string;\n address?: string;\n city?: string;\n latitude?: number;\n longitude?: number;\n }[]\n > {\n // The API returns `data` as a flat array of warehouse objects. There is no\n // `id` field — the warehouse code lives in `name` (e.g. \"RUH-WH\").\n const response = await this.http.get<{\n success: boolean;\n data: Array<{\n name: string;\n city?: string;\n address?: string;\n manager?: string;\n mobile_phone?: string;\n email?: string;\n location_lat?: number | null;\n location_lng?: number | null;\n }>;\n }>(\"/dropoff_locations\");\n\n if (!response.success) {\n throw new APIError(\"Failed to get dropoff locations\", {\n carrier: \"aymakan\",\n raw: response,\n });\n }\n\n return response.data.map((loc) => ({\n id: loc.name,\n name: loc.name,\n address: loc.address,\n city: loc.city,\n latitude: loc.location_lat ?? undefined,\n longitude: loc.location_lng ?? undefined,\n }));\n }\n\n // =========================================================================\n // CUSTOMER ADDRESSES\n // =========================================================================\n\n async createCustomerAddress(\n address: CustomerAddress,\n ): Promise<CustomerAddress> {\n const request = mapCustomerAddressRequest(address);\n const response = await this.http.post<AymakanAddressResponse>(\n \"/address/create\",\n request,\n this.errorOpts,\n );\n\n if (!response.success || !response.data?.address) {\n throw new APIError(\"Failed to create address\", {\n carrier: \"aymakan\",\n raw: response,\n });\n }\n\n const addr = response.data.address;\n return {\n id: addr.id,\n title: addr.title,\n name: addr.name,\n email: addr.email,\n phone: addr.phone,\n city: addr.city,\n address: addr.address,\n neighbourhood: addr.neighbourhood,\n postalCode: addr.postcode,\n countryCode: addr.country,\n description: addr.description,\n };\n }\n\n async getCustomerAddresses(): Promise<CustomerAddress[]> {\n const response = await this.http.get<{\n success: boolean;\n data: { address: AymakanAddressResponse[\"data\"][\"address\"][] };\n }>(\"/address/list\", this.errorOpts);\n\n if (!response.success) {\n throw new APIError(\"Failed to get customer addresses\", {\n carrier: \"aymakan\",\n raw: response,\n });\n }\n\n if (!Array.isArray(response.data?.address)) {\n throw new APIError(\n \"Aymakan address list response is missing data.address\",\n { carrier: \"aymakan\", raw: response },\n );\n }\n\n return response.data.address.map((addr) => ({\n id: addr.id,\n title: addr.title,\n name: addr.name,\n email: addr.email,\n phone: addr.phone,\n city: addr.city,\n address: addr.address,\n neighbourhood: addr.neighbourhood,\n postalCode: addr.postcode,\n countryCode: addr.country,\n description: addr.description,\n }));\n }\n\n async updateCustomerAddress(\n id: number,\n address: Partial<CustomerAddress>,\n ): Promise<CustomerAddress> {\n const response = await this.http.put<AymakanAddressResponse>(\n \"/address/update\",\n {\n id,\n title: address.title,\n name: address.name,\n email: address.email,\n city: address.city,\n address: address.address,\n neighbourhood: address.neighbourhood,\n postcode: address.postalCode,\n phone: address.phone,\n description: address.description,\n },\n this.errorOpts,\n );\n\n if (!response.success || !response.data?.address) {\n throw new APIError(\"Failed to update address\", {\n carrier: \"aymakan\",\n raw: response,\n });\n }\n\n const addr = response.data.address;\n return {\n id: addr.id,\n title: addr.title,\n name: addr.name,\n email: addr.email,\n phone: addr.phone,\n city: addr.city,\n address: addr.address,\n neighbourhood: addr.neighbourhood,\n postalCode: addr.postcode,\n countryCode: addr.country,\n description: addr.description,\n };\n }\n\n async deleteCustomerAddress(id: number): Promise<boolean> {\n // The id must be sent in the JSON request body, not the URL path.\n const response = await this.http.delete<{ success: boolean }>(\n \"/address/delete\",\n { body: { id }, errorExtractor: aymakanErrorExtractor },\n );\n return response.success;\n }\n\n // =========================================================================\n // WEBHOOKS\n // =========================================================================\n\n parseWebhook(\n payload: unknown,\n options?: {\n headers?: Record<string, string>;\n queryParams?: Record<string, string>;\n config?: WebhookConfig;\n },\n ): WebhookEvent {\n return parseAymakanWebhook(payload, options);\n }\n\n // =========================================================================\n // NOT SUPPORTED\n // =========================================================================\n\n getRates(): Promise<never> {\n throw new UnsupportedOperationError(\"aymakan\", \"getRates\");\n }\n}\n"
6
+ "// file: src/carriers/aymakan/mappers.ts\n/**\n * Aymakan Data Mappers\n * Transform between unified ShipFlow types and Aymakan API formats.\n */\n\nimport { ValidationError, WebhookVerificationError } from \"../../core/errors\";\nimport type {\n Address,\n City,\n CreateShipmentInput,\n CustomerAddress,\n Pickup,\n PickupRequest,\n Shipment,\n ShipmentStatus,\n TrackingEvent,\n TrackingResult,\n WebhookConfig,\n WebhookEvent,\n} from \"../../core/types\";\nimport { AymakanService, AymakanStatusCodes } from \"./services\";\nimport type {\n AymakanAddressRequest,\n AymakanCity,\n AymakanCreateShipmentRequest,\n AymakanNationalAddressRequest,\n AymakanPickupRequest,\n AymakanPickupResponse,\n AymakanShipmentResponse,\n AymakanTrackingEvent,\n AymakanTrackShipmentData,\n AymakanWebhookPayload,\n} from \"./types\";\n\n// ============================================================================\n// STATUS MAPPING\n// ============================================================================\n\nexport function mapAymakanStatus(statusCode: string): ShipmentStatus | undefined {\n const mapped =\n AymakanStatusCodes[statusCode as keyof typeof AymakanStatusCodes];\n return mapped as ShipmentStatus | undefined;\n}\n\n/**\n * The /track endpoint's top-level `status` is a human-readable English label\n * (e.g. \"Received at Warehouse\") rather than an AY code, so `mapAymakanStatus`\n * can never resolve it. This map recovers a real unified status from that label\n * when there are no tracking events to derive it from. Keys are compared\n * case-insensitively.\n */\nconst AymakanStatusLabels: Record<string, ShipmentStatus> = {\n \"awb created at origin\": \"created\",\n \"shipment created\": \"created\",\n \"collected from collection point\": \"picked_up\",\n collected: \"picked_up\",\n \"picked up\": \"picked_up\",\n \"received at hub\": \"at_warehouse\",\n \"received at warehouse\": \"at_warehouse\",\n \"out for delivery\": \"out_for_delivery\",\n \"out for final destination\": \"out_for_delivery\",\n delivered: \"delivered\",\n \"shipment is delivered\": \"delivered\",\n \"transferred to destination city\": \"in_transit\",\n \"in transit\": \"in_transit\",\n \"not delivered\": \"exception\",\n \"failed attempt\": \"exception\",\n pending: \"pending\",\n \"future delivery\": \"pending\",\n returned: \"returned\",\n \"returned to shipper\": \"returned\",\n \"return to origin\": \"returned\",\n cancelled: \"cancelled\",\n canceled: \"cancelled\",\n};\n\n/**\n * Map a human-readable Aymakan status label to a unified status.\n * Returns undefined for unrecognized labels.\n */\nexport function mapAymakanStatusLabel(\n label: string,\n): ShipmentStatus | undefined {\n return AymakanStatusLabels[label.trim().toLowerCase()];\n}\n\n// ============================================================================\n// REQUEST MAPPERS\n// ============================================================================\n\nfunction mapNationalAddress(\n addr?: Address[\"nationalAddress\"],\n): AymakanNationalAddressRequest | undefined {\n if (!addr) return undefined;\n return {\n short_code: addr.shortCode,\n building_number: addr.buildingNumber,\n street_name: addr.streetName,\n district: addr.district,\n additional_number: addr.additionalNumber,\n };\n}\n\n/** Strip non-digit characters from phone numbers (Aymakan requires digits only) */\nexport function sanitizePhone(phone: string): string {\n return phone.replace(/\\D/g, '');\n}\n\n/** Set of valid Aymakan service type codes */\nconst VALID_AYMAKAN_SERVICE_TYPES = new Set(\n Object.values(AymakanService) as string[],\n);\n\n/**\n * Resolve service type to a valid Aymakan code.\n * Returns undefined for unknown values so the API uses its default (ONP/ecommerce).\n */\nfunction resolveServiceType(serviceType?: string): string | undefined {\n if (!serviceType) return undefined;\n if (VALID_AYMAKAN_SERVICE_TYPES.has(serviceType)) return serviceType;\n return undefined;\n}\n\nexport function mapCreateShipmentRequest(\n input: CreateShipmentInput,\n): AymakanCreateShipmentRequest {\n const firstParcel = input.parcels[0];\n const totalPieces = input.parcels.reduce((sum, p) => sum + p.pieces, 0);\n const totalWeight = input.parcels.reduce(\n (sum, p) =>\n sum +\n (p.weight.unit === \"lb\" ? p.weight.value * 0.453592 : p.weight.value),\n 0,\n );\n const totalItems = input.parcels.reduce(\n (sum, p) => sum + (p.itemsCount ?? p.pieces),\n 0,\n );\n\n // COD (collected from the buyer on delivery) and declared/customs value are\n // distinct concepts and must never be conflated. Declared value comes solely\n // from input.declaredValue; COD comes solely from input.cod.\n const codEnabled = input.cod?.enabled === true;\n const declaredValueCurrency = input.declaredValue?.currency ?? \"SAR\";\n\n return {\n requested_by: input.options?.requestedBy ?? input.shipper.name,\n declared_value: input.declaredValue?.amount ?? 0,\n declared_value_currency: declaredValueCurrency,\n reference: input.reference,\n customer_tracking: input.options?.customerTracking,\n service_type: resolveServiceType(input.serviceType),\n is_cod: codEnabled ? 1 : 0,\n cod_amount: codEnabled ? input.cod?.amount : undefined,\n fulfilment_customer_name: input.options?.fulfilmentCustomerName,\n // Top-level currency prefers the COD currency when COD is enabled (it's the\n // amount actually collected), otherwise the declared-value currency.\n currency: codEnabled\n ? (input.cod?.currency ?? \"SAR\")\n : declaredValueCurrency,\n\n // Delivery (consignee)\n delivery_name: input.consignee.name,\n delivery_email: input.consignee.email,\n delivery_city: input.consignee.city,\n delivery_address: input.consignee.line1,\n delivery_neighbourhood:\n input.consignee.neighbourhood ?? input.consignee.state,\n delivery_postcode: input.consignee.postalCode,\n delivery_country: input.consignee.countryCode,\n delivery_phone: sanitizePhone(input.consignee.phone),\n delivery_description: input.consignee.description,\n delivery_national_address: mapNationalAddress(\n input.consignee.nationalAddress,\n ),\n\n // Collection (shipper)\n collection_name: input.shipper.company ?? input.shipper.name,\n collection_email: input.shipper.email,\n collection_city: input.shipper.city,\n collection_address: input.shipper.line1,\n collection_neighbourhood:\n input.shipper.neighbourhood ?? input.shipper.state,\n collection_postcode: input.shipper.postalCode,\n collection_country: input.shipper.countryCode,\n collection_phone: sanitizePhone(input.shipper.phone),\n collection_description: input.shipper.description,\n collection_national_address: mapNationalAddress(\n input.shipper.nationalAddress,\n ),\n\n // Parcel details\n weight: totalWeight,\n length: firstParcel?.dimensions?.length,\n width: firstParcel?.dimensions?.width,\n height: firstParcel?.dimensions?.height,\n pieces: totalPieces,\n items_count: totalItems,\n is_insured: input.options?.isInsured ? 1 : 0,\n\n // International\n international_metadata: input.options?.internationalMetadata\n ? {\n document_id: input.options.internationalMetadata.documentId,\n tax_identification_number: input.options.internationalMetadata.taxId,\n invoice_number: input.options.internationalMetadata.invoiceNumber,\n invoice_date: input.options.internationalMetadata.invoiceDate,\n }\n : undefined,\n };\n}\n\nexport function mapPickupRequest(input: PickupRequest): AymakanPickupRequest {\n return {\n reference: input.trackingNumbers?.[0],\n pickup_date: input.date,\n time_slot: input.timeSlot,\n city: input.city,\n contact_name: input.contactName,\n contact_phone: input.contactPhone,\n address: input.address,\n shipments: input.shipmentCount,\n };\n}\n\nexport function mapCustomerAddressRequest(\n addr: CustomerAddress,\n): AymakanAddressRequest {\n return {\n title: addr.title,\n name: addr.name,\n email: addr.email,\n city: addr.city,\n address: addr.address,\n neighbourhood: addr.neighbourhood,\n postcode: addr.postalCode ?? \"\",\n phone: addr.phone,\n description: addr.description ?? \"\",\n };\n}\n\n// ============================================================================\n// RESPONSE MAPPERS\n// ============================================================================\n\nexport function mapShipmentResponse(data: AymakanShipmentResponse): Shipment {\n // Parse cod_amount: API returns string like \"150.00\", we need number\n const codAmount =\n data.cod_amount != null\n ? typeof data.cod_amount === \"string\"\n ? parseFloat(data.cod_amount)\n : data.cod_amount\n : undefined;\n\n return {\n carrier: \"aymakan\",\n trackingNumber: data.tracking_number,\n customerTracking: data.customer_tracking ?? undefined,\n reference: data.reference ?? undefined,\n status: mapAymakanStatus(data.status) ?? \"created\",\n statusLabel: data.status_label,\n labelUrl: data.label || undefined,\n pdfLabelUrl: data.pdf_label || undefined,\n // Emit a defined COD amount whenever we parsed a real number. A COD of 0\n // means \"no cash collected\", so surface it as undefined, but never let NaN\n // logic on a falsy 0 drop an otherwise valid value.\n codAmount:\n codAmount != null && !Number.isNaN(codAmount) && codAmount !== 0\n ? codAmount\n : undefined,\n declaredValue: data.declared_value,\n currency: data.currency,\n createdAt: new Date(data.created_at),\n raw: data,\n };\n}\n\n/**\n * Parse an Aymakan timestamp. Top-level fields are ISO 8601 (with `T`/`Z`), but\n * `tracking_info[].created_at` values are space-separated \"YYYY-MM-DD HH:MM:SS\"\n * strings in Saudi local time (UTC+3) with no timezone marker. `new Date()`\n * would parse those in the host's local timezone, so normalize to +03:00.\n */\nfunction parseAymakanDate(value: string): Date {\n if (/[TZ]|[+-]\\d{2}:?\\d{2}$/.test(value)) {\n return new Date(value);\n }\n return new Date(`${value.replace(\" \", \"T\")}+03:00`);\n}\n\nexport function mapTrackingEvent(event: AymakanTrackingEvent): TrackingEvent {\n return {\n timestamp: parseAymakanDate(event.created_at),\n statusCode: event.status_code,\n status: mapAymakanStatus(event.status_code) ?? \"unknown\",\n description: event.description,\n descriptionArabic: event.description_ar ?? undefined,\n };\n}\n\nexport function mapTrackingResult(\n data: AymakanTrackShipmentData,\n): TrackingResult {\n const events = (data.tracking_info ?? []).map(mapTrackingEvent);\n\n // The top-level `status` field is a human-readable label on the /track\n // endpoint (e.g. \"Received at Warehouse\") and an AY code on /by_reference.\n // Derive the unified status from the most recent tracking event (whose\n // status_code is always an AY code), falling back to mapping the top-level\n // status. The fallback tries the AY-code map first (handles /by_reference)\n // and then the human-label map (handles /track), so a real state is recovered\n // even when there are no events, then \"unknown\".\n const sortedEvents = events.length\n ? [...events].sort((a, b) => b.timestamp.getTime() - a.timestamp.getTime())\n : [];\n // Some event codes aren't in AymakanStatusCodes and map to \"unknown\" — scan\n // back through older events (newest-first) for the most recent one we can\n // actually recognize, instead of giving up as soon as the latest is unknown.\n const mostRecentRecognizedEvent = sortedEvents.find(\n (e) => e.status !== \"unknown\",\n );\n let status: ShipmentStatus;\n if (mostRecentRecognizedEvent) {\n status = mostRecentRecognizedEvent.status;\n } else {\n // No recognizable event (or none at all) — derive from the top-level\n // status: AY-code map first (/by_reference), then human-label map (/track),\n // else \"unknown\".\n status =\n mapAymakanStatus(data.status) ??\n mapAymakanStatusLabel(data.status) ??\n \"unknown\";\n }\n\n return {\n trackingNumber: data.tracking_number,\n carrier: \"aymakan\",\n reference: data.reference ?? undefined,\n status,\n statusLabel: data.status_label,\n events,\n deliveryDate: data.delivery_date ? new Date(data.delivery_date) : undefined,\n pickupDate: data.pickup_date ? new Date(data.pickup_date) : undefined,\n receivedAt: data.received_at ? new Date(data.received_at) : undefined,\n codAmount: data.cod_amount\n ? Number.isNaN(parseFloat(data.cod_amount))\n ? undefined\n : parseFloat(data.cod_amount)\n : undefined,\n weight: Number.isNaN(parseFloat(data.weight))\n ? undefined\n : parseFloat(data.weight),\n pieces: data.pieces,\n raw: data,\n };\n}\n\nexport function mapCity(city: AymakanCity): City {\n return {\n nameEn: city.city_en,\n nameAr: city.city_ar,\n };\n}\n\nexport function mapPickupResponse(data: AymakanPickupResponse[\"data\"]): Pickup {\n return {\n id: data.id,\n carrier: \"aymakan\",\n status: (\n [\"pending\", \"processing\", \"completed\", \"cancelled\"] as const\n ).includes(data.status as Pickup[\"status\"])\n ? (data.status as Pickup[\"status\"])\n : \"pending\",\n date: data.pickup_date,\n timeSlot: data.time_slot,\n city: data.city,\n contactName: data.contact_name,\n contactPhone: data.contact_phone,\n address: data.address,\n shipmentCount: data.shipments,\n warehouseId: data.warehouse_id,\n warehouseName: data.warehouse_name,\n createdAt: new Date(data.created_at),\n raw: data,\n };\n}\n\n// ============================================================================\n// WEBHOOK MAPPER\n// ============================================================================\n\n/**\n * Timing-safe string comparison to prevent timing attacks on auth tokens.\n */\nfunction timingSafeEqual(a: string, b: string): boolean {\n const encoder = new TextEncoder();\n const bufA = encoder.encode(a);\n const bufB = encoder.encode(b);\n if (bufA.byteLength !== bufB.byteLength) return false;\n // Use crypto.subtle-compatible constant-time compare\n let mismatch = 0;\n for (let i = 0; i < bufA.byteLength; i++) {\n mismatch |= bufA[i]! ^ bufB[i]!;\n }\n return mismatch === 0;\n}\n\nexport function parseAymakanWebhook(\n payload: unknown,\n options?: {\n headers?: Record<string, string>;\n queryParams?: Record<string, string>;\n config?: WebhookConfig;\n },\n): WebhookEvent {\n const { headers = {}, queryParams = {}, config } = options ?? {};\n\n // Verify auth FIRST, before inspecting the payload shape. These checks depend\n // only on `options` (headers/queryParams/config), so an unauthenticated caller\n // is rejected before any payload-validation detail can leak back to them.\n\n // Verify auth via header (case-insensitive lookup, timing-safe comparison)\n if (config?.authHeader && config?.authValue) {\n const lowerKey = config.authHeader.toLowerCase();\n const headerValue = Object.entries(headers).find(\n ([k]) => k.toLowerCase() === lowerKey,\n )?.[1];\n if (!headerValue || !timingSafeEqual(headerValue, config.authValue)) {\n throw new WebhookVerificationError(\"Invalid webhook auth header\", {\n carrier: \"aymakan\",\n });\n }\n }\n\n // Verify auth via query param (timing-safe comparison)\n if (config?.authQueryParam && config?.authQueryValue) {\n const paramValue = queryParams[config.authQueryParam];\n if (!paramValue || !timingSafeEqual(paramValue, config.authQueryValue)) {\n throw new WebhookVerificationError(\"Invalid webhook auth query param\", {\n carrier: \"aymakan\",\n });\n }\n }\n\n // Validate required fields (only after auth has passed)\n if (\n !payload ||\n typeof payload !== \"object\" ||\n !(\"tracking_number\" in payload) ||\n !(\"status\" in payload)\n ) {\n throw new ValidationError(\n \"Invalid webhook payload: missing required fields\",\n {\n raw: payload,\n },\n );\n }\n\n const data = payload as AymakanWebhookPayload;\n\n const eventType = data.event ?? \"status_update\";\n\n // Validate timestamp\n const timestamp = new Date(data.date_time);\n if (Number.isNaN(timestamp.getTime())) {\n throw new ValidationError(\n \"Invalid webhook payload: invalid date_time value\",\n { raw: data.date_time },\n );\n }\n\n return {\n carrier: \"aymakan\",\n eventType,\n trackingNumber: data.tracking_number,\n reference: data.reference ?? undefined,\n // `status` is a core field present on every webhook regardless of event\n // type, so map it even for weight_update events. Consumers can still branch\n // on `eventType` to detect weight updates.\n status: mapAymakanStatus(data.status) ?? \"unknown\",\n statusCode: data.status,\n statusLabel: data.status_label,\n reasonCode: data.reason_code ?? undefined,\n reasonLabel: data.reason_en ?? undefined,\n timestamp,\n raw: data,\n };\n}\n",
7
+ "// file: src/carriers/aymakan/adapter.ts\n/**\n * Aymakan Carrier Adapter\n * Full implementation of the CarrierAdapter interface for Aymakan API.\n */\n\nimport { APIError, ValidationError } from \"../../core/errors\";\nimport { HttpClient } from \"../../core/http\";\nimport {\n validateCreateShipmentInput,\n validatePickupRequest,\n} from \"../../core/schemas\";\nimport type {\n Address,\n CarrierConfig,\n City,\n CreateShipmentInput,\n CustomerAddress,\n Pickup,\n PickupRequest,\n Shipment,\n TimeSlot,\n TrackingResult,\n WebhookConfig,\n WebhookEvent,\n} from \"../../core/types\";\nimport { BaseCarrierAdapter } from \"../base\";\nimport {\n mapCity,\n mapCreateShipmentRequest,\n mapCustomerAddressRequest,\n mapPickupRequest,\n mapPickupResponse,\n mapShipmentResponse,\n mapTrackingResult,\n parseAymakanWebhook,\n sanitizePhone,\n} from \"./mappers\";\nimport type {\n AymakanAddressResponse,\n AymakanCancelResponse,\n AymakanCitiesResponse,\n AymakanCreateShipmentResponse,\n AymakanPickupResponse,\n AymakanShipmentResponse,\n AymakanTrackResponse,\n} from \"./types\";\n\nconst AYMAKAN_SANDBOX_URL = \"https://dev-api.aymakan.com.sa/v2\";\nconst AYMAKAN_PRODUCTION_URL = \"https://api.aymakan.net/v2\";\n\n/**\n * Aymakan returns logical errors inside a fake-200 envelope (HTTP 200 with an\n * error flag/message in the body). Without an extractor these are swallowed —\n * e.g. cancel endpoints would return `success: undefined` and the adapter would\n * report `false` with no reason. This extractor surfaces those as APIError.\n *\n * Recognised error shapes (all on a 200 body):\n * - `{ error: true, ... }` → Laravel/Aymakan error flag\n * - `{ success: false, ... }` → explicit failure flag\n * - `{ message }` / `{ response }` → human-readable error text\n * - `{ errors: { field: [...] } }` → Laravel field validation errors\n *\n * A bare `{ message }` is NOT treated as an error on its own (many success\n * envelopes carry a `message`); we only flag when `error`/`success:false` is\n * present, or validation `errors` exist.\n */\n/**\n * Pull a human-readable message out of an object-shaped error value, e.g.\n * `{ error: { message: \"...\" } }` or `{ error: { response: \"...\" } }`.\n */\nfunction extractNestedMessage(value: unknown): string | undefined {\n if (typeof value === \"string\") return value;\n if (value && typeof value === \"object\") {\n const obj = value as Record<string, unknown>;\n if (typeof obj.message === \"string\") return obj.message;\n if (typeof obj.response === \"string\") return obj.response;\n }\n return undefined;\n}\n\n/** Join Laravel-style `{ field: [msg, ...] }` validation errors into one string. */\nfunction joinFieldErrors(errors: Record<string, unknown>): string | undefined {\n const parts = Object.values(errors)\n .flat()\n .filter((v): v is string => typeof v === \"string\");\n return parts.length ? parts.join(\"; \") : undefined;\n}\n\nfunction aymakanErrorExtractor(json: unknown): {\n hasError: boolean;\n message?: string;\n errors?: Record<string, string[]>;\n} {\n if (!json || typeof json !== \"object\") {\n return { hasError: false };\n }\n const obj = json as Record<string, unknown>;\n\n const hasValidationErrors =\n !!obj.errors &&\n typeof obj.errors === \"object\" &&\n Object.keys(obj.errors as object).length > 0;\n const hasError = obj.error === true || obj.success === false || hasValidationErrors;\n\n if (!hasError) {\n return { hasError: false };\n }\n\n const message =\n (typeof obj.message === \"string\" && obj.message) ||\n (typeof obj.response === \"string\" && obj.response) ||\n (typeof obj.error === \"string\" && obj.error) ||\n extractNestedMessage(obj.error) ||\n (hasValidationErrors\n ? joinFieldErrors(obj.errors as Record<string, string[]>)\n : undefined) ||\n undefined;\n\n return {\n hasError: true,\n message,\n errors: hasValidationErrors\n ? (obj.errors as Record<string, string[]>)\n : undefined,\n };\n}\n\nexport interface AymakanConfig extends CarrierConfig {\n credentials: {\n apiKey: string;\n };\n}\n\nexport class AymakanAdapter extends BaseCarrierAdapter {\n readonly name = \"aymakan\";\n readonly supportedCountries = [\"SA\", \"AE\", \"BH\", \"KW\", \"OM\", \"QA\"];\n\n private http: HttpClient;\n\n /**\n * Shared options applied to every Aymakan http call so fake-200 error\n * envelopes surface as APIError instead of being silently swallowed.\n */\n private readonly errorOpts = { errorExtractor: aymakanErrorExtractor };\n\n /** Cached Aymakan cities list for city name resolution */\n private citiesCache: City[] | null = null;\n private citiesCacheTime = 0;\n /** Timestamp of the last failed /cities fetch attempt, if any */\n private citiesFetchFailedAt = 0;\n /** Cache TTL: 1 hour */\n private static readonly CITIES_CACHE_TTL = 60 * 60 * 1000;\n /**\n * After a failed /cities fetch, back off for this long before retrying so a\n * carrier outage doesn't force every shipment/pickup call to re-attempt the\n * multi-retry /cities request.\n */\n private static readonly CITIES_FAILURE_COOLDOWN = 60 * 1000;\n\n constructor(config: AymakanConfig) {\n super(config);\n this.http = new HttpClient({\n baseUrl: this.getBaseUrl(),\n carrier: \"aymakan\",\n headers: {\n Authorization: config.credentials.apiKey,\n },\n });\n }\n\n protected getBaseUrl(): string {\n return this.config.mode === \"production\"\n ? AYMAKAN_PRODUCTION_URL\n : AYMAKAN_SANDBOX_URL;\n }\n\n // =========================================================================\n // CITY RESOLUTION\n // =========================================================================\n\n /**\n * Load cities list from Aymakan API and cache it.\n * Silently falls back to empty list on failure so shipments can still be attempted.\n */\n private async ensureCitiesLoaded(): Promise<void> {\n const now = Date.now();\n if (\n this.citiesCache &&\n now - this.citiesCacheTime < AymakanAdapter.CITIES_CACHE_TTL\n ) {\n return;\n }\n // A recent failure is still in its cooldown window — skip re-attempting\n // the /cities fetch and fall back to whatever cache we have (possibly\n // empty), so an outage never hard-blocks shipment/pickup creation.\n if (now - this.citiesFetchFailedAt < AymakanAdapter.CITIES_FAILURE_COOLDOWN) {\n if (!this.citiesCache) this.citiesCache = [];\n return;\n }\n try {\n this.citiesCache = await this.getCities();\n this.citiesCacheTime = now;\n } catch {\n this.citiesFetchFailedAt = now;\n if (!this.citiesCache) this.citiesCache = [];\n }\n }\n\n /**\n * Normalize Arabic text for comparison:\n * - Strip diacritics (tashkeel)\n * - Normalize alef variants (أ إ آ → ا)\n * - Normalize taa marbuta (ة → ه)\n * - Trim whitespace\n */\n private static normalizeArabic(text: string): string {\n return text\n .trim()\n .replace(/[\\u064B-\\u065F\\u0670]/g, \"\") // strip tashkeel\n .replace(/[أإآ]/g, \"ا\") // normalize alef\n .replace(/ة/g, \"ه\"); // normalize taa marbuta\n }\n\n /**\n * Resolve a user-input city name to the valid Aymakan English city name.\n *\n * Matching strategy (first match wins):\n * 1. Exact match on English name (case-insensitive)\n * 2. Exact match on Arabic name\n * 3. Normalized Arabic match (handles tashkeel, alef variants, taa marbuta)\n * 4. Match after stripping \"ال\" prefix from Arabic input\n * 5. Candidate-contains-input match on English name (candidate name contains\n * the input, e.g. \"Riyadh\" -> \"Riyadh City\"; requires input length >= 3).\n * The reverse direction is intentionally excluded so a distinct longer\n * city like \"Riyadh Al Khabra\" is never rerouted to \"Riyadh\".\n *\n * Falls back to the original input if no match is found.\n */\n private resolveCity(inputCity: string): string {\n if (!this.citiesCache || this.citiesCache.length === 0) return inputCity;\n\n const trimmed = inputCity.trim();\n if (!trimmed) return inputCity;\n const lower = trimmed.toLowerCase();\n\n // 1. Exact English match (case-insensitive)\n const exactEn = this.citiesCache.find(\n (c) => c.nameEn.toLowerCase() === lower,\n );\n if (exactEn) return exactEn.nameEn;\n\n // 2. Exact Arabic match\n const exactAr = this.citiesCache.find((c) => c.nameAr === trimmed);\n if (exactAr) return exactAr.nameEn;\n\n // 3. Normalized Arabic match\n const normalizedInput = AymakanAdapter.normalizeArabic(trimmed);\n const normalizedAr = this.citiesCache.find(\n (c) =>\n c.nameAr &&\n AymakanAdapter.normalizeArabic(c.nameAr) === normalizedInput,\n );\n if (normalizedAr) return normalizedAr.nameEn;\n\n // 4. Arabic without \"ال\" prefix\n const withoutAl = normalizedInput.startsWith(\"ال\")\n ? normalizedInput.slice(2)\n : `ال${normalizedInput}`;\n const alMatch = this.citiesCache.find(\n (c) => c.nameAr && AymakanAdapter.normalizeArabic(c.nameAr) === withoutAl,\n );\n if (alMatch) return alMatch.nameEn;\n\n // 5. Candidate-contains-input match on English name (e.g. input \"Riyadh\"\n // resolves to the canonical \"Riyadh City\"). We deliberately match ONLY\n // this direction. The reverse direction (input contains a candidate's\n // name) is excluded because a longer, distinct city such as\n // \"Riyadh Al Khabra\" would otherwise be silently rerouted to \"Riyadh\".\n // Guarded by a minimum input length so very short inputs (1-2 chars)\n // don't spuriously substring-match many candidates.\n if (lower.length >= 3) {\n const containsEn = this.citiesCache.find((c) =>\n c.nameEn.toLowerCase().includes(lower),\n );\n if (containsEn) return containsEn.nameEn;\n }\n\n // No match — return as-is and let the API return a validation error\n return trimmed;\n }\n\n /**\n * Resolve city names in a CreateShipmentInput to valid Aymakan city names.\n */\n private resolveCitiesInInput(\n input: CreateShipmentInput,\n ): CreateShipmentInput {\n return {\n ...input,\n shipper: {\n ...input.shipper,\n city: this.resolveCity(input.shipper.city),\n },\n consignee: {\n ...input.consignee,\n city: this.resolveCity(input.consignee.city),\n },\n };\n }\n\n // =========================================================================\n // SHIPPING\n // =========================================================================\n\n protected async executeCreateShipment(\n input: CreateShipmentInput,\n ): Promise<Shipment> {\n await this.ensureCitiesLoaded();\n const resolved = this.resolveCitiesInInput(input);\n const request = mapCreateShipmentRequest(resolved);\n const response = await this.http.post<AymakanCreateShipmentResponse>(\n \"/shipping/create\",\n request,\n this.errorOpts,\n );\n\n if (!response.success) {\n throw new APIError(\"Failed to create shipment\", {\n carrier: \"aymakan\",\n raw: response,\n });\n }\n\n return mapShipmentResponse(response.shipping);\n }\n\n async createBulkShipments(\n inputs: CreateShipmentInput[],\n ): Promise<Shipment[]> {\n // Nothing to create — avoid an empty request to the carrier.\n if (inputs.length === 0) return [];\n // Aymakan rejects batches larger than 30 (\"Only 30 shipments can be\n // created at a time.\"), so fail fast with a clear error before the request.\n if (inputs.length > 30) {\n throw new ValidationError(\n \"Aymakan bulk create accepts at most 30 shipments per request\",\n { raw: { count: inputs.length } },\n );\n }\n inputs.forEach(validateCreateShipmentInput);\n await this.ensureCitiesLoaded();\n const requests = inputs\n .map((i) => this.resolveCitiesInInput(i))\n .map(mapCreateShipmentRequest);\n const response = await this.http.post<{\n success: boolean;\n message?: string;\n bulk_awb?: string;\n total_shipments?: number;\n shipments: AymakanCreateShipmentResponse[\"shipping\"][];\n }>(\"/shipping/create/bulk_shipping\", { shipments: requests }, this.errorOpts);\n\n if (!response.success) {\n throw new APIError(\"Failed to create bulk shipments\", {\n carrier: \"aymakan\",\n raw: response,\n });\n }\n\n if (!Array.isArray(response.shipments)) {\n throw new APIError(\n \"Aymakan bulk create response is missing the shipments array\",\n { carrier: \"aymakan\", raw: response },\n );\n }\n\n return response.shipments.map(mapShipmentResponse);\n }\n\n async cancelShipment(trackingNumber: string): Promise<boolean> {\n // The errorExtractor surfaces fake-200 error envelopes as APIError, so a\n // real failure throws with the carrier's message rather than silently\n // returning false.\n const response = await this.http.post<AymakanCancelResponse>(\n \"/shipping/cancel\",\n {\n tracking: trackingNumber,\n },\n this.errorOpts,\n );\n return response.success === true;\n }\n\n async cancelByReference(reference: string): Promise<boolean> {\n const response = await this.http.post<AymakanCancelResponse>(\n \"/shipping/cancel_by_reference\",\n { reference },\n this.errorOpts,\n );\n return response.success === true;\n }\n\n async updateDeliveryAddress(\n trackingNumber: string,\n address: Address,\n ): Promise<boolean> {\n await this.ensureCitiesLoaded();\n const resolvedCity = this.resolveCity(address.city);\n // Documented endpoint: POST /shipping/update/delivery_address with the\n // tracking number as a `tracking` field in the JSON body (NOT in the path).\n const response = await this.http.post<{ success: boolean }>(\n \"/shipping/update/delivery_address\",\n {\n tracking: trackingNumber,\n delivery_name: address.name,\n delivery_email: address.email,\n delivery_city: resolvedCity,\n delivery_address: address.line1,\n delivery_neighbourhood: address.neighbourhood,\n delivery_postcode: address.postalCode,\n delivery_country: address.countryCode,\n delivery_phone: sanitizePhone(address.phone),\n },\n this.errorOpts,\n );\n return response.success === true;\n }\n\n // =========================================================================\n // TRACKING\n // =========================================================================\n\n async track(trackingNumber: string): Promise<TrackingResult> {\n const results = await this.trackMultiple([trackingNumber]);\n const result = results[0];\n if (!result) {\n throw new APIError(\"Shipment not found\", { carrier: \"aymakan\" });\n }\n return result;\n }\n\n async trackMultiple(trackingNumbers: string[]): Promise<TrackingResult[]> {\n const ids = trackingNumbers.map(encodeURIComponent).join(\",\");\n const response = await this.http.get<AymakanTrackResponse>(\n `/shipping/track/${ids}`,\n this.errorOpts,\n );\n\n if (!response.success) {\n throw new APIError(\"Failed to track shipments\", {\n carrier: \"aymakan\",\n raw: response,\n });\n }\n\n if (!Array.isArray(response.data?.shipments)) {\n throw new APIError(\"Aymakan track response is missing data.shipments\", {\n carrier: \"aymakan\",\n raw: response,\n });\n }\n\n return response.data.shipments.map(mapTrackingResult);\n }\n\n async trackByReference(reference: string): Promise<TrackingResult> {\n const response = await this.http.get<AymakanTrackResponse>(\n `/shipping/by_reference/${encodeURIComponent(reference)}`,\n this.errorOpts,\n );\n\n const shipment = response.data?.shipments?.[0];\n if (!response.success || !shipment) {\n throw new APIError(\"Shipment not found\", {\n carrier: \"aymakan\",\n raw: response,\n });\n }\n\n return mapTrackingResult(shipment);\n }\n\n // =========================================================================\n // LABELS\n // =========================================================================\n\n async getLabel(\n trackingNumber: string,\n _format?: \"PDF\" | \"ZPL\" | \"PNG\",\n ): Promise<string> {\n // Note: this endpoint always returns a single PDF download URL, so the\n // requested `format` cannot be honored.\n const response = await this.http.get<{\n success: boolean;\n error?: boolean;\n message?: string;\n response?: string;\n data: { awb_url: string };\n }>(\n `/shipping/awb/tracking/${encodeURIComponent(trackingNumber)}`,\n this.errorOpts,\n );\n\n if (!response.success || !response.data?.awb_url) {\n const msg = response.message ?? response.response ?? \"Failed to get label\";\n throw new APIError(msg, { carrier: \"aymakan\", raw: response });\n }\n\n return response.data.awb_url;\n }\n\n async getBulkLabels(trackingNumbers: string[]): Promise<string> {\n // Documented as a GET with comma-separated tracking numbers in the path.\n const ids = trackingNumbers.map(encodeURIComponent).join(\",\");\n const response = await this.http.get<{\n success: boolean;\n error?: boolean;\n message?: string;\n response?: string;\n data: { bulk_awb_url: string };\n }>(`/shipping/bulk_awb/trackings/${ids}`, this.errorOpts);\n\n if (!response.success || !response.data?.bulk_awb_url) {\n const msg =\n response.message ?? response.response ?? \"Failed to get bulk labels\";\n throw new APIError(msg, { carrier: \"aymakan\", raw: response });\n }\n\n return response.data.bulk_awb_url;\n }\n\n // =========================================================================\n // PICKUPS\n // =========================================================================\n\n async getPickupCities(): Promise<City[]> {\n const response = await this.http.get<AymakanCitiesResponse>(\n \"/pickup_request/cities\",\n this.errorOpts,\n );\n\n if (!response.success) {\n throw new APIError(\"Failed to get pickup cities\", {\n carrier: \"aymakan\",\n raw: response,\n });\n }\n\n return response.data.cities.map(mapCity);\n }\n\n async getTimeSlots(_city: string, date: string): Promise<TimeSlot[]> {\n const response = await this.http.get<{\n success: boolean;\n error?: boolean;\n message?: string;\n data: {\n date: string;\n slots: Record<string, string>;\n };\n }>(`/time_slots/${encodeURIComponent(date)}`, this.errorOpts);\n\n // Aymakan returns error responses for invalid dates (past, Fridays, etc.)\n if (!response.success || response.error || !response.data?.slots) {\n const msg = response.message ?? \"No slots available\";\n throw new APIError(msg, { carrier: \"aymakan\", raw: response });\n }\n\n // data.slots is an object like { \"afternoon\": \"After Noon (02 PM - 06 PM)\" }\n return Object.entries(response.data.slots).map(([id, label]) => ({\n id,\n label,\n }));\n }\n\n async createPickup(input: PickupRequest): Promise<Pickup> {\n validatePickupRequest(input);\n await this.ensureCitiesLoaded();\n const resolvedInput = { ...input, city: this.resolveCity(input.city) };\n const request = mapPickupRequest(resolvedInput);\n const response = await this.http.post<AymakanPickupResponse>(\n \"/pickup_request/create\",\n request,\n this.errorOpts,\n );\n\n if (!response.success) {\n throw new APIError(\"Failed to create pickup\", {\n carrier: \"aymakan\",\n raw: response,\n });\n }\n\n return mapPickupResponse(response.data);\n }\n\n async cancelPickup(pickupId: string | number): Promise<boolean> {\n const response = await this.http.post<{ success: boolean }>(\n \"/pickup_request/cancel\",\n { pickup_request: Number(pickupId) },\n this.errorOpts,\n );\n return response.success === true;\n }\n\n async getPickupRequests(): Promise<Pickup[]> {\n // The list endpoint returns a Laravel paginated structure:\n // { success, data: { pickupRequests: { data: [...] } } }\n const response = await this.http.get<{\n success: boolean;\n data: { pickupRequests: { data: AymakanPickupResponse[\"data\"][] } };\n }>(\"/pickup_request/list\", this.errorOpts);\n\n if (!response.success) {\n throw new APIError(\"Failed to get pickup requests\", {\n carrier: \"aymakan\",\n raw: response,\n });\n }\n\n const list = response.data?.pickupRequests?.data;\n if (!Array.isArray(list)) {\n throw new APIError(\n \"Aymakan pickup list response is missing data.pickupRequests.data\",\n { carrier: \"aymakan\", raw: response },\n );\n }\n\n return list.map(mapPickupResponse);\n }\n\n // =========================================================================\n // CITIES & LOCATIONS\n // =========================================================================\n\n async getCities(): Promise<City[]> {\n const response = await this.http.get<AymakanCitiesResponse>(\n \"/cities\",\n this.errorOpts,\n );\n\n if (!response.success) {\n throw new APIError(\"Failed to get cities\", {\n carrier: \"aymakan\",\n raw: response,\n });\n }\n\n return response.data.cities.map(mapCity);\n }\n\n async getDropoffLocations(): Promise<\n {\n id: string;\n name: string;\n address?: string;\n city?: string;\n latitude?: number;\n longitude?: number;\n }[]\n > {\n // The API returns `data` as a flat array of warehouse objects. There is no\n // `id` field — the warehouse code lives in `name` (e.g. \"RUH-WH\").\n const response = await this.http.get<{\n success: boolean;\n data: Array<{\n name: string;\n city?: string;\n address?: string;\n manager?: string;\n mobile_phone?: string;\n email?: string;\n location_lat?: number | null;\n location_lng?: number | null;\n }>;\n }>(\"/dropoff_locations\", this.errorOpts);\n\n if (!response.success) {\n throw new APIError(\"Failed to get dropoff locations\", {\n carrier: \"aymakan\",\n raw: response,\n });\n }\n\n return response.data.map((loc) => ({\n id: loc.name,\n name: loc.name,\n address: loc.address,\n city: loc.city,\n latitude: loc.location_lat ?? undefined,\n longitude: loc.location_lng ?? undefined,\n }));\n }\n\n // =========================================================================\n // CUSTOMER ADDRESSES\n // =========================================================================\n\n async createCustomerAddress(\n address: CustomerAddress,\n ): Promise<CustomerAddress> {\n const request = mapCustomerAddressRequest(address);\n const response = await this.http.post<AymakanAddressResponse>(\n \"/address/create\",\n request,\n this.errorOpts,\n );\n\n if (!response.success || !response.data?.address) {\n throw new APIError(\"Failed to create address\", {\n carrier: \"aymakan\",\n raw: response,\n });\n }\n\n const addr = response.data.address;\n return {\n id: addr.id,\n title: addr.title,\n name: addr.name,\n email: addr.email,\n phone: addr.phone,\n city: addr.city,\n address: addr.address,\n neighbourhood: addr.neighbourhood,\n postalCode: addr.postcode,\n countryCode: addr.country,\n description: addr.description,\n };\n }\n\n async getCustomerAddresses(): Promise<CustomerAddress[]> {\n const response = await this.http.get<{\n success: boolean;\n data: { address: AymakanAddressResponse[\"data\"][\"address\"][] };\n }>(\"/address/list\", this.errorOpts);\n\n if (!response.success) {\n throw new APIError(\"Failed to get customer addresses\", {\n carrier: \"aymakan\",\n raw: response,\n });\n }\n\n if (!Array.isArray(response.data?.address)) {\n throw new APIError(\n \"Aymakan address list response is missing data.address\",\n { carrier: \"aymakan\", raw: response },\n );\n }\n\n return response.data.address.map((addr) => ({\n id: addr.id,\n title: addr.title,\n name: addr.name,\n email: addr.email,\n phone: addr.phone,\n city: addr.city,\n address: addr.address,\n neighbourhood: addr.neighbourhood,\n postalCode: addr.postcode,\n countryCode: addr.country,\n description: addr.description,\n }));\n }\n\n async updateCustomerAddress(\n id: number,\n address: Partial<CustomerAddress>,\n ): Promise<CustomerAddress> {\n const response = await this.http.put<AymakanAddressResponse>(\n \"/address/update\",\n {\n id,\n title: address.title,\n name: address.name,\n email: address.email,\n city: address.city,\n address: address.address,\n neighbourhood: address.neighbourhood,\n postcode: address.postalCode,\n phone: address.phone,\n description: address.description,\n },\n this.errorOpts,\n );\n\n if (!response.success || !response.data?.address) {\n throw new APIError(\"Failed to update address\", {\n carrier: \"aymakan\",\n raw: response,\n });\n }\n\n const addr = response.data.address;\n return {\n id: addr.id,\n title: addr.title,\n name: addr.name,\n email: addr.email,\n phone: addr.phone,\n city: addr.city,\n address: addr.address,\n neighbourhood: addr.neighbourhood,\n postalCode: addr.postcode,\n countryCode: addr.country,\n description: addr.description,\n };\n }\n\n async deleteCustomerAddress(id: number): Promise<boolean> {\n // The id must be sent in the JSON request body, not the URL path.\n const response = await this.http.delete<{ success: boolean }>(\n \"/address/delete\",\n { body: { id }, errorExtractor: aymakanErrorExtractor },\n );\n return response.success === true;\n }\n\n // =========================================================================\n // WEBHOOKS\n // =========================================================================\n\n parseWebhook(\n payload: unknown,\n options?: {\n headers?: Record<string, string>;\n queryParams?: Record<string, string>;\n config?: WebhookConfig;\n },\n ): WebhookEvent {\n return parseAymakanWebhook(payload, options);\n }\n}\n"
8
8
  ],
9
- "mappings": "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",
10
- "debugId": "52369388ABAA8E1964756E2164756E21",
9
+ "mappings": "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",
10
+ "debugId": "30143D4A5E00F51C64756E2164756E21",
11
11
  "names": []
12
12
  }
@@ -10,6 +10,8 @@ export declare function mapAymakanStatus(statusCode: string): ShipmentStatus | u
10
10
  * Returns undefined for unrecognized labels.
11
11
  */
12
12
  export declare function mapAymakanStatusLabel(label: string): ShipmentStatus | undefined;
13
+ /** Strip non-digit characters from phone numbers (Aymakan requires digits only) */
14
+ export declare function sanitizePhone(phone: string): string;
13
15
  export declare function mapCreateShipmentRequest(input: CreateShipmentInput): AymakanCreateShipmentRequest;
14
16
  export declare function mapPickupRequest(input: PickupRequest): AymakanPickupRequest;
15
17
  export declare function mapCustomerAddressRequest(addr: CustomerAddress): AymakanAddressRequest;
@@ -1 +1 @@
1
- {"version":3,"file":"mappers.d.ts","sourceRoot":"","sources":["../../../src/carriers/aymakan/mappers.ts"],"names":[],"mappings":"AACA;;;GAGG;AAGH,OAAO,KAAK,EAEV,IAAI,EACJ,mBAAmB,EACnB,eAAe,EACf,MAAM,EACN,aAAa,EACb,QAAQ,EACR,cAAc,EACd,aAAa,EACb,cAAc,EACd,aAAa,EACb,YAAY,EACb,MAAM,kBAAkB,CAAC;AAE1B,OAAO,KAAK,EACV,qBAAqB,EACrB,WAAW,EACX,4BAA4B,EAE5B,oBAAoB,EACpB,qBAAqB,EACrB,uBAAuB,EACvB,oBAAoB,EACpB,wBAAwB,EAEzB,MAAM,SAAS,CAAC;AAMjB,wBAAgB,gBAAgB,CAAC,UAAU,EAAE,MAAM,GAAG,cAAc,GAAG,SAAS,CAI/E;AAkCD;;;GAGG;AACH,wBAAgB,qBAAqB,CACnC,KAAK,EAAE,MAAM,GACZ,cAAc,GAAG,SAAS,CAE5B;AAuCD,wBAAgB,wBAAwB,CACtC,KAAK,EAAE,mBAAmB,GACzB,4BAA4B,CAqF9B;AAED,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,aAAa,GAAG,oBAAoB,CAW3E;AAED,wBAAgB,yBAAyB,CACvC,IAAI,EAAE,eAAe,GACpB,qBAAqB,CAYvB;AAMD,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,uBAAuB,GAAG,QAAQ,CA8B3E;AAeD,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,oBAAoB,GAAG,aAAa,CAQ3E;AAED,wBAAgB,iBAAiB,CAC/B,IAAI,EAAE,wBAAwB,GAC7B,cAAc,CA+ChB;AAED,wBAAgB,OAAO,CAAC,IAAI,EAAE,WAAW,GAAG,IAAI,CAK/C;AAED,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,qBAAqB,CAAC,MAAM,CAAC,GAAG,MAAM,CAqB7E;AAsBD,wBAAgB,mBAAmB,CACjC,OAAO,EAAE,OAAO,EAChB,OAAO,CAAC,EAAE;IACR,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACrC,MAAM,CAAC,EAAE,aAAa,CAAC;CACxB,GACA,YAAY,CAsEd"}
1
+ {"version":3,"file":"mappers.d.ts","sourceRoot":"","sources":["../../../src/carriers/aymakan/mappers.ts"],"names":[],"mappings":"AACA;;;GAGG;AAGH,OAAO,KAAK,EAEV,IAAI,EACJ,mBAAmB,EACnB,eAAe,EACf,MAAM,EACN,aAAa,EACb,QAAQ,EACR,cAAc,EACd,aAAa,EACb,cAAc,EACd,aAAa,EACb,YAAY,EACb,MAAM,kBAAkB,CAAC;AAE1B,OAAO,KAAK,EACV,qBAAqB,EACrB,WAAW,EACX,4BAA4B,EAE5B,oBAAoB,EACpB,qBAAqB,EACrB,uBAAuB,EACvB,oBAAoB,EACpB,wBAAwB,EAEzB,MAAM,SAAS,CAAC;AAMjB,wBAAgB,gBAAgB,CAAC,UAAU,EAAE,MAAM,GAAG,cAAc,GAAG,SAAS,CAI/E;AAkCD;;;GAGG;AACH,wBAAgB,qBAAqB,CACnC,KAAK,EAAE,MAAM,GACZ,cAAc,GAAG,SAAS,CAE5B;AAmBD,mFAAmF;AACnF,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAEnD;AAiBD,wBAAgB,wBAAwB,CACtC,KAAK,EAAE,mBAAmB,GACzB,4BAA4B,CAqF9B;AAED,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,aAAa,GAAG,oBAAoB,CAW3E;AAED,wBAAgB,yBAAyB,CACvC,IAAI,EAAE,eAAe,GACpB,qBAAqB,CAYvB;AAMD,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,uBAAuB,GAAG,QAAQ,CA8B3E;AAeD,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,oBAAoB,GAAG,aAAa,CAQ3E;AAED,wBAAgB,iBAAiB,CAC/B,IAAI,EAAE,wBAAwB,GAC7B,cAAc,CAqDhB;AAED,wBAAgB,OAAO,CAAC,IAAI,EAAE,WAAW,GAAG,IAAI,CAK/C;AAED,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,qBAAqB,CAAC,MAAM,CAAC,GAAG,MAAM,CAqB7E;AAsBD,wBAAgB,mBAAmB,CACjC,OAAO,EAAE,OAAO,EAChB,OAAO,CAAC,EAAE;IACR,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACrC,MAAM,CAAC,EAAE,aAAa,CAAC;CACxB,GACA,YAAY,CA0Ed"}
@@ -176,7 +176,7 @@ export interface AymakanTrackShipmentData {
176
176
  created_at: string;
177
177
  id_customer: number;
178
178
  is_reverse_pickup: 0 | 1;
179
- tracking_info: AymakanTrackingEvent[];
179
+ tracking_info?: AymakanTrackingEvent[];
180
180
  }
181
181
  export interface AymakanTrackResponse {
182
182
  success: boolean;
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/carriers/aymakan/types.ts"],"names":[],"mappings":"AACA;;;GAGG;AAMH,MAAM,WAAW,6BAA6B;IAC5C,UAAU,EAAE,MAAM,CAAC;IACnB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC5B;AAED,MAAM,WAAW,4BAA4B;IAC3C,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,yBAAyB,CAAC,EAAE,MAAM,CAAC;IACnC,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,4BAA4B;IAC3C,YAAY,EAAE,MAAM,CAAC;IACrB,cAAc,EAAE,MAAM,CAAC;IACvB,uBAAuB,CAAC,EAAE,MAAM,CAAC;IACjC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,MAAM,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC;IACf,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,wBAAwB,CAAC,EAAE,MAAM,CAAC;IAClC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,aAAa,EAAE,MAAM,CAAC;IACtB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,aAAa,EAAE,MAAM,CAAC;IACtB,gBAAgB,EAAE,MAAM,CAAC;IACzB,sBAAsB,CAAC,EAAE,MAAM,CAAC;IAChC,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,gBAAgB,EAAE,MAAM,CAAC;IACzB,cAAc,EAAE,MAAM,CAAC;IACvB,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,yBAAyB,CAAC,EAAE,6BAA6B,CAAC;IAC1D,eAAe,EAAE,MAAM,CAAC;IACxB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,eAAe,EAAE,MAAM,CAAC;IACxB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,wBAAwB,CAAC,EAAE,MAAM,CAAC;IAClC,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,kBAAkB,EAAE,MAAM,CAAC;IAC3B,gBAAgB,EAAE,MAAM,CAAC;IACzB,sBAAsB,CAAC,EAAE,MAAM,CAAC;IAChC,2BAA2B,CAAC,EAAE,6BAA6B,CAAC;IAC5D,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,UAAU,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC;IACnB,sBAAsB,CAAC,EAAE,4BAA4B,CAAC;CACvD;AAED,MAAM,WAAW,oBAAoB;IACnC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,YAAY,EAAE,MAAM,CAAC;IACrB,aAAa,EAAE,MAAM,CAAC;IACtB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,qBAAqB;IACpC,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,aAAa,EAAE,MAAM,CAAC;IACtB,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;CACrB;AAMD,MAAM,WAAW,uBAAuB;IACtC,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,eAAe,EAAE,MAAM,CAAC;IACxB,iBAAiB,EAAE,MAAM,GAAG,IAAI,CAAC;IACjC,aAAa,EAAE,MAAM,CAAC;IACtB,YAAY,EAAE,MAAM,CAAC;IACrB,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,yBAAyB,EAAE,MAAM,GAAG,IAAI,CAAC;IACzC,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,UAAU,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAAC;IACnC,cAAc,EAAE,MAAM,CAAC;IACvB,uBAAuB,EAAE,MAAM,CAAC;IAChC,QAAQ,EAAE,MAAM,CAAC;IACjB,aAAa,EAAE,MAAM,CAAC;IACtB,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,aAAa,EAAE,MAAM,CAAC;IACtB,gBAAgB,EAAE,MAAM,CAAC;IACzB,sBAAsB,EAAE,MAAM,GAAG,IAAI,CAAC;IACtC,iBAAiB,EAAE,MAAM,GAAG,IAAI,CAAC;IACjC,gBAAgB,EAAE,MAAM,CAAC;IACzB,cAAc,EAAE,MAAM,CAAC;IACvB,oBAAoB,EAAE,MAAM,GAAG,IAAI,CAAC;IACpC,eAAe,EAAE,MAAM,CAAC;IACxB,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,eAAe,EAAE,MAAM,CAAC;IACxB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,iBAAiB,EAAE,MAAM,GAAG,IAAI,CAAC;IACjC,mBAAmB,EAAE,MAAM,GAAG,IAAI,CAAC;IACnC,kBAAkB,EAAE,MAAM,CAAC;IAC3B,gBAAgB,EAAE,MAAM,CAAC;IACzB,sBAAsB,EAAE,MAAM,GAAG,IAAI,CAAC;IACtC,eAAe,EAAE,MAAM,CAAC;IACxB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC;IACf,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,iBAAiB,EAAE,CAAC,GAAG,CAAC,CAAC;IACzB,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,6BAA6B;IAC5C,OAAO,EAAE,OAAO,CAAC;IACjB,QAAQ,EAAE,uBAAuB,CAAC;CACnC;AAED,MAAM,WAAW,oBAAoB;IACnC,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,wBAAwB;IACvC,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,eAAe,EAAE,MAAM,CAAC;IACxB,iBAAiB,EAAE,MAAM,GAAG,IAAI,CAAC;IACjC,aAAa,EAAE,MAAM,CAAC;IACtB,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,uBAAuB,EAAE,MAAM,GAAG,IAAI,CAAC;IACvC,QAAQ,EAAE,MAAM,CAAC;IACjB,aAAa,EAAE,MAAM,CAAC;IACtB,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,aAAa,EAAE,MAAM,CAAC;IACtB,gBAAgB,EAAE,MAAM,CAAC;IACzB,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,iBAAiB,EAAE,MAAM,GAAG,IAAI,CAAC;IACjC,gBAAgB,EAAE,MAAM,CAAC;IACzB,cAAc,EAAE,MAAM,CAAC;IACvB,oBAAoB,EAAE,MAAM,GAAG,IAAI,CAAC;IACpC,eAAe,EAAE,MAAM,CAAC;IACxB,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,eAAe,EAAE,MAAM,CAAC;IACxB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,iBAAiB,EAAE,MAAM,GAAG,IAAI,CAAC;IACjC,mBAAmB,EAAE,MAAM,GAAG,IAAI,CAAC;IACnC,kBAAkB,EAAE,MAAM,CAAC;IAC3B,gBAAgB,EAAE,MAAM,CAAC;IACzB,sBAAsB,EAAE,MAAM,GAAG,IAAI,CAAC;IACtC,eAAe,EAAE,MAAM,CAAC;IACxB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC;IACf,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,iBAAiB,EAAE,CAAC,GAAG,CAAC,CAAC;IACzB,aAAa,EAAE,oBAAoB,EAAE,CAAC;CACvC;AAED,MAAM,WAAW,oBAAoB;IACnC,OAAO,EAAE,OAAO,CAAC;IACjB,IAAI,EAAE;QACJ,SAAS,EAAE,wBAAwB,EAAE,CAAC;KACvC,CAAC;CACH;AAED,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,qBAAqB;IACpC,OAAO,EAAE,OAAO,CAAC;IACjB,IAAI,EAAE;QACJ,MAAM,EAAE,WAAW,EAAE,CAAC;KACvB,CAAC;CACH;AAED,MAAM,WAAW,qBAAqB;IACpC,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE;QACJ,EAAE,EAAE,MAAM,CAAC;QACX,WAAW,EAAE,MAAM,CAAC;QACpB,YAAY,EAAE,MAAM,CAAC;QACrB,aAAa,EAAE,MAAM,CAAC;QACtB,SAAS,EAAE,MAAM,CAAC;QAClB,SAAS,EAAE,MAAM,CAAC;QAClB,WAAW,EAAE,MAAM,CAAC;QACpB,OAAO,EAAE,MAAM,CAAC;QAChB,QAAQ,EAAE,MAAM,CAAC;QACjB,MAAM,EAAE,MAAM,CAAC;QACf,IAAI,EAAE,MAAM,CAAC;QACb,YAAY,EAAE,MAAM,CAAC;QACrB,cAAc,EAAE,MAAM,CAAC;QACvB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;QACzB,UAAU,EAAE,MAAM,CAAC;QACnB,UAAU,EAAE,MAAM,CAAC;KACpB,CAAC;CACH;AAED,MAAM,WAAW,sBAAsB;IACrC,OAAO,EAAE,OAAO,CAAC;IACjB,IAAI,EAAE;QACJ,OAAO,EAAE;YACP,EAAE,EAAE,MAAM,CAAC;YACX,KAAK,EAAE,MAAM,CAAC;YACd,IAAI,EAAE,MAAM,CAAC;YACb,KAAK,EAAE,MAAM,CAAC;YACd,IAAI,EAAE,MAAM,CAAC;YACb,OAAO,EAAE,MAAM,CAAC;YAChB,QAAQ,EAAE,MAAM,CAAC;YACjB,aAAa,EAAE,MAAM,CAAC;YACtB,KAAK,EAAE,MAAM,CAAC;YACd,OAAO,EAAE,MAAM,CAAC;YAChB,WAAW,EAAE,MAAM,CAAC;SACrB,CAAC;KACH,CAAC;CACH;AAED,MAAM,WAAW,qBAAqB;IACpC,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,qBAAqB;IACpC,eAAe,EAAE,MAAM,CAAC;IACxB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,MAAM,EAAE,MAAM,CAAC;IACf,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,eAAe,GAAG,eAAe,CAAC;IACzC,uBAAuB,EAAE,MAAM,GAAG,IAAI,CAAC;IACvC,aAAa,EAAE,MAAM,CAAC;IACtB,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,aAAa,EAAE,MAAM,CAAC;IACtB,gBAAgB,EAAE,MAAM,CAAC;IACzB,iBAAiB,EAAE,MAAM,GAAG,IAAI,CAAC;IACjC,gBAAgB,EAAE,MAAM,CAAC;IACzB,cAAc,EAAE,MAAM,CAAC;IACvB,oBAAoB,EAAE,MAAM,GAAG,IAAI,CAAC;IACpC,sBAAsB,EAAE,MAAM,GAAG,IAAI,CAAC;IACtC,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,eAAe,EAAE,MAAM,CAAC;IACxB,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,eAAe,EAAE,MAAM,CAAC;IACxB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,wBAAwB,EAAE,MAAM,GAAG,IAAI,CAAC;IACxC,iBAAiB,EAAE,CAAC,GAAG,CAAC,CAAC;IACzB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC;IACf,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,aAAa,EAAE,MAAM,CAAC;IACtB,aAAa,EAAE,oBAAoB,EAAE,CAAC;CACvC;AAED,MAAM,WAAW,oBAAoB;IACnC,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;IAClC,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/carriers/aymakan/types.ts"],"names":[],"mappings":"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"}