shipflow 0.1.0 → 0.2.1

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.
Files changed (36) hide show
  1. package/README.md +139 -33
  2. package/dist/carriers/aramex/adapter.d.ts +82 -0
  3. package/dist/carriers/aramex/adapter.d.ts.map +1 -0
  4. package/dist/carriers/aramex/index.d.ts +9 -0
  5. package/dist/carriers/aramex/index.d.ts.map +1 -0
  6. package/dist/carriers/aramex/index.js +694 -0
  7. package/dist/carriers/aramex/index.js.map +12 -0
  8. package/dist/carriers/aramex/mappers.d.ts +76 -0
  9. package/dist/carriers/aramex/mappers.d.ts.map +1 -0
  10. package/dist/carriers/aramex/services.d.ts +74 -0
  11. package/dist/carriers/aramex/services.d.ts.map +1 -0
  12. package/dist/carriers/aramex/types.d.ts +302 -0
  13. package/dist/carriers/aramex/types.d.ts.map +1 -0
  14. package/dist/carriers/aymakan/adapter.d.ts +8 -2
  15. package/dist/carriers/aymakan/adapter.d.ts.map +1 -1
  16. package/dist/carriers/aymakan/index.js +138 -61
  17. package/dist/carriers/aymakan/index.js.map +4 -4
  18. package/dist/carriers/aymakan/mappers.d.ts +5 -0
  19. package/dist/carriers/aymakan/mappers.d.ts.map +1 -1
  20. package/dist/carriers/aymakan/types.d.ts +4 -6
  21. package/dist/carriers/aymakan/types.d.ts.map +1 -1
  22. package/dist/carriers/base.d.ts +2 -2
  23. package/dist/carriers/base.d.ts.map +1 -1
  24. package/dist/carriers/smsaexpress/adapter.d.ts +1 -1
  25. package/dist/carriers/smsaexpress/adapter.d.ts.map +1 -1
  26. package/dist/carriers/smsaexpress/index.js +32 -22
  27. package/dist/carriers/smsaexpress/index.js.map +4 -4
  28. package/dist/carriers/smsaexpress/mappers.d.ts.map +1 -1
  29. package/dist/core/http.d.ts.map +1 -1
  30. package/dist/core/schemas.d.ts +3 -3
  31. package/dist/core/types.d.ts +1 -1
  32. package/dist/core/types.d.ts.map +1 -1
  33. package/dist/{index-x8sk1kw9.js → index-qjtxhwzv.js} +5 -3
  34. package/dist/{index-x8sk1kw9.js.map → index-qjtxhwzv.js.map} +5 -5
  35. package/dist/index.js +1 -1
  36. package/package.json +8 -3
@@ -13,6 +13,11 @@ export declare class AymakanAdapter extends BaseCarrierAdapter {
13
13
  readonly name = "aymakan";
14
14
  readonly supportedCountries: string[];
15
15
  private http;
16
+ /**
17
+ * Shared options applied to every Aymakan http call so fake-200 error
18
+ * envelopes surface as APIError instead of being silently swallowed.
19
+ */
20
+ private readonly errorOpts;
16
21
  /** Cached Aymakan cities list for city name resolution */
17
22
  private citiesCache;
18
23
  private citiesCacheTime;
@@ -58,7 +63,7 @@ export declare class AymakanAdapter extends BaseCarrierAdapter {
58
63
  track(trackingNumber: string): Promise<TrackingResult>;
59
64
  trackMultiple(trackingNumbers: string[]): Promise<TrackingResult[]>;
60
65
  trackByReference(reference: string): Promise<TrackingResult>;
61
- getLabel(trackingNumber: string, format?: "PDF" | "PNG"): Promise<string>;
66
+ getLabel(trackingNumber: string, _format?: "PDF" | "ZPL" | "PNG"): Promise<string>;
62
67
  getBulkLabels(trackingNumbers: string[]): Promise<string>;
63
68
  getPickupCities(): Promise<City[]>;
64
69
  getTimeSlots(_city: string, date: string): Promise<TimeSlot[]>;
@@ -69,9 +74,10 @@ export declare class AymakanAdapter extends BaseCarrierAdapter {
69
74
  getDropoffLocations(): Promise<{
70
75
  id: string;
71
76
  name: string;
72
- nameAr?: string;
73
77
  address?: string;
74
78
  city?: string;
79
+ latitude?: number;
80
+ longitude?: number;
75
81
  }[]>;
76
82
  createCustomerAddress(address: CustomerAddress): Promise<CustomerAddress>;
77
83
  getCustomerAddresses(): Promise<CustomerAddress[]>;
@@ -1 +1 @@
1
- {"version":3,"file":"adapter.d.ts","sourceRoot":"","sources":["../../../src/carriers/aymakan/adapter.ts"],"names":[],"mappings":"AACA;;;GAGG;AAQH,OAAO,KAAK,EACV,OAAO,EACP,aAAa,EACb,IAAI,EACJ,mBAAmB,EACnB,eAAe,EACf,MAAM,EACN,aAAa,EACb,QAAQ,EACR,QAAQ,EACR,cAAc,EACd,aAAa,EACb,YAAY,EACb,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,kBAAkB,EAAE,MAAM,SAAS,CAAC;AAuB7C,MAAM,WAAW,aAAc,SAAQ,aAAa;IAClD,WAAW,EAAE;QACX,MAAM,EAAE,MAAM,CAAC;KAChB,CAAC;CACH;AAED,qBAAa,cAAe,SAAQ,kBAAkB;IACpD,QAAQ,CAAC,IAAI,aAAa;IAC1B,QAAQ,CAAC,kBAAkB,WAAwC;IAEnE,OAAO,CAAC,IAAI,CAAa;IAEzB,0DAA0D;IAC1D,OAAO,CAAC,WAAW,CAAuB;IAC1C,OAAO,CAAC,eAAe,CAAK;IAC5B,wBAAwB;IACxB,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,gBAAgB,CAAkB;gBAE9C,MAAM,EAAE,aAAa;IAWjC,SAAS,CAAC,UAAU,IAAI,MAAM;IAU9B;;;OAGG;YACW,kBAAkB;IAehC;;;;;;OAMG;IACH,OAAO,CAAC,MAAM,CAAC,eAAe;IAQ9B;;;;;;;;;;;OAWG;IACH,OAAO,CAAC,WAAW;IA+CnB;;OAEG;IACH,OAAO,CAAC,oBAAoB;cAoBZ,qBAAqB,CACnC,KAAK,EAAE,mBAAmB,GACzB,OAAO,CAAC,QAAQ,CAAC;IAmBd,mBAAmB,CACvB,MAAM,EAAE,mBAAmB,EAAE,GAC5B,OAAO,CAAC,QAAQ,EAAE,CAAC;IAqBhB,cAAc,CAAC,cAAc,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAWxD,iBAAiB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAOtD,qBAAqB,CACzB,cAAc,EAAE,MAAM,EACtB,OAAO,EAAE,OAAO,GACf,OAAO,CAAC,OAAO,CAAC;IAuBb,KAAK,CAAC,cAAc,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC;IAStD,aAAa,CAAC,eAAe,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,cAAc,EAAE,CAAC;IAgBnE,gBAAgB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC;IAmB5D,QAAQ,CACZ,cAAc,EAAE,MAAM,EACtB,MAAM,CAAC,EAAE,KAAK,GAAG,KAAK,GACrB,OAAO,CAAC,MAAM,CAAC;IAwBZ,aAAa,CAAC,eAAe,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC;IAsBzD,eAAe,IAAI,OAAO,CAAC,IAAI,EAAE,CAAC;IAelC,YAAY,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,EAAE,CAAC;IAwB9D,YAAY,CAAC,KAAK,EAAE,aAAa,GAAG,OAAO,CAAC,MAAM,CAAC;IAoBnD,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAOzD,iBAAiB,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;IAoBtC,SAAS,IAAI,OAAO,CAAC,IAAI,EAAE,CAAC;IAa5B,mBAAmB,IAAI,OAAO,CAClC;QACE,EAAE,EAAE,MAAM,CAAC;QACX,IAAI,EAAE,MAAM,CAAC;QACb,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,IAAI,CAAC,EAAE,MAAM,CAAC;KACf,EAAE,CACJ;IAkCK,qBAAqB,CACzB,OAAO,EAAE,eAAe,GACvB,OAAO,CAAC,eAAe,CAAC;IA8BrB,oBAAoB,IAAI,OAAO,CAAC,eAAe,EAAE,CAAC;IA4BlD,qBAAqB,CACzB,EAAE,EAAE,MAAM,EACV,OAAO,EAAE,OAAO,CAAC,eAAe,CAAC,GAChC,OAAO,CAAC,eAAe,CAAC;IAuCrB,qBAAqB,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAWzD,YAAY,CACV,OAAO,EAAE,OAAO,EAChB,OAAO,CAAC,EAAE;QACR,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QACjC,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QACrC,MAAM,CAAC,EAAE,aAAa,CAAC;KACxB,GACA,YAAY;IAQf,QAAQ,IAAI,OAAO,CAAC,KAAK,CAAC;CAG3B"}
1
+ {"version":3,"file":"adapter.d.ts","sourceRoot":"","sources":["../../../src/carriers/aymakan/adapter.ts"],"names":[],"mappings":"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"}
@@ -7,7 +7,7 @@ import {
7
7
  WebhookVerificationError,
8
8
  validateCreateShipmentInput,
9
9
  validatePickupRequest
10
- } from "../../index-x8sk1kw9.js";
10
+ } from "../../index-qjtxhwzv.js";
11
11
 
12
12
  // src/carriers/aymakan/services.ts
13
13
  var AymakanService = {
@@ -43,6 +43,33 @@ function mapAymakanStatus(statusCode) {
43
43
  const mapped = AymakanStatusCodes[statusCode];
44
44
  return mapped;
45
45
  }
46
+ var AymakanStatusLabels = {
47
+ "awb created at origin": "created",
48
+ "shipment created": "created",
49
+ "collected from collection point": "picked_up",
50
+ collected: "picked_up",
51
+ "picked up": "picked_up",
52
+ "received at hub": "at_warehouse",
53
+ "received at warehouse": "at_warehouse",
54
+ "out for delivery": "out_for_delivery",
55
+ "out for final destination": "out_for_delivery",
56
+ delivered: "delivered",
57
+ "shipment is delivered": "delivered",
58
+ "transferred to destination city": "in_transit",
59
+ "in transit": "in_transit",
60
+ "not delivered": "exception",
61
+ "failed attempt": "exception",
62
+ pending: "pending",
63
+ "future delivery": "pending",
64
+ returned: "returned",
65
+ "returned to shipper": "returned",
66
+ "return to origin": "returned",
67
+ cancelled: "cancelled",
68
+ canceled: "cancelled"
69
+ };
70
+ function mapAymakanStatusLabel(label) {
71
+ return AymakanStatusLabels[label.trim().toLowerCase()];
72
+ }
46
73
  function mapNationalAddress(addr) {
47
74
  if (!addr)
48
75
  return;
@@ -70,17 +97,19 @@ function mapCreateShipmentRequest(input) {
70
97
  const totalPieces = input.parcels.reduce((sum, p) => sum + p.pieces, 0);
71
98
  const totalWeight = input.parcels.reduce((sum, p) => sum + (p.weight.unit === "lb" ? p.weight.value * 0.453592 : p.weight.value), 0);
72
99
  const totalItems = input.parcels.reduce((sum, p) => sum + (p.itemsCount ?? p.pieces), 0);
100
+ const codEnabled = input.cod?.enabled === true;
101
+ const declaredValueCurrency = input.declaredValue?.currency ?? "SAR";
73
102
  return {
74
103
  requested_by: input.options?.requestedBy ?? input.shipper.name,
75
- declared_value: input.declaredValue?.amount ?? input.cod?.amount ?? 0,
76
- declared_value_currency: input.declaredValue?.currency ?? input.cod?.currency ?? "SAR",
104
+ declared_value: input.declaredValue?.amount ?? 0,
105
+ declared_value_currency: declaredValueCurrency,
77
106
  reference: input.reference,
78
107
  customer_tracking: input.options?.customerTracking,
79
108
  service_type: resolveServiceType(input.serviceType),
80
- is_cod: input.cod?.enabled ? 1 : 0,
81
- cod_amount: input.cod?.enabled ? input.cod.amount : undefined,
109
+ is_cod: codEnabled ? 1 : 0,
110
+ cod_amount: codEnabled ? input.cod?.amount : undefined,
82
111
  fulfilment_customer_name: input.options?.fulfilmentCustomerName,
83
- currency: input.cod?.currency ?? "SAR",
112
+ currency: codEnabled ? input.cod?.currency ?? "SAR" : declaredValueCurrency,
84
113
  delivery_name: input.consignee.name,
85
114
  delivery_email: input.consignee.email,
86
115
  delivery_city: input.consignee.city,
@@ -152,16 +181,22 @@ function mapShipmentResponse(data) {
152
181
  statusLabel: data.status_label,
153
182
  labelUrl: data.label || undefined,
154
183
  pdfLabelUrl: data.pdf_label || undefined,
155
- codAmount: codAmount && !Number.isNaN(codAmount) ? codAmount : undefined,
184
+ codAmount: codAmount != null && !Number.isNaN(codAmount) && codAmount !== 0 ? codAmount : undefined,
156
185
  declaredValue: data.declared_value,
157
186
  currency: data.currency,
158
187
  createdAt: new Date(data.created_at),
159
188
  raw: data
160
189
  };
161
190
  }
191
+ function parseAymakanDate(value) {
192
+ if (/[TZ]|[+-]\d{2}:?\d{2}$/.test(value)) {
193
+ return new Date(value);
194
+ }
195
+ return new Date(`${value.replace(" ", "T")}+03:00`);
196
+ }
162
197
  function mapTrackingEvent(event) {
163
198
  return {
164
- timestamp: new Date(event.created_at),
199
+ timestamp: parseAymakanDate(event.created_at),
165
200
  statusCode: event.status_code,
166
201
  status: mapAymakanStatus(event.status_code) ?? "unknown",
167
202
  description: event.description,
@@ -169,13 +204,21 @@ function mapTrackingEvent(event) {
169
204
  };
170
205
  }
171
206
  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;
209
+ let status;
210
+ if (latestEvent && latestEvent.status !== "unknown") {
211
+ status = latestEvent.status;
212
+ } else {
213
+ status = mapAymakanStatus(data.status) ?? mapAymakanStatusLabel(data.status) ?? latestEvent?.status ?? "unknown";
214
+ }
172
215
  return {
173
216
  trackingNumber: data.tracking_number,
174
217
  carrier: "aymakan",
175
218
  reference: data.reference ?? undefined,
176
- status: mapAymakanStatus(data.status) ?? "unknown",
219
+ status,
177
220
  statusLabel: data.status_label,
178
- events: data.tracking_info.map(mapTrackingEvent),
221
+ events,
179
222
  deliveryDate: data.delivery_date ? new Date(data.delivery_date) : undefined,
180
223
  pickupDate: data.pickup_date ? new Date(data.pickup_date) : undefined,
181
224
  receivedAt: data.received_at ? new Date(data.received_at) : undefined,
@@ -256,7 +299,7 @@ function parseAymakanWebhook(payload, options) {
256
299
  eventType,
257
300
  trackingNumber: data.tracking_number,
258
301
  reference: data.reference ?? undefined,
259
- status: eventType === "weight_update" ? "unknown" : mapAymakanStatus(data.status) ?? "unknown",
302
+ status: mapAymakanStatus(data.status) ?? "unknown",
260
303
  statusCode: data.status,
261
304
  statusLabel: data.status_label,
262
305
  reasonCode: data.reason_code ?? undefined,
@@ -269,11 +312,29 @@ function parseAymakanWebhook(payload, options) {
269
312
  // src/carriers/aymakan/adapter.ts
270
313
  var AYMAKAN_SANDBOX_URL = "https://dev-api.aymakan.com.sa/v2";
271
314
  var AYMAKAN_PRODUCTION_URL = "https://api.aymakan.net/v2";
315
+ function aymakanErrorExtractor(json) {
316
+ if (!json || typeof json !== "object") {
317
+ return { hasError: false };
318
+ }
319
+ const obj = json;
320
+ const hasValidationErrors = !!obj.errors && typeof obj.errors === "object" && Object.keys(obj.errors).length > 0;
321
+ const hasError = obj.error === true || obj.success === false || hasValidationErrors;
322
+ if (!hasError) {
323
+ return { hasError: false };
324
+ }
325
+ const message = typeof obj.message === "string" && obj.message || typeof obj.response === "string" && obj.response || typeof obj.error === "string" && obj.error || undefined;
326
+ return {
327
+ hasError: true,
328
+ message,
329
+ errors: hasValidationErrors ? obj.errors : undefined
330
+ };
331
+ }
272
332
 
273
333
  class AymakanAdapter extends BaseCarrierAdapter {
274
334
  name = "aymakan";
275
335
  supportedCountries = ["SA", "AE", "BH", "KW", "OM", "QA"];
276
336
  http;
337
+ errorOpts = { errorExtractor: aymakanErrorExtractor };
277
338
  citiesCache = null;
278
339
  citiesCacheTime = 0;
279
340
  static CITIES_CACHE_TTL = 60 * 60 * 1000;
@@ -348,7 +409,7 @@ class AymakanAdapter extends BaseCarrierAdapter {
348
409
  await this.ensureCitiesLoaded();
349
410
  const resolved = this.resolveCitiesInInput(input);
350
411
  const request = mapCreateShipmentRequest(resolved);
351
- const response = await this.http.post("/shipping/create", request);
412
+ const response = await this.http.post("/shipping/create", request, this.errorOpts);
352
413
  if (!response.success) {
353
414
  throw new APIError("Failed to create shipment", {
354
415
  carrier: "aymakan",
@@ -358,27 +419,35 @@ class AymakanAdapter extends BaseCarrierAdapter {
358
419
  return mapShipmentResponse(response.shipping);
359
420
  }
360
421
  async createBulkShipments(inputs) {
422
+ if (inputs.length === 0)
423
+ return [];
424
+ if (inputs.length > 30) {
425
+ throw new ValidationError("Aymakan bulk create accepts at most 30 shipments per request", { raw: { count: inputs.length } });
426
+ }
361
427
  inputs.forEach(validateCreateShipmentInput);
362
428
  await this.ensureCitiesLoaded();
363
429
  const requests = inputs.map((i) => this.resolveCitiesInInput(i)).map(mapCreateShipmentRequest);
364
- const response = await this.http.post("/shipping/create_bulk", { data: requests });
430
+ const response = await this.http.post("/shipping/create/bulk_shipping", { shipments: requests }, this.errorOpts);
365
431
  if (!response.success) {
366
432
  throw new APIError("Failed to create bulk shipments", {
367
433
  carrier: "aymakan",
368
434
  raw: response
369
435
  });
370
436
  }
371
- return response.data.shipments.map(mapShipmentResponse);
437
+ if (!Array.isArray(response.shipments)) {
438
+ throw new APIError("Aymakan bulk create response is missing the shipments array", { carrier: "aymakan", raw: response });
439
+ }
440
+ return response.shipments.map(mapShipmentResponse);
372
441
  }
373
442
  async cancelShipment(trackingNumber) {
374
443
  const response = await this.http.post("/shipping/cancel", {
375
444
  tracking: trackingNumber
376
- });
377
- return response.success;
445
+ }, this.errorOpts);
446
+ return response.success === true;
378
447
  }
379
448
  async cancelByReference(reference) {
380
- const response = await this.http.post(`/shipping/cancel/reference/${encodeURIComponent(reference)}`);
381
- return response.success;
449
+ const response = await this.http.post("/shipping/cancel_by_reference", { reference }, this.errorOpts);
450
+ return response.success === true;
382
451
  }
383
452
  async updateDeliveryAddress(trackingNumber, address) {
384
453
  await this.ensureCitiesLoaded();
@@ -405,52 +474,51 @@ class AymakanAdapter extends BaseCarrierAdapter {
405
474
  }
406
475
  async trackMultiple(trackingNumbers) {
407
476
  const ids = trackingNumbers.map(encodeURIComponent).join(",");
408
- const response = await this.http.get(`/shipping/track/${ids}`);
477
+ const response = await this.http.get(`/shipping/track/${ids}`, this.errorOpts);
409
478
  if (!response.success) {
410
479
  throw new APIError("Failed to track shipments", {
411
480
  carrier: "aymakan",
412
481
  raw: response
413
482
  });
414
483
  }
415
- return response.data.shipments.map(mapTrackingResult);
416
- }
417
- async trackByReference(reference) {
418
- const response = await this.http.get(`/shipments/by_reference/${encodeURIComponent(reference)}`);
419
- if (!response.success || !response.data.shipments[0]) {
420
- throw new APIError("Shipment not found", {
484
+ if (!Array.isArray(response.data?.shipments)) {
485
+ throw new APIError("Aymakan track response is missing data.shipments", {
421
486
  carrier: "aymakan",
422
487
  raw: response
423
488
  });
424
489
  }
425
- return mapTrackingResult(response.data.shipments[0]);
490
+ return response.data.shipments.map(mapTrackingResult);
426
491
  }
427
- async getLabel(trackingNumber, format) {
428
- const response = await this.http.get(`/shipping/awb/tracking/${encodeURIComponent(trackingNumber)}`);
429
- if (!response.success) {
430
- throw new APIError("Failed to get label", {
492
+ async trackByReference(reference) {
493
+ const response = await this.http.get(`/shipping/by_reference/${encodeURIComponent(reference)}`, this.errorOpts);
494
+ const shipment = response.data?.shipments?.[0];
495
+ if (!response.success || !shipment) {
496
+ throw new APIError("Shipment not found", {
431
497
  carrier: "aymakan",
432
498
  raw: response
433
499
  });
434
500
  }
435
- if (format === "PNG") {
436
- return response.data.label || response.data.awb_url || response.data.pdf_label;
501
+ return mapTrackingResult(shipment);
502
+ }
503
+ async getLabel(trackingNumber, _format) {
504
+ const response = await this.http.get(`/shipping/awb/tracking/${encodeURIComponent(trackingNumber)}`, this.errorOpts);
505
+ if (!response.success || !response.data?.awb_url) {
506
+ const msg = response.message ?? response.response ?? "Failed to get label";
507
+ throw new APIError(msg, { carrier: "aymakan", raw: response });
437
508
  }
438
- return response.data.pdf_label || response.data.awb_url || response.data.label;
509
+ return response.data.awb_url;
439
510
  }
440
511
  async getBulkLabels(trackingNumbers) {
441
- const response = await this.http.post("/shipping/bulk_awb_labels", {
442
- tracking_numbers: trackingNumbers
443
- });
444
- if (!response.success) {
445
- throw new APIError("Failed to get bulk labels", {
446
- carrier: "aymakan",
447
- raw: response
448
- });
512
+ const ids = trackingNumbers.map(encodeURIComponent).join(",");
513
+ const response = await this.http.get(`/shipping/bulk_awb/trackings/${ids}`, this.errorOpts);
514
+ if (!response.success || !response.data?.bulk_awb_url) {
515
+ const msg = response.message ?? response.response ?? "Failed to get bulk labels";
516
+ throw new APIError(msg, { carrier: "aymakan", raw: response });
449
517
  }
450
- return response.data.label_url;
518
+ return response.data.bulk_awb_url;
451
519
  }
452
520
  async getPickupCities() {
453
- const response = await this.http.get("/pickup_request/cities");
521
+ const response = await this.http.get("/pickup_request/cities", this.errorOpts);
454
522
  if (!response.success) {
455
523
  throw new APIError("Failed to get pickup cities", {
456
524
  carrier: "aymakan",
@@ -475,7 +543,7 @@ class AymakanAdapter extends BaseCarrierAdapter {
475
543
  await this.ensureCitiesLoaded();
476
544
  const resolvedInput = { ...input, city: this.resolveCity(input.city) };
477
545
  const request = mapPickupRequest(resolvedInput);
478
- const response = await this.http.post("/pickup_request/create", request);
546
+ const response = await this.http.post("/pickup_request/create", request, this.errorOpts);
479
547
  if (!response.success) {
480
548
  throw new APIError("Failed to create pickup", {
481
549
  carrier: "aymakan",
@@ -485,18 +553,22 @@ class AymakanAdapter extends BaseCarrierAdapter {
485
553
  return mapPickupResponse(response.data);
486
554
  }
487
555
  async cancelPickup(pickupId) {
488
- const response = await this.http.post(`/pickup_request/cancel/${encodeURIComponent(String(pickupId))}`);
489
- return response.success;
556
+ const response = await this.http.post("/pickup_request/cancel", { pickup_request: Number(pickupId) }, this.errorOpts);
557
+ return response.success === true;
490
558
  }
491
559
  async getPickupRequests() {
492
- const response = await this.http.get("/pickup_requests");
560
+ const response = await this.http.get("/pickup_request/list", this.errorOpts);
493
561
  if (!response.success) {
494
562
  throw new APIError("Failed to get pickup requests", {
495
563
  carrier: "aymakan",
496
564
  raw: response
497
565
  });
498
566
  }
499
- return response.data.pickup_requests.map(mapPickupResponse);
567
+ const list = response.data?.pickupRequests?.data;
568
+ if (!Array.isArray(list)) {
569
+ throw new APIError("Aymakan pickup list response is missing data.pickupRequests.data", { carrier: "aymakan", raw: response });
570
+ }
571
+ return list.map(mapPickupResponse);
500
572
  }
501
573
  async getCities() {
502
574
  const response = await this.http.get("/cities");
@@ -516,18 +588,19 @@ class AymakanAdapter extends BaseCarrierAdapter {
516
588
  raw: response
517
589
  });
518
590
  }
519
- return response.data.locations.map((loc) => ({
520
- id: String(loc.id),
591
+ return response.data.map((loc) => ({
592
+ id: loc.name,
521
593
  name: loc.name,
522
- nameAr: loc.name_ar,
523
594
  address: loc.address,
524
- city: loc.city
595
+ city: loc.city,
596
+ latitude: loc.location_lat ?? undefined,
597
+ longitude: loc.location_lng ?? undefined
525
598
  }));
526
599
  }
527
600
  async createCustomerAddress(address) {
528
601
  const request = mapCustomerAddressRequest(address);
529
- const response = await this.http.post("/address/create", request);
530
- if (!response.success) {
602
+ const response = await this.http.post("/address/create", request, this.errorOpts);
603
+ if (!response.success || !response.data?.address) {
531
604
  throw new APIError("Failed to create address", {
532
605
  carrier: "aymakan",
533
606
  raw: response
@@ -549,14 +622,17 @@ class AymakanAdapter extends BaseCarrierAdapter {
549
622
  };
550
623
  }
551
624
  async getCustomerAddresses() {
552
- const response = await this.http.get("/addresses");
625
+ const response = await this.http.get("/address/list", this.errorOpts);
553
626
  if (!response.success) {
554
627
  throw new APIError("Failed to get customer addresses", {
555
628
  carrier: "aymakan",
556
629
  raw: response
557
630
  });
558
631
  }
559
- return response.data.addresses.map((addr) => ({
632
+ if (!Array.isArray(response.data?.address)) {
633
+ throw new APIError("Aymakan address list response is missing data.address", { carrier: "aymakan", raw: response });
634
+ }
635
+ return response.data.address.map((addr) => ({
560
636
  id: addr.id,
561
637
  title: addr.title,
562
638
  name: addr.name,
@@ -571,7 +647,8 @@ class AymakanAdapter extends BaseCarrierAdapter {
571
647
  }));
572
648
  }
573
649
  async updateCustomerAddress(id, address) {
574
- const response = await this.http.put(`/address/update/${id}`, {
650
+ const response = await this.http.put("/address/update", {
651
+ id,
575
652
  title: address.title,
576
653
  name: address.name,
577
654
  email: address.email,
@@ -581,8 +658,8 @@ class AymakanAdapter extends BaseCarrierAdapter {
581
658
  postcode: address.postalCode,
582
659
  phone: address.phone,
583
660
  description: address.description
584
- });
585
- if (!response.success) {
661
+ }, this.errorOpts);
662
+ if (!response.success || !response.data?.address) {
586
663
  throw new APIError("Failed to update address", {
587
664
  carrier: "aymakan",
588
665
  raw: response
@@ -604,7 +681,7 @@ class AymakanAdapter extends BaseCarrierAdapter {
604
681
  };
605
682
  }
606
683
  async deleteCustomerAddress(id) {
607
- const response = await this.http.delete(`/address/delete/${id}`);
684
+ const response = await this.http.delete("/address/delete", { body: { id }, errorExtractor: aymakanErrorExtractor });
608
685
  return response.success;
609
686
  }
610
687
  parseWebhook(payload, options) {
@@ -622,4 +699,4 @@ export {
622
699
  AymakanAdapter
623
700
  };
624
701
 
625
- //# debugId=ECFB3CDDA31BC0F864756E2164756E21
702
+ //# debugId=52369388ABAA8E1964756E2164756E21