shipflow 0.1.1 → 0.3.0
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.
- package/README.md +179 -37
- package/dist/carriers/aramex/adapter.d.ts +7 -0
- package/dist/carriers/aramex/adapter.d.ts.map +1 -1
- package/dist/carriers/aramex/index.js +58 -23
- package/dist/carriers/aramex/index.js.map +4 -4
- package/dist/carriers/aramex/mappers.d.ts +8 -0
- package/dist/carriers/aramex/mappers.d.ts.map +1 -1
- package/dist/carriers/aymakan/adapter.d.ts +5 -0
- package/dist/carriers/aymakan/adapter.d.ts.map +1 -1
- package/dist/carriers/aymakan/index.js +96 -30
- package/dist/carriers/aymakan/index.js.map +4 -4
- package/dist/carriers/aymakan/mappers.d.ts +5 -0
- package/dist/carriers/aymakan/mappers.d.ts.map +1 -1
- package/dist/carriers/smsaexpress/index.js +22 -16
- package/dist/carriers/smsaexpress/index.js.map +3 -3
- package/dist/carriers/smsaexpress/mappers.d.ts.map +1 -1
- package/dist/core/errors.d.ts +19 -1
- package/dist/core/errors.d.ts.map +1 -1
- package/dist/core/http.d.ts +24 -3
- package/dist/core/http.d.ts.map +1 -1
- package/dist/core/retry.d.ts +42 -0
- package/dist/core/retry.d.ts.map +1 -0
- package/dist/core/schemas.d.ts +196 -812
- package/dist/core/schemas.d.ts.map +1 -1
- package/dist/index-qnxj8bct.js +1067 -0
- package/dist/index-qnxj8bct.js.map +15 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -2
- package/dist/index.js.map +2 -2
- package/package.json +4 -4
- package/dist/index-qjtxhwzv.js +0 -4602
- package/dist/index-qjtxhwzv.js.map +0 -22
|
@@ -3,10 +3,10 @@
|
|
|
3
3
|
"sources": ["../src/carriers/aramex/services.ts", "../src/carriers/aramex/mappers.ts", "../src/carriers/aramex/adapter.ts"],
|
|
4
4
|
"sourcesContent": [
|
|
5
5
|
"// file: src/carriers/aramex/services.ts\n/**\n * Aramex Service / Product Codes\n * Use these constants for type-safe product and payment selection.\n *\n * Reference: Aramex Shipping Services API manual, Appendix A (Product Types)\n * and Appendix B (Payment Types).\n */\n\n/** Shipment product group: domestic vs international/express. */\nexport const AramexProductGroup = {\n EXPRESS: \"EXP\",\n DOMESTIC: \"DOM\",\n} as const;\n\n/** Product type codes (Appendix A). `OND` is the only domestic type. */\nexport const AramexProductType = {\n /** Domestic (DOM group) */\n DOMESTIC: \"OND\",\n /** Priority Document Express */\n PRIORITY_DOCUMENT_EXPRESS: \"PDX\",\n /** Priority Parcel Express */\n PRIORITY_PARCEL_EXPRESS: \"PPX\",\n /** Priority Letter Express */\n PRIORITY_LETTER_EXPRESS: \"PLX\",\n /** Deferred Document Express */\n DEFERRED_DOCUMENT_EXPRESS: \"DDX\",\n /** Deferred Parcel Express */\n DEFERRED_PARCEL_EXPRESS: \"DPX\",\n /** Ground Document Express */\n GROUND_DOCUMENT_EXPRESS: \"GDX\",\n /** Ground Parcel Express */\n GROUND_PARCEL_EXPRESS: \"GPX\",\n /** Economy Parcel Express */\n ECONOMY_PARCEL_EXPRESS: \"EPX\",\n /** Return */\n RETURN: \"RTN\",\n} as const;\n\n/** Payment type codes (Appendix B). */\nexport const AramexPaymentType = {\n PREPAID: \"P\",\n COLLECT: \"C\",\n THIRD_PARTY: \"3\",\n} as const;\n\n/**\n * Special service codes joined (comma-separated) into `Details.Services`.\n * e.g. `\"CODS\"` enables Cash-On-Delivery handling.\n */\nexport const AramexService = {\n COD: \"CODS\",\n INSURANCE: \"INSR\",\n} as const;\n\nexport type AramexProductGroupType =\n (typeof AramexProductGroup)[keyof typeof AramexProductGroup];\nexport type AramexProductTypeCode =\n (typeof AramexProductType)[keyof typeof AramexProductType];\nexport type AramexPaymentTypeCode =\n (typeof AramexPaymentType)[keyof typeof AramexPaymentType];\n\n/**\n * Aramex Tracking Status Codes (`UpdateCode`) → unified ShipmentStatus.\n *\n * IMPORTANT: Aramex does not publish a stable, comprehensive `UpdateCode` list,\n * and the codes vary by region/account. This table is a best-effort starter —\n * entries marked `VERIFY` should be confirmed against live tracking data. The\n * mapper falls back to a description-keyword heuristic and then `\"unknown\"`, so\n * an unmapped code never breaks tracking.\n */\nexport const AramexStatusCodes = {\n \"SH001\": \"created\", // Shipment information received (VERIFY)\n \"SH002\": \"picked_up\", // Picked up from shipper (VERIFY)\n \"SH004\": \"at_warehouse\", // Received at origin facility (VERIFY)\n \"SH005\": \"out_for_delivery\", // Out on delivery courier\n \"SH014\": \"delivered\", // Shipment delivered (VERIFY)\n \"SH060\": \"in_transit\", // Departed / in transit (VERIFY)\n \"SH074\": \"exception\", // Delivery attempt failed (VERIFY)\n \"SH159\": \"exception\", // Held / customs / address problem (VERIFY)\n \"SH212\": \"returned\", // Returned to shipper (VERIFY)\n \"SH235\": \"delivered\", // Delivered (VERIFY)\n} as const;\n",
|
|
6
|
-
"// file: src/carriers/aramex/mappers.ts\n/**\n * Aramex Data Mappers\n * Transform between unified ShipFlow types and the Aramex JSON API formats.\n */\n\nimport type {\n Address,\n City,\n CreateShipmentInput,\n Dimensions,\n Location,\n Pickup,\n PickupRequest,\n Rate,\n Shipment,\n ShipmentStatus,\n TrackingEvent,\n TrackingResult,\n} from \"../../core/types\";\nimport {\n AramexProductType,\n AramexService,\n AramexStatusCodes,\n} from \"./services\";\nimport type {\n AramexCalculateRateResponse,\n AramexClientInfo,\n AramexContact,\n AramexDimensions,\n AramexMoney,\n AramexOffice,\n AramexParty,\n AramexPartyAddress,\n AramexPickupObject,\n AramexProcessedPickup,\n AramexProcessedShipment,\n AramexShipment,\n AramexShipmentDetails,\n AramexTrackingResult,\n AramexTrackShipmentsResponse,\n AramexWeight,\n} from \"./types\";\n\n// ============================================================================\n// CREDENTIALS / CLIENT INFO\n// ============================================================================\n\nexport interface AramexCredentials {\n userName: string;\n password: string;\n accountNumber: string;\n accountPin: string;\n accountEntity: string;\n accountCountryCode: string;\n}\n\n/** Build the ClientInfo block injected into every Aramex request body. */\nexport function buildClientInfo(\n credentials: AramexCredentials,\n opts?: { source?: number; version?: string },\n): AramexClientInfo {\n return {\n UserName: credentials.userName,\n Password: credentials.password,\n Version: opts?.version ?? \"v1.0\",\n AccountNumber: credentials.accountNumber,\n AccountPin: credentials.accountPin,\n AccountEntity: credentials.accountEntity,\n AccountCountryCode: credentials.accountCountryCode,\n Source: opts?.source ?? 24,\n };\n}\n\n// ============================================================================\n// STATUS MAPPING\n// ============================================================================\n\nexport function mapAramexStatus(\n updateCode: string,\n): ShipmentStatus | undefined {\n const mapped = AramexStatusCodes[updateCode as keyof typeof AramexStatusCodes];\n return mapped as ShipmentStatus | undefined;\n}\n\n/**\n * Secondary heuristic: derive a status from the human-readable update text when\n * the `UpdateCode` isn't in our table (Aramex codes vary by region). Ordered so\n * the more specific phrases win (e.g. \"out for delivery\" before \"delivered\").\n */\nexport function statusFromDescription(\n description: string | undefined,\n): ShipmentStatus | undefined {\n if (!description) return undefined;\n const d = description.toLowerCase();\n if (/out for delivery|on delivery|with delivery courier/.test(d))\n return \"out_for_delivery\";\n // Failure phrases must be checked before the generic \"deliver\" match, so\n // \"delivery failed\" / \"undeliverable\" aren't mistaken for a delivery.\n if (/fail|unable|undeliver|exception|held|on hold|problem|refused|damaged/.test(d))\n return \"exception\";\n if (/deliver/.test(d)) return \"delivered\";\n if (/return/.test(d)) return \"returned\";\n if (/cancel/.test(d)) return \"cancelled\";\n if (/picked up|collected|pickup/.test(d)) return \"picked_up\";\n if (/transit|departed|forwarded|en route/.test(d)) return \"in_transit\";\n if (/received at|arrived|facility|warehouse|sorting|hub/.test(d))\n return \"at_warehouse\";\n if (/created|information received|booked/.test(d)) return \"created\";\n return undefined;\n}\n\n// ============================================================================\n// DATES (WCF /Date(ms)/ format)\n// ============================================================================\n\n/** Parse an Aramex WCF date (`/Date(1609459200000+0300)/`) or ISO string. */\nexport function parseAramexDate(value: string | null | undefined): Date {\n if (!value) return new Date(Number.NaN);\n const wcf = /\\/Date\\((-?\\d+)(?:[+-]\\d{4})?\\)\\//.exec(value);\n if (wcf?.[1]) return new Date(Number.parseInt(wcf[1], 10));\n return new Date(value);\n}\n\nfunction toWcfDate(date: Date): string {\n return `/Date(${date.getTime()})/`;\n}\n\n// ============================================================================\n// HELPERS\n// ============================================================================\n\nfunction round(value: number): number {\n return Math.round(value * 1000) / 1000;\n}\n\nconst VALID_PRODUCT_TYPES = new Set(\n Object.values(AramexProductType) as string[],\n);\n\nfunction getMeta(\n input: CreateShipmentInput,\n key: string,\n): string | undefined {\n const value = input.options?.metadata?.[key];\n return typeof value === \"string\" ? value : undefined;\n}\n\n/**\n * Resolve ProductGroup (DOM/EXP) and ProductType. Defaults to domestic when\n * shipper and consignee share a country, else express. Overridable via\n * `serviceType` (a valid Aramex product code) or `options.metadata`.\n */\nexport function resolveProductGroupAndType(input: CreateShipmentInput): {\n productGroup: \"EXP\" | \"DOM\";\n productType: string;\n} {\n const sameCountry =\n input.shipper.countryCode.trim().toUpperCase() ===\n input.consignee.countryCode.trim().toUpperCase();\n\n const metaGroup = getMeta(input, \"productGroup\")?.toUpperCase();\n const productGroup: \"EXP\" | \"DOM\" =\n metaGroup === \"EXP\" || metaGroup === \"DOM\"\n ? metaGroup\n : sameCountry\n ? \"DOM\"\n : \"EXP\";\n\n const candidate = getMeta(input, \"productType\") ?? input.serviceType;\n const productType =\n candidate && VALID_PRODUCT_TYPES.has(candidate)\n ? candidate\n : productGroup === \"DOM\"\n ? AramexProductType.DOMESTIC\n : AramexProductType.ECONOMY_PARCEL_EXPRESS;\n\n return { productGroup, productType };\n}\n\nfunction resolvePaymentType(input: CreateShipmentInput): \"P\" | \"C\" | \"3\" {\n const meta = getMeta(input, \"paymentType\");\n if (meta === \"P\" || meta === \"C\" || meta === \"3\") return meta;\n return input.cod?.enabled ? \"C\" : \"P\";\n}\n\n/** Aggregate parcel weights; preserve the unit when uniform, else normalize to kg. */\nfunction aggregateWeight(input: CreateShipmentInput): AramexWeight {\n const allLb = input.parcels.every((p) => p.weight.unit === \"lb\");\n if (allLb) {\n const value = input.parcels.reduce((s, p) => s + p.weight.value, 0);\n return { Value: round(value), Unit: \"Lb\" };\n }\n const value = input.parcels.reduce(\n (s, p) =>\n s + (p.weight.unit === \"lb\" ? p.weight.value * 0.453592 : p.weight.value),\n 0,\n );\n return { Value: round(value), Unit: \"Kg\" };\n}\n\nfunction mapDimensions(dims?: Dimensions): AramexDimensions | null {\n if (!dims) return null;\n const factor = dims.unit === \"in\" ? 2.54 : 1;\n return {\n Length: round(dims.length * factor),\n Width: round(dims.width * factor),\n Height: round(dims.height * factor),\n Unit: \"CM\",\n };\n}\n\nfunction mapAddress(addr: Address): AramexPartyAddress {\n // Aramex's WCF `Address` contract marks Line2, Line3 and PostCode as REQUIRED\n // members — omitting them fails deserialization (\"required data members\n // 'Line2, Line3, PostCode' were not found\"). Always send them (empty if unset).\n return {\n Line1: addr.line1,\n Line2: addr.line2 ?? \"\",\n Line3: addr.neighbourhood ?? \"\",\n City: addr.city,\n StateOrProvinceCode: addr.state,\n PostCode: addr.postalCode ?? \"\",\n CountryCode: addr.countryCode,\n // Coordinates are optional in the contract; omit when unset so Aramex\n // doesn't treat a 0,0 default as a real location.\n Longitude: addr.coordinates?.longitude,\n Latitude: addr.coordinates?.latitude,\n };\n}\n\n/**\n * Build an Aramex `Contact`. Aramex's WCF Contact contract marks its string\n * members as REQUIRED (the same pattern confirmed live for Address and\n * Transaction — an empty value fails deserialization, an empty string is\n * accepted), so every member is sent, defaulting to \"\".\n */\nfunction buildContact(opts: {\n personName: string;\n companyName: string;\n phone: string;\n email?: string;\n}): AramexContact {\n return {\n Department: \"\",\n PersonName: opts.personName,\n Title: \"\",\n CompanyName: opts.companyName,\n PhoneNumber1: opts.phone,\n PhoneNumber1Ext: \"\",\n PhoneNumber2: \"\",\n CellPhone: opts.phone,\n EmailAddress: opts.email ?? \"\",\n Type: \"\",\n };\n}\n\nfunction mapContact(addr: Address, fallbackCompany?: string): AramexContact {\n return buildContact({\n personName: addr.name,\n companyName: addr.company ?? fallbackCompany ?? addr.name,\n phone: addr.phone,\n email: addr.email,\n });\n}\n\nfunction mapParty(\n addr: Address,\n accountNumber?: string,\n fallbackCompany?: string,\n): AramexParty {\n return {\n AccountNumber: accountNumber,\n PartyAddress: mapAddress(addr),\n Contact: mapContact(addr, fallbackCompany),\n };\n}\n\n/** Shared between CreateShipments and CalculateRate. */\nfunction mapShipmentDetails(\n input: CreateShipmentInput,\n productGroup: \"EXP\" | \"DOM\",\n productType: string,\n paymentType: \"P\" | \"C\" | \"3\",\n): AramexShipmentDetails {\n const numberOfPieces =\n input.parcels.reduce((s, p) => s + p.pieces, 0) || 1;\n const description =\n input.parcels\n .map((p) => p.description)\n .filter(Boolean)\n .join(\", \") || \"Goods\";\n\n const services: string[] = [];\n let cashOnDelivery: AramexMoney | null = null;\n if (input.cod?.enabled) {\n // Use the caller-supplied COD currency — never hardcode.\n cashOnDelivery = {\n Value: input.cod.amount,\n CurrencyCode: input.cod.currency,\n };\n services.push(AramexService.COD);\n }\n\n const customsValue: AramexMoney | null = input.declaredValue\n ? {\n Value: input.declaredValue.amount,\n CurrencyCode: input.declaredValue.currency,\n }\n : null;\n\n // Insurance (INSR) must be accompanied by an amount to insure. Aramex rejects\n // the service with a null InsuranceAmount, so only request it when a declared\n // value is present to base the insured amount on.\n const insuranceAmount: AramexMoney | null =\n input.options?.isInsured && customsValue ? customsValue : null;\n if (insuranceAmount) services.push(AramexService.INSURANCE);\n\n return {\n Dimensions: mapDimensions(input.parcels[0]?.dimensions),\n ActualWeight: aggregateWeight(input),\n ChargeableWeight: null,\n DescriptionOfGoods: description,\n GoodsOriginCountry: input.shipper.countryCode,\n NumberOfPieces: numberOfPieces,\n ProductGroup: productGroup,\n ProductType: productType,\n PaymentType: paymentType,\n PaymentOptions: \"\",\n CustomsValueAmount: customsValue,\n CashOnDeliveryAmount: cashOnDelivery,\n InsuranceAmount: insuranceAmount,\n Services: services.join(\",\") || undefined,\n };\n}\n\n// ============================================================================\n// REQUEST MAPPERS\n// ============================================================================\n\nexport interface AramexShipmentContext {\n accountNumber: string;\n companyName?: string;\n}\n\nexport function mapCreateShipmentRequest(\n input: CreateShipmentInput,\n ctx: AramexShipmentContext,\n): AramexShipment {\n const { productGroup, productType } = resolveProductGroupAndType(input);\n const paymentType = resolvePaymentType(input);\n const now = new Date();\n const due = new Date(now.getTime() + 24 * 60 * 60 * 1000);\n\n return {\n Reference1: input.reference,\n Reference2: input.options?.customerTracking,\n Shipper: mapParty(input.shipper, ctx.accountNumber, ctx.companyName),\n Consignee: mapParty(input.consignee),\n ThirdParty: null,\n ShippingDateTime: toWcfDate(now),\n DueDate: toWcfDate(due),\n Comments: getMeta(input, \"comments\"),\n PickupLocation: getMeta(input, \"pickupLocation\"),\n Details: mapShipmentDetails(input, productGroup, productType, paymentType),\n Attachments: null,\n ForeignHAWB: null,\n TransportType: 0,\n Number: null,\n };\n}\n\nexport function mapCalculateRateRequest(\n input: CreateShipmentInput,\n preferredCurrency?: string,\n): {\n OriginAddress: AramexPartyAddress;\n DestinationAddress: AramexPartyAddress;\n ShipmentDetails: AramexShipmentDetails;\n PreferredCurrencyCode?: string;\n} {\n const { productGroup, productType } = resolveProductGroupAndType(input);\n const paymentType = resolvePaymentType(input);\n return {\n OriginAddress: mapAddress(input.shipper),\n DestinationAddress: mapAddress(input.consignee),\n ShipmentDetails: mapShipmentDetails(\n input,\n productGroup,\n productType,\n paymentType,\n ),\n PreferredCurrencyCode:\n preferredCurrency ??\n input.cod?.currency ??\n input.declaredValue?.currency,\n };\n}\n\nexport interface AramexPickupContext {\n accountNumber: string;\n countryCode: string;\n companyName?: string;\n}\n\nexport function mapPickupRequest(\n input: PickupRequest,\n ctx: AramexPickupContext,\n): AramexPickupObject {\n const pickupDate = new Date(`${input.date}T00:00:00`);\n const ready = new Date(`${input.date}T09:00:00`);\n const closing = new Date(`${input.date}T17:00:00`);\n\n return {\n Reference1: input.trackingNumbers?.[0],\n PickupAddress: {\n Line1: input.address,\n City: input.city,\n CountryCode: ctx.countryCode,\n },\n PickupContact: buildContact({\n personName: input.contactName,\n companyName: ctx.companyName ?? input.contactName,\n phone: input.contactPhone,\n }),\n PickupLocation: \"Reception\",\n PickupDate: toWcfDate(pickupDate),\n ReadyTime: toWcfDate(ready),\n LastPickupTime: toWcfDate(closing),\n ClosingTime: toWcfDate(closing),\n Comments: input.timeSlot,\n Status: \"Ready\",\n PickupItems: {\n PickupItemDetail: [\n {\n ProductGroup: \"DOM\",\n ProductType: AramexProductType.DOMESTIC,\n Payment: \"P\",\n NumberOfShipments: input.shipmentCount,\n NumberOfPieces: input.shipmentCount,\n ShipmentWeight: { Value: 1, Unit: \"Kg\" },\n },\n ],\n },\n };\n}\n\n// ============================================================================\n// RESPONSE MAPPERS\n// ============================================================================\n\nexport function mapShipmentResponse(\n processed: AramexProcessedShipment,\n input?: CreateShipmentInput,\n): Shipment {\n const trackingNumber = processed.ID || processed.ShipmentNumber || \"\";\n const labelUrl = processed.ShipmentLabel?.LabelURL || undefined;\n\n return {\n carrier: \"aramex\",\n trackingNumber,\n customerTracking: input?.options?.customerTracking,\n reference: input?.reference,\n // Aramex returns no status code on create — the shipment is freshly created.\n status: \"created\",\n statusLabel: \"Created\",\n labelUrl,\n pdfLabelUrl: labelUrl,\n codAmount: input?.cod?.enabled ? input.cod.amount : undefined,\n declaredValue: input?.declaredValue?.amount,\n currency:\n input?.cod?.currency ?? input?.declaredValue?.currency ?? \"SAR\",\n createdAt: new Date(),\n raw: processed,\n };\n}\n\nexport function mapTrackingEvent(\n result: AramexTrackingResult,\n): TrackingEvent {\n return {\n timestamp: parseAramexDate(result.UpdateDateTime),\n statusCode: result.UpdateCode,\n status:\n mapAramexStatus(result.UpdateCode) ??\n statusFromDescription(result.UpdateDescription) ??\n \"unknown\",\n description: result.UpdateDescription,\n location: result.UpdateLocation || undefined,\n };\n}\n\nexport function mapTrackingResult(\n waybill: string,\n results: AramexTrackingResult[],\n): TrackingResult {\n const events = results\n .map(mapTrackingEvent)\n .sort((a, b) => b.timestamp.getTime() - a.timestamp.getTime());\n\n const latest = events[0];\n const delivered = events.find((e) => e.status === \"delivered\");\n\n // Pull a weight from the most recent raw result that reports one.\n const weightStr = [...results]\n .reverse()\n .find((r) => r.GrossWeight)?.GrossWeight;\n const weight = weightStr ? Number.parseFloat(weightStr) : undefined;\n\n return {\n trackingNumber: waybill,\n carrier: \"aramex\",\n status: latest?.status ?? \"unknown\",\n statusLabel: latest?.description ?? \"Unknown\",\n events,\n deliveryDate: delivered?.timestamp,\n weight: weight != null && !Number.isNaN(weight) ? weight : undefined,\n raw: results,\n };\n}\n\n/**\n * Normalize the `TrackingResults` envelope into a plain map. The WCF JSON\n * serializer renders the dictionary as `[{ Key, Value }]`, but some gateways\n * return a plain object map instead — accept both.\n */\nexport function normalizeTrackingResults(\n raw: AramexTrackShipmentsResponse[\"TrackingResults\"],\n): Record<string, AramexTrackingResult[]> {\n if (!raw) return {};\n if (Array.isArray(raw)) {\n const map: Record<string, AramexTrackingResult[]> = {};\n for (const kv of raw) {\n if (kv && typeof kv === \"object\" && \"Key\" in kv) {\n map[kv.Key] = kv.Value ?? [];\n }\n }\n return map;\n }\n return raw;\n}\n\nexport function mapRate(\n response: AramexCalculateRateResponse,\n input: CreateShipmentInput,\n): Rate {\n const { productType } = resolveProductGroupAndType(input);\n return {\n carrier: \"aramex\",\n serviceType: productType,\n serviceName: productType,\n amount: response.TotalAmount?.Value ?? 0,\n currency:\n response.TotalAmount?.CurrencyCode ??\n input.cod?.currency ??\n input.declaredValue?.currency ??\n \"SAR\",\n raw: response,\n };\n}\n\nexport function mapPickupResponse(\n processed: AramexProcessedPickup,\n input: PickupRequest,\n): Pickup {\n return {\n id: processed.GUID || processed.ID,\n carrier: \"aramex\",\n status: \"pending\",\n date: input.date,\n timeSlot: input.timeSlot,\n city: input.city,\n contactName: input.contactName,\n contactPhone: input.contactPhone,\n address: input.address,\n shipmentCount: input.shipmentCount,\n createdAt: new Date(),\n raw: processed,\n };\n}\n\nexport function mapCity(name: string): City {\n return { nameEn: name };\n}\n\nexport function mapOffice(office: AramexOffice): Location {\n const addr = office.Address;\n const lines = [addr?.Line1, addr?.Line2, addr?.Line3].filter(Boolean);\n return {\n id: office.EntityCode,\n name: office.EntityName ?? office.EntityCode,\n address: lines.length ? lines.join(\", \") : undefined,\n city: addr?.City,\n latitude: addr?.Latitude,\n longitude: addr?.Longitude,\n };\n}\n",
|
|
7
|
-
"// file: src/carriers/aramex/adapter.ts\n/**\n * Aramex Carrier Adapter\n * Implementation of the CarrierAdapter interface for the Aramex JSON Shipping\n * Services API v2.\n *\n * Key differences from the other carriers:\n * - Auth is a `ClientInfo` object sent in EVERY request body (not headers).\n * - The four Aramex services (Shipping, Tracking, RateCalculator, Location)\n * live on different base URLs, so the adapter holds one HttpClient per service.\n * - Errors use the \"Fake 200 OK\" pattern (HTTP 200 + `HasErrors`/`Notifications`),\n * surfaced via the shared HttpClient's `errorExtractor` hook on every call.\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 CarrierConfig,\n City,\n CreateShipmentInput,\n Location,\n Pickup,\n PickupRequest,\n Rate,\n Shipment,\n TrackingResult,\n} from \"../../core/types\";\nimport { BaseCarrierAdapter } from \"../base\";\nimport {\n buildClientInfo,\n mapCalculateRateRequest,\n mapCity,\n mapCreateShipmentRequest,\n mapOffice,\n mapPickupRequest,\n mapPickupResponse,\n mapRate,\n mapShipmentResponse,\n mapTrackingResult,\n normalizeTrackingResults,\n} from \"./mappers\";\nimport type {\n AramexCalculateRateResponse,\n AramexClientInfo,\n AramexCreatePickupResponse,\n AramexCancelPickupResponse,\n AramexCreateShipmentsResponse,\n AramexFetchCitiesResponse,\n AramexFetchOfficesResponse,\n AramexLabelInfo,\n AramexNotification,\n AramexPrintLabelResponse,\n AramexTrackShipmentsResponse,\n} from \"./types\";\n\nconst SHIPPING_SANDBOX_URL =\n \"https://ws.dev.aramex.net/ShippingAPI.V2/Shipping/Service_1_0.svc\";\nconst SHIPPING_PRODUCTION_URL =\n \"https://ws.aramex.net/ShippingAPI.V2/Shipping/Service_1_0.svc\";\n\n/** Default Aramex label report (HTML/PDF label at 9.7x21cm), returned as a URL. */\nconst DEFAULT_LABEL_INFO: AramexLabelInfo = {\n ReportID: 9201,\n ReportType: \"URL\",\n};\n\n/**\n * Aramex's WCF `Transaction` data contract marks Reference1–Reference5 as\n * REQUIRED members, so an empty `{}` fails deserialization (\"required data\n * members 'Reference1..Reference5' were not found\") on every operation. All five\n * must be present; empty strings are accepted.\n */\nconst EMPTY_TRANSACTION = {\n Reference1: \"\",\n Reference2: \"\",\n Reference3: \"\",\n Reference4: \"\",\n Reference5: \"\",\n} as const;\n\nexport interface AramexConfig extends CarrierConfig {\n credentials: {\n userName: string;\n password: string;\n accountNumber: string;\n accountPin: string;\n accountEntity: string;\n accountCountryCode: string;\n };\n /** API source channel (default 24). */\n source?: number;\n /** ClientInfo version (default \"v1.0\"). */\n version?: string;\n /** Company name used when an address has no company set. */\n companyName?: string;\n /**\n * Optional override for the Location service base URL. Live Aramex WSDLs\n * disagree on the production Location host (ws.aramex.net vs anfe02.aramex.com);\n * set this if your account is provisioned on a different host.\n */\n locationBaseUrl?: string;\n}\n\nexport class AramexAdapter extends BaseCarrierAdapter {\n readonly name = \"aramex\";\n readonly supportedCountries = [\n \"SA\",\n \"AE\",\n \"BH\",\n \"KW\",\n \"OM\",\n \"QA\",\n \"JO\",\n \"EG\",\n \"LB\",\n \"IQ\",\n ];\n\n private shippingHttp: HttpClient;\n private trackingHttp: HttpClient;\n private rateHttp: HttpClient;\n private locationHttp: HttpClient;\n\n constructor(config: AramexConfig) {\n super(config);\n const shippingBase = this.getBaseUrl();\n const common = {\n carrier: \"aramex\",\n // Aramex auth lives in the request body (ClientInfo), so no auth headers.\n };\n this.shippingHttp = new HttpClient({ ...common, baseUrl: shippingBase });\n this.trackingHttp = new HttpClient({\n ...common,\n baseUrl: this.serviceBase(shippingBase, \"Tracking\"),\n });\n this.rateHttp = new HttpClient({\n ...common,\n baseUrl: this.serviceBase(shippingBase, \"RateCalculator\"),\n });\n this.locationHttp = new HttpClient({\n ...common,\n baseUrl:\n config.locationBaseUrl ?? this.serviceBase(shippingBase, \"Location\"),\n });\n }\n\n protected getBaseUrl(): string {\n return this.config.mode === \"production\"\n ? SHIPPING_PRODUCTION_URL\n : SHIPPING_SANDBOX_URL;\n }\n\n /** Derive a sibling service base URL by swapping the `/Shipping/` segment. */\n private serviceBase(shippingBase: string, service: string): string {\n return shippingBase.replace(\"/Shipping/\", `/${service}/`);\n }\n\n private get aramexConfig(): AramexConfig {\n return this.config as AramexConfig;\n }\n\n private buildClientInfo(): AramexClientInfo {\n const cfg = this.aramexConfig;\n return buildClientInfo(cfg.credentials, {\n source: cfg.source,\n version: cfg.version,\n });\n }\n\n /**\n * Extracts the Aramex \"Fake 200 OK\" error (envelope-level `HasErrors` +\n * `Notifications`). Passed to every request so the HttpClient raises APIError.\n */\n private static aramexErrorExtractor(json: unknown): {\n hasError: boolean;\n message?: string;\n errors?: Record<string, string[]>;\n } {\n const obj = json as {\n HasErrors?: boolean;\n Notifications?: AramexNotification[];\n } | null;\n const notifications = obj?.Notifications ?? [];\n const hasError = obj?.HasErrors === true;\n const message =\n notifications\n .map((n) => n?.Message)\n .filter(Boolean)\n .join(\"; \") || (hasError ? \"Aramex returned an error\" : undefined);\n return {\n hasError,\n message,\n errors: notifications.length\n ? AramexAdapter.notificationsToErrors(notifications)\n : undefined,\n };\n }\n\n private static notificationsToErrors(\n notifications: AramexNotification[],\n ): Record<string, string[]> {\n return {\n _aramex: notifications.map((n) =>\n `${n?.Code ?? \"\"}: ${n?.Message ?? \"\"}`.trim(),\n ),\n };\n }\n\n // =========================================================================\n // SHIPPING\n // =========================================================================\n\n protected async executeCreateShipment(\n input: CreateShipmentInput,\n ): Promise<Shipment> {\n const cfg = this.aramexConfig;\n const shipment = mapCreateShipmentRequest(input, {\n accountNumber: cfg.credentials.accountNumber,\n companyName: cfg.companyName,\n });\n\n const response = await this.shippingHttp.post<AramexCreateShipmentsResponse>(\n \"/json/CreateShipments\",\n {\n ClientInfo: this.buildClientInfo(),\n Transaction: EMPTY_TRANSACTION,\n LabelInfo: DEFAULT_LABEL_INFO,\n Shipments: [shipment],\n },\n { errorExtractor: AramexAdapter.aramexErrorExtractor },\n );\n\n const processed = response.Shipments?.[0];\n if (!processed) {\n throw new APIError(\"Aramex returned no shipment\", {\n carrier: \"aramex\",\n raw: response,\n });\n }\n\n // CreateShipments can also fail per-shipment while the envelope is clean.\n if (processed.HasErrors) {\n const notifications = processed.Notifications ?? [];\n throw new APIError(\n notifications\n .map((n) => n.Message)\n .filter(Boolean)\n .join(\"; \") || \"Failed to create shipment\",\n {\n carrier: \"aramex\",\n errors: AramexAdapter.notificationsToErrors(notifications),\n raw: processed,\n },\n );\n }\n\n return mapShipmentResponse(processed, input);\n }\n\n /**\n * Create multiple shipments in a single request. Aramex's `CreateShipments`\n * operation is natively batch — it takes a `Shipments` array and returns one\n * processed result per shipment, in request order.\n *\n * Fails loud: if ANY shipment in the batch errors, an `APIError` is thrown\n * whose `raw` holds the full response, so already-created AWBs remain\n * recoverable (the unified `Shipment` type has no per-item error channel).\n */\n async createBulkShipments(\n inputs: CreateShipmentInput[],\n ): Promise<Shipment[]> {\n if (inputs.length === 0) {\n throw new ValidationError(\n \"At least one shipment is required for bulk create\",\n { raw: { count: 0 } },\n );\n }\n for (const input of inputs) validateCreateShipmentInput(input);\n\n const cfg = this.aramexConfig;\n const shipments = inputs.map((input) =>\n mapCreateShipmentRequest(input, {\n accountNumber: cfg.credentials.accountNumber,\n companyName: cfg.companyName,\n }),\n );\n\n const response = await this.shippingHttp.post<AramexCreateShipmentsResponse>(\n \"/json/CreateShipments\",\n {\n ClientInfo: this.buildClientInfo(),\n Transaction: EMPTY_TRANSACTION,\n LabelInfo: DEFAULT_LABEL_INFO,\n Shipments: shipments,\n },\n { errorExtractor: AramexAdapter.aramexErrorExtractor },\n );\n\n const processed = response.Shipments ?? [];\n if (processed.length === 0) {\n throw new APIError(\"Aramex returned no shipments\", {\n carrier: \"aramex\",\n raw: response,\n });\n }\n\n const failed = processed.filter((p) => p.HasErrors);\n if (failed.length > 0) {\n const notifications = failed.flatMap((p) => p.Notifications ?? []);\n throw new APIError(\n notifications\n .map((n) => n.Message)\n .filter(Boolean)\n .join(\"; \") ||\n `Failed to create ${failed.length} of ${processed.length} shipments`,\n {\n carrier: \"aramex\",\n errors: AramexAdapter.notificationsToErrors(notifications),\n raw: response,\n },\n );\n }\n\n return processed.map((p, i) => mapShipmentResponse(p, inputs[i]));\n }\n\n /**\n * Aramex's classic Shipping Services API has no shipment-cancellation\n * endpoint, so this is unsupported. (Pickups can be cancelled via cancelPickup.)\n */\n cancelShipment(_trackingNumber: string): Promise<boolean> {\n throw new UnsupportedOperationError(\"aramex\", \"cancelShipment\");\n }\n\n // =========================================================================\n // LABELS\n // =========================================================================\n\n async getLabel(\n trackingNumber: string,\n _format?: \"PDF\" | \"ZPL\" | \"PNG\",\n ): Promise<string> {\n // Aramex PrintLabel returns a URL to the label document. The requested\n // `format` cannot be honored (ZPL/PNG are not selectable) — always a URL.\n const response = await this.shippingHttp.post<AramexPrintLabelResponse>(\n \"/json/PrintLabel\",\n {\n ClientInfo: this.buildClientInfo(),\n Transaction: EMPTY_TRANSACTION,\n ShipmentNumber: trackingNumber,\n LabelInfo: DEFAULT_LABEL_INFO,\n },\n { errorExtractor: AramexAdapter.aramexErrorExtractor },\n );\n\n const url = response.ShipmentLabel?.LabelURL;\n if (!url) {\n throw new APIError(\"Failed to get label\", {\n carrier: \"aramex\",\n raw: response,\n });\n }\n return url;\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\", {\n carrier: \"aramex\",\n raw: { trackingNumber },\n });\n }\n return result;\n }\n\n async trackMultiple(trackingNumbers: string[]): Promise<TrackingResult[]> {\n const response = await this.trackingHttp.post<AramexTrackShipmentsResponse>(\n \"/json/TrackShipments\",\n {\n ClientInfo: this.buildClientInfo(),\n Transaction: EMPTY_TRANSACTION,\n Shipments: trackingNumbers,\n GetLastTrackingUpdateOnly: false,\n },\n { retry: true, errorExtractor: AramexAdapter.aramexErrorExtractor },\n );\n\n const map = normalizeTrackingResults(response.TrackingResults);\n return Object.entries(map).map(([waybill, results]) =>\n mapTrackingResult(waybill, results),\n );\n }\n\n async trackByReference(reference: string): Promise<TrackingResult> {\n // Aramex tracks references through the same TrackShipments operation.\n const result = await this.track(reference);\n return { ...result, reference };\n }\n\n // =========================================================================\n // RATES\n // =========================================================================\n\n async getRates(input: CreateShipmentInput): Promise<Rate[]> {\n const rateRequest = mapCalculateRateRequest(input);\n const response = await this.rateHttp.post<AramexCalculateRateResponse>(\n \"/json/CalculateRate\",\n {\n ClientInfo: this.buildClientInfo(),\n Transaction: EMPTY_TRANSACTION,\n ...rateRequest,\n },\n { retry: true, errorExtractor: AramexAdapter.aramexErrorExtractor },\n );\n\n // A clean envelope with no TotalAmount means Aramex couldn't price the\n // route. Surface it as an error rather than returning a misleading 0 rate.\n if (response.TotalAmount?.Value == null) {\n throw new APIError(\"Aramex returned no rate for this shipment\", {\n carrier: \"aramex\",\n raw: response,\n });\n }\n\n return [mapRate(response, input)];\n }\n\n // =========================================================================\n // PICKUPS\n // =========================================================================\n\n async createPickup(input: PickupRequest): Promise<Pickup> {\n validatePickupRequest(input);\n const cfg = this.aramexConfig;\n const pickup = mapPickupRequest(input, {\n accountNumber: cfg.credentials.accountNumber,\n countryCode: cfg.credentials.accountCountryCode,\n companyName: cfg.companyName,\n });\n\n const response = await this.shippingHttp.post<AramexCreatePickupResponse>(\n \"/json/CreatePickup\",\n {\n ClientInfo: this.buildClientInfo(),\n Transaction: EMPTY_TRANSACTION,\n Pickup: pickup,\n },\n { errorExtractor: AramexAdapter.aramexErrorExtractor },\n );\n\n // Judge success on the body payload, not the HTTP status: a \"Fake 200 OK\"\n // can carry an empty ProcessedPickup. A usable pickup needs a GUID (or ID).\n const processed = response.ProcessedPickup;\n if (!processed || (!processed.GUID && !processed.ID)) {\n throw new APIError(\"Failed to create pickup\", {\n carrier: \"aramex\",\n raw: response,\n });\n }\n\n return mapPickupResponse(processed, input);\n }\n\n async cancelPickup(pickupId: string | number): Promise<boolean> {\n const response = await this.shippingHttp.post<AramexCancelPickupResponse>(\n \"/json/CancelPickup\",\n {\n ClientInfo: this.buildClientInfo(),\n Transaction: EMPTY_TRANSACTION,\n PickupGUID: String(pickupId),\n },\n { errorExtractor: AramexAdapter.aramexErrorExtractor },\n );\n // The errorExtractor already throws on `HasErrors: true`, so reaching here\n // means the body reported no error — judge success from that, treating a\n // missing flag as success (consistent with the extractor's `=== true`).\n return response.HasErrors !== true;\n }\n\n // =========================================================================\n // CITIES & LOCATIONS\n // =========================================================================\n\n async getCities(countryCode?: string): Promise<City[]> {\n const response = await this.locationHttp.post<AramexFetchCitiesResponse>(\n \"/json/FetchCities\",\n {\n ClientInfo: this.buildClientInfo(),\n Transaction: EMPTY_TRANSACTION,\n CountryCode:\n countryCode ?? this.aramexConfig.credentials.accountCountryCode,\n },\n { retry: true, errorExtractor: AramexAdapter.aramexErrorExtractor },\n );\n\n return (response.Cities ?? []).map(mapCity);\n }\n\n async getDropoffLocations(countryCode?: string): Promise<Location[]> {\n const response = await this.locationHttp.post<AramexFetchOfficesResponse>(\n \"/json/FetchOffices\",\n {\n ClientInfo: this.buildClientInfo(),\n Transaction: EMPTY_TRANSACTION,\n CountryCode:\n countryCode ?? this.aramexConfig.credentials.accountCountryCode,\n },\n { retry: true, errorExtractor: AramexAdapter.aramexErrorExtractor },\n );\n\n return (response.Offices ?? []).map(mapOffice);\n }\n}\n"
|
|
6
|
+
"// file: src/carriers/aramex/mappers.ts\n/**\n * Aramex Data Mappers\n * Transform between unified ShipFlow types and the Aramex JSON API formats.\n */\n\nimport type {\n Address,\n City,\n CreateShipmentInput,\n Dimensions,\n Location,\n Pickup,\n PickupRequest,\n Rate,\n Shipment,\n ShipmentStatus,\n TrackingEvent,\n TrackingResult,\n} from \"../../core/types\";\nimport {\n AramexProductType,\n AramexService,\n AramexStatusCodes,\n} from \"./services\";\nimport type {\n AramexCalculateRateResponse,\n AramexClientInfo,\n AramexContact,\n AramexDimensions,\n AramexMoney,\n AramexOffice,\n AramexParty,\n AramexPartyAddress,\n AramexPickupObject,\n AramexProcessedPickup,\n AramexProcessedShipment,\n AramexShipment,\n AramexShipmentDetails,\n AramexTrackingResult,\n AramexTrackShipmentsResponse,\n AramexWeight,\n} from \"./types\";\n\n// ============================================================================\n// CREDENTIALS / CLIENT INFO\n// ============================================================================\n\nexport interface AramexCredentials {\n userName: string;\n password: string;\n accountNumber: string;\n accountPin: string;\n accountEntity: string;\n accountCountryCode: string;\n}\n\n/** Build the ClientInfo block injected into every Aramex request body. */\nexport function buildClientInfo(\n credentials: AramexCredentials,\n opts?: { source?: number; version?: string },\n): AramexClientInfo {\n return {\n UserName: credentials.userName,\n Password: credentials.password,\n Version: opts?.version ?? \"v1.0\",\n AccountNumber: credentials.accountNumber,\n AccountPin: credentials.accountPin,\n AccountEntity: credentials.accountEntity,\n AccountCountryCode: credentials.accountCountryCode,\n Source: opts?.source ?? 24,\n };\n}\n\n// ============================================================================\n// STATUS MAPPING\n// ============================================================================\n\nexport function mapAramexStatus(\n updateCode: string,\n): ShipmentStatus | undefined {\n const mapped = AramexStatusCodes[updateCode as keyof typeof AramexStatusCodes];\n return mapped as ShipmentStatus | undefined;\n}\n\n/**\n * Secondary heuristic: derive a status from the human-readable update text when\n * the `UpdateCode` isn't in our table (Aramex codes vary by region). Ordered so\n * the more specific phrases win (e.g. \"out for delivery\" before \"delivered\").\n */\nexport function statusFromDescription(\n description: string | undefined,\n): ShipmentStatus | undefined {\n if (!description) return undefined;\n const d = description.toLowerCase();\n if (/out for delivery|on delivery|with delivery courier/.test(d))\n return \"out_for_delivery\";\n // Failure phrases must be checked before the generic \"deliver\" match, so\n // \"delivery failed\" / \"undeliverable\" aren't mistaken for a delivery.\n if (/fail|unable|undeliver|exception|held|on hold|problem|refused|damaged/.test(d))\n return \"exception\";\n if (/deliver/.test(d)) return \"delivered\";\n if (/return/.test(d)) return \"returned\";\n if (/cancel/.test(d)) return \"cancelled\";\n if (/picked up|collected|pickup/.test(d)) return \"picked_up\";\n if (/transit|departed|forwarded|en route/.test(d)) return \"in_transit\";\n if (/received at|arrived|facility|warehouse|sorting|hub/.test(d))\n return \"at_warehouse\";\n if (/created|information received|booked/.test(d)) return \"created\";\n return undefined;\n}\n\n// ============================================================================\n// DATES (WCF /Date(ms)/ format)\n// ============================================================================\n\n/** Parse an Aramex WCF date (`/Date(1609459200000+0300)/`) or ISO string. */\nexport function parseAramexDate(value: string | null | undefined): Date {\n if (!value) return new Date(Number.NaN);\n const wcf = /\\/Date\\((-?\\d+)(?:[+-]\\d{4})?\\)\\//.exec(value);\n if (wcf?.[1]) return new Date(Number.parseInt(wcf[1], 10));\n return new Date(value);\n}\n\nfunction toWcfDate(date: Date): string {\n return `/Date(${date.getTime()})/`;\n}\n\n// ============================================================================\n// HELPERS\n// ============================================================================\n\nfunction round(value: number): number {\n return Math.round(value * 1000) / 1000;\n}\n\nconst VALID_PRODUCT_TYPES = new Set(\n Object.values(AramexProductType) as string[],\n);\n\nfunction getMeta(\n input: CreateShipmentInput,\n key: string,\n): string | undefined {\n const value = input.options?.metadata?.[key];\n return typeof value === \"string\" ? value : undefined;\n}\n\n/**\n * Resolve ProductGroup (DOM/EXP) and ProductType. Defaults to domestic when\n * shipper and consignee share a country, else express. Overridable via\n * `serviceType` (a valid Aramex product code) or `options.metadata`.\n */\nexport function resolveProductGroupAndType(input: CreateShipmentInput): {\n productGroup: \"EXP\" | \"DOM\";\n productType: string;\n} {\n const sameCountry =\n input.shipper.countryCode.trim().toUpperCase() ===\n input.consignee.countryCode.trim().toUpperCase();\n\n const metaGroup = getMeta(input, \"productGroup\")?.toUpperCase();\n const productGroup: \"EXP\" | \"DOM\" =\n metaGroup === \"EXP\" || metaGroup === \"DOM\"\n ? metaGroup\n : sameCountry\n ? \"DOM\"\n : \"EXP\";\n\n const candidate = getMeta(input, \"productType\") ?? input.serviceType;\n const productType =\n candidate && VALID_PRODUCT_TYPES.has(candidate)\n ? candidate\n : productGroup === \"DOM\"\n ? AramexProductType.DOMESTIC\n : AramexProductType.ECONOMY_PARCEL_EXPRESS;\n\n return { productGroup, productType };\n}\n\n/**\n * Resolve the freight PaymentType — who pays the SHIPPING cost: P = prepaid\n * (billed to the shipper's Aramex account), C = collect (charged to the\n * consignee), 3 = third party.\n *\n * This is INDEPENDENT of COD. COD is the cash collected from the consignee for\n * the goods, carried by the `CODS` service + `CashOnDeliveryAmount` — not by\n * PaymentType. KSA/GCC e-commerce COD is overwhelmingly prepaid freight (billed\n * to the merchant) with the goods value collected on delivery, so freight\n * defaults to \"P\". Enabling COD must NOT force freight onto the consignee.\n * Override the freight payer with `options.metadata.paymentType`.\n */\nfunction resolvePaymentType(input: CreateShipmentInput): \"P\" | \"C\" | \"3\" {\n const meta = getMeta(input, \"paymentType\");\n if (meta === \"P\" || meta === \"C\" || meta === \"3\") return meta;\n return \"P\";\n}\n\n/** Aggregate parcel weights; preserve the unit when uniform, else normalize to kg. */\nfunction aggregateWeight(input: CreateShipmentInput): AramexWeight {\n const allLb = input.parcels.every((p) => p.weight.unit === \"lb\");\n if (allLb) {\n const value = input.parcels.reduce((s, p) => s + p.weight.value, 0);\n return { Value: round(value), Unit: \"Lb\" };\n }\n const value = input.parcels.reduce(\n (s, p) =>\n s + (p.weight.unit === \"lb\" ? p.weight.value * 0.453592 : p.weight.value),\n 0,\n );\n return { Value: round(value), Unit: \"Kg\" };\n}\n\nfunction mapDimensions(dims?: Dimensions): AramexDimensions | null {\n if (!dims) return null;\n const factor = dims.unit === \"in\" ? 2.54 : 1;\n return {\n Length: round(dims.length * factor),\n Width: round(dims.width * factor),\n Height: round(dims.height * factor),\n Unit: \"CM\",\n };\n}\n\n/**\n * Build an Aramex `PartyAddress` with every WCF-required member present. The\n * contract marks `Line2`, `Line3` and `PostCode` as REQUIRED — omitting any\n * fails deserialization (\"required data members 'Line2, Line3, PostCode' were\n * not found\") — so they default to \"\" rather than being dropped. Coordinates\n * stay optional and are omitted when unset, so a 0,0 default is never sent as a\n * real location. This is the single source of truth for the address shape;\n * every Aramex address (shipper, consignee, pickup) goes through it.\n */\nfunction buildPartyAddress(fields: {\n line1: string;\n line2?: string;\n line3?: string;\n city: string;\n state?: string;\n postCode?: string;\n countryCode: string;\n coordinates?: { latitude: number; longitude: number };\n}): AramexPartyAddress {\n return {\n Line1: fields.line1,\n Line2: fields.line2 ?? \"\",\n Line3: fields.line3 ?? \"\",\n City: fields.city,\n StateOrProvinceCode: fields.state,\n PostCode: fields.postCode ?? \"\",\n CountryCode: fields.countryCode,\n Longitude: fields.coordinates?.longitude,\n Latitude: fields.coordinates?.latitude,\n };\n}\n\nfunction mapAddress(addr: Address): AramexPartyAddress {\n return buildPartyAddress({\n line1: addr.line1,\n line2: addr.line2,\n line3: addr.neighbourhood,\n city: addr.city,\n state: addr.state,\n postCode: addr.postalCode,\n countryCode: addr.countryCode,\n coordinates: addr.coordinates,\n });\n}\n\n/**\n * Build an Aramex `Contact`. Aramex's WCF Contact contract marks its string\n * members as REQUIRED (the same pattern confirmed live for Address and\n * Transaction — an empty value fails deserialization, an empty string is\n * accepted), so every member is sent, defaulting to \"\".\n */\nfunction buildContact(opts: {\n personName: string;\n companyName: string;\n phone: string;\n email?: string;\n}): AramexContact {\n return {\n Department: \"\",\n PersonName: opts.personName,\n Title: \"\",\n CompanyName: opts.companyName,\n PhoneNumber1: opts.phone,\n PhoneNumber1Ext: \"\",\n PhoneNumber2: \"\",\n CellPhone: opts.phone,\n EmailAddress: opts.email ?? \"\",\n Type: \"\",\n };\n}\n\nfunction mapContact(addr: Address, fallbackCompany?: string): AramexContact {\n return buildContact({\n personName: addr.name,\n companyName: addr.company ?? fallbackCompany ?? addr.name,\n phone: addr.phone,\n email: addr.email,\n });\n}\n\nfunction mapParty(\n addr: Address,\n accountNumber?: string,\n fallbackCompany?: string,\n): AramexParty {\n return {\n AccountNumber: accountNumber,\n PartyAddress: mapAddress(addr),\n Contact: mapContact(addr, fallbackCompany),\n };\n}\n\n/** Shared between CreateShipments and CalculateRate. */\nfunction mapShipmentDetails(\n input: CreateShipmentInput,\n productGroup: \"EXP\" | \"DOM\",\n productType: string,\n paymentType: \"P\" | \"C\" | \"3\",\n): AramexShipmentDetails {\n const numberOfPieces =\n input.parcels.reduce((s, p) => s + p.pieces, 0) || 1;\n const description =\n input.parcels\n .map((p) => p.description)\n .filter(Boolean)\n .join(\", \") || \"Goods\";\n\n const services: string[] = [];\n let cashOnDelivery: AramexMoney | null = null;\n if (input.cod?.enabled) {\n // Use the caller-supplied COD currency — never hardcode.\n cashOnDelivery = {\n Value: input.cod.amount,\n CurrencyCode: input.cod.currency,\n };\n services.push(AramexService.COD);\n }\n\n const customsValue: AramexMoney | null = input.declaredValue\n ? {\n Value: input.declaredValue.amount,\n CurrencyCode: input.declaredValue.currency,\n }\n : null;\n\n // Insurance (INSR) must be accompanied by an amount to insure. Aramex rejects\n // the service with a null InsuranceAmount, so only request it when a declared\n // value is present to base the insured amount on.\n const insuranceAmount: AramexMoney | null =\n input.options?.isInsured && customsValue ? customsValue : null;\n if (insuranceAmount) services.push(AramexService.INSURANCE);\n\n return {\n Dimensions: mapDimensions(input.parcels[0]?.dimensions),\n ActualWeight: aggregateWeight(input),\n ChargeableWeight: null,\n DescriptionOfGoods: description,\n GoodsOriginCountry: input.shipper.countryCode,\n NumberOfPieces: numberOfPieces,\n ProductGroup: productGroup,\n ProductType: productType,\n PaymentType: paymentType,\n PaymentOptions: \"\",\n CustomsValueAmount: customsValue,\n CashOnDeliveryAmount: cashOnDelivery,\n InsuranceAmount: insuranceAmount,\n Services: services.join(\",\") || undefined,\n };\n}\n\n// ============================================================================\n// REQUEST MAPPERS\n// ============================================================================\n\nexport interface AramexShipmentContext {\n accountNumber: string;\n companyName?: string;\n}\n\nexport function mapCreateShipmentRequest(\n input: CreateShipmentInput,\n ctx: AramexShipmentContext,\n): AramexShipment {\n const { productGroup, productType } = resolveProductGroupAndType(input);\n const paymentType = resolvePaymentType(input);\n const now = new Date();\n const due = new Date(now.getTime() + 24 * 60 * 60 * 1000);\n\n return {\n Reference1: input.reference,\n Reference2: input.options?.customerTracking,\n Shipper: mapParty(input.shipper, ctx.accountNumber, ctx.companyName),\n Consignee: mapParty(input.consignee),\n ThirdParty: null,\n ShippingDateTime: toWcfDate(now),\n DueDate: toWcfDate(due),\n Comments: getMeta(input, \"comments\"),\n PickupLocation: getMeta(input, \"pickupLocation\"),\n Details: mapShipmentDetails(input, productGroup, productType, paymentType),\n Attachments: null,\n ForeignHAWB: null,\n TransportType: 0,\n Number: null,\n };\n}\n\nexport function mapCalculateRateRequest(\n input: CreateShipmentInput,\n preferredCurrency?: string,\n): {\n OriginAddress: AramexPartyAddress;\n DestinationAddress: AramexPartyAddress;\n ShipmentDetails: AramexShipmentDetails;\n PreferredCurrencyCode?: string;\n} {\n const { productGroup, productType } = resolveProductGroupAndType(input);\n const paymentType = resolvePaymentType(input);\n return {\n OriginAddress: mapAddress(input.shipper),\n DestinationAddress: mapAddress(input.consignee),\n ShipmentDetails: mapShipmentDetails(\n input,\n productGroup,\n productType,\n paymentType,\n ),\n PreferredCurrencyCode:\n preferredCurrency ??\n input.cod?.currency ??\n input.declaredValue?.currency,\n };\n}\n\nexport interface AramexPickupContext {\n accountNumber: string;\n countryCode: string;\n companyName?: string;\n}\n\nexport function mapPickupRequest(\n input: PickupRequest,\n ctx: AramexPickupContext,\n): AramexPickupObject {\n const pickupDate = new Date(`${input.date}T00:00:00`);\n const ready = new Date(`${input.date}T09:00:00`);\n const closing = new Date(`${input.date}T17:00:00`);\n\n return {\n Reference1: input.trackingNumbers?.[0],\n // Routed through buildPartyAddress so the pickup address carries the same\n // WCF-required members (Line2/Line3/PostCode) as shipper/consignee — a\n // hand-built address that omits them fails Aramex deserialization.\n PickupAddress: buildPartyAddress({\n line1: input.address,\n city: input.city,\n countryCode: ctx.countryCode,\n }),\n PickupContact: buildContact({\n personName: input.contactName,\n companyName: ctx.companyName ?? input.contactName,\n phone: input.contactPhone,\n }),\n PickupLocation: \"Reception\",\n PickupDate: toWcfDate(pickupDate),\n ReadyTime: toWcfDate(ready),\n LastPickupTime: toWcfDate(closing),\n ClosingTime: toWcfDate(closing),\n Comments: input.timeSlot,\n Status: \"Ready\",\n PickupItems: {\n PickupItemDetail: [\n {\n ProductGroup: \"DOM\",\n ProductType: AramexProductType.DOMESTIC,\n Payment: \"P\",\n NumberOfShipments: input.shipmentCount,\n NumberOfPieces: input.shipmentCount,\n ShipmentWeight: { Value: 1, Unit: \"Kg\" },\n },\n ],\n },\n };\n}\n\n// ============================================================================\n// RESPONSE MAPPERS\n// ============================================================================\n\nexport function mapShipmentResponse(\n processed: AramexProcessedShipment,\n input?: CreateShipmentInput,\n): Shipment {\n const trackingNumber = processed.ID || processed.ShipmentNumber || \"\";\n const labelUrl = processed.ShipmentLabel?.LabelURL || undefined;\n\n return {\n carrier: \"aramex\",\n trackingNumber,\n customerTracking: input?.options?.customerTracking,\n reference: input?.reference,\n // Aramex returns no status code on create — the shipment is freshly created.\n status: \"created\",\n statusLabel: \"Created\",\n labelUrl,\n pdfLabelUrl: labelUrl,\n codAmount: input?.cod?.enabled ? input.cod.amount : undefined,\n declaredValue: input?.declaredValue?.amount,\n currency:\n input?.cod?.currency ?? input?.declaredValue?.currency ?? \"SAR\",\n createdAt: new Date(),\n raw: processed,\n };\n}\n\nexport function mapTrackingEvent(\n result: AramexTrackingResult,\n): TrackingEvent {\n return {\n timestamp: parseAramexDate(result.UpdateDateTime),\n statusCode: result.UpdateCode,\n status:\n mapAramexStatus(result.UpdateCode) ??\n statusFromDescription(result.UpdateDescription) ??\n \"unknown\",\n description: result.UpdateDescription,\n location: result.UpdateLocation || undefined,\n };\n}\n\nexport function mapTrackingResult(\n waybill: string,\n results: AramexTrackingResult[],\n): TrackingResult {\n const events = results\n .map(mapTrackingEvent)\n .sort((a, b) => b.timestamp.getTime() - a.timestamp.getTime());\n\n const latest = events[0];\n const delivered = events.find((e) => e.status === \"delivered\");\n\n // Pull a weight from the most recent raw result that reports one.\n const weightStr = [...results]\n .reverse()\n .find((r) => r.GrossWeight)?.GrossWeight;\n const weight = weightStr ? Number.parseFloat(weightStr) : undefined;\n\n return {\n trackingNumber: waybill,\n carrier: \"aramex\",\n status: latest?.status ?? \"unknown\",\n statusLabel: latest?.description ?? \"Unknown\",\n events,\n deliveryDate: delivered?.timestamp,\n weight: weight != null && !Number.isNaN(weight) ? weight : undefined,\n raw: results,\n };\n}\n\n/**\n * Normalize the `TrackingResults` envelope into a plain map. The WCF JSON\n * serializer renders the dictionary as `[{ Key, Value }]`, but some gateways\n * return a plain object map instead — accept both.\n */\nexport function normalizeTrackingResults(\n raw: AramexTrackShipmentsResponse[\"TrackingResults\"],\n): Record<string, AramexTrackingResult[]> {\n if (!raw) return {};\n if (Array.isArray(raw)) {\n const map: Record<string, AramexTrackingResult[]> = {};\n for (const kv of raw) {\n if (kv && typeof kv === \"object\" && \"Key\" in kv) {\n map[kv.Key] = kv.Value ?? [];\n }\n }\n return map;\n }\n return raw;\n}\n\n/**\n * Build a placeholder `TrackingResult` for a waybill Aramex reports under\n * `NonExistingWaybills`. Aramex splits the TrackShipments response into found\n * (`TrackingResults`) and not-found (`NonExistingWaybills`) buckets; emitting an\n * \"unknown\" entry for the latter keeps the returned array aligned to the input\n * waybills so callers can map inputs→results positionally/by trackingNumber.\n */\nexport function mapNonExistingWaybill(waybill: string): TrackingResult {\n return {\n trackingNumber: waybill,\n carrier: \"aramex\",\n status: \"unknown\",\n statusLabel: \"Waybill not found\",\n events: [],\n raw: { nonExisting: true, waybill },\n };\n}\n\nexport function mapRate(\n response: AramexCalculateRateResponse,\n input: CreateShipmentInput,\n): Rate {\n const { productType } = resolveProductGroupAndType(input);\n return {\n carrier: \"aramex\",\n serviceType: productType,\n serviceName: productType,\n amount: response.TotalAmount?.Value ?? 0,\n currency:\n response.TotalAmount?.CurrencyCode ??\n input.cod?.currency ??\n input.declaredValue?.currency ??\n \"SAR\",\n raw: response,\n };\n}\n\nexport function mapPickupResponse(\n processed: AramexProcessedPickup,\n input: PickupRequest,\n): Pickup {\n // CancelPickup keys on the GUID (PickupGUID), NOT the numeric ID — a pickup\n // that also carries an ID must still surface the GUID as its `id` so the\n // round-trip createPickup → cancelPickup works. Prefer GUID; only fall back\n // to ID when no GUID is present (cancellation then isn't possible, but the\n // caller still gets a usable identifier).\n return {\n id: processed.GUID || processed.ID,\n carrier: \"aramex\",\n status: \"pending\",\n date: input.date,\n timeSlot: input.timeSlot,\n city: input.city,\n contactName: input.contactName,\n contactPhone: input.contactPhone,\n address: input.address,\n shipmentCount: input.shipmentCount,\n createdAt: new Date(),\n raw: processed,\n };\n}\n\nexport function mapCity(name: string): City {\n return { nameEn: name };\n}\n\nexport function mapOffice(office: AramexOffice): Location {\n const addr = office.Address;\n const lines = [addr?.Line1, addr?.Line2, addr?.Line3].filter(Boolean);\n return {\n id: office.EntityCode,\n name: office.EntityName ?? office.EntityCode,\n address: lines.length ? lines.join(\", \") : undefined,\n city: addr?.City,\n latitude: addr?.Latitude,\n longitude: addr?.Longitude,\n };\n}\n",
|
|
7
|
+
"// file: src/carriers/aramex/adapter.ts\n/**\n * Aramex Carrier Adapter\n * Implementation of the CarrierAdapter interface for the Aramex JSON Shipping\n * Services API v2.\n *\n * Key differences from the other carriers:\n * - Auth is a `ClientInfo` object sent in EVERY request body (not headers).\n * - The four Aramex services (Shipping, Tracking, RateCalculator, Location)\n * live on different base URLs, so the adapter holds one HttpClient per service.\n * - Errors use the \"Fake 200 OK\" pattern (HTTP 200 + `HasErrors`/`Notifications`),\n * surfaced via the shared HttpClient's `errorExtractor` hook on every call.\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 CarrierConfig,\n City,\n CreateShipmentInput,\n Location,\n Pickup,\n PickupRequest,\n Rate,\n Shipment,\n TrackingResult,\n} from \"../../core/types\";\nimport { BaseCarrierAdapter } from \"../base\";\nimport {\n buildClientInfo,\n mapCalculateRateRequest,\n mapCity,\n mapCreateShipmentRequest,\n mapNonExistingWaybill,\n mapOffice,\n mapPickupRequest,\n mapPickupResponse,\n mapRate,\n mapShipmentResponse,\n mapTrackingResult,\n normalizeTrackingResults,\n} from \"./mappers\";\nimport type {\n AramexCalculateRateResponse,\n AramexClientInfo,\n AramexCreatePickupResponse,\n AramexCancelPickupResponse,\n AramexCreateShipmentsResponse,\n AramexFetchCitiesResponse,\n AramexFetchOfficesResponse,\n AramexLabelInfo,\n AramexNotification,\n AramexPrintLabelResponse,\n AramexTrackShipmentsResponse,\n} from \"./types\";\n\nconst SHIPPING_SANDBOX_URL =\n \"https://ws.dev.aramex.net/ShippingAPI.V2/Shipping/Service_1_0.svc\";\nconst SHIPPING_PRODUCTION_URL =\n \"https://ws.aramex.net/ShippingAPI.V2/Shipping/Service_1_0.svc\";\n\n/** Default Aramex label report (HTML/PDF label at 9.7x21cm), returned as a URL. */\nconst DEFAULT_LABEL_INFO: AramexLabelInfo = {\n ReportID: 9201,\n ReportType: \"URL\",\n};\n\n/**\n * Aramex's WCF `Transaction` data contract marks Reference1–Reference5 as\n * REQUIRED members, so an empty `{}` fails deserialization (\"required data\n * members 'Reference1..Reference5' were not found\") on every operation. All five\n * must be present; empty strings are accepted.\n */\nconst EMPTY_TRANSACTION = {\n Reference1: \"\",\n Reference2: \"\",\n Reference3: \"\",\n Reference4: \"\",\n Reference5: \"\",\n} as const;\n\nexport interface AramexConfig extends CarrierConfig {\n credentials: {\n userName: string;\n password: string;\n accountNumber: string;\n accountPin: string;\n accountEntity: string;\n accountCountryCode: string;\n };\n /** API source channel (default 24). */\n source?: number;\n /** ClientInfo version (default \"v1.0\"). */\n version?: string;\n /** Company name used when an address has no company set. */\n companyName?: string;\n /**\n * Optional override for the Location service base URL. Live Aramex WSDLs\n * disagree on the production Location host (ws.aramex.net vs anfe02.aramex.com);\n * set this if your account is provisioned on a different host.\n */\n locationBaseUrl?: string;\n}\n\nexport class AramexAdapter extends BaseCarrierAdapter {\n readonly name = \"aramex\";\n readonly supportedCountries = [\n \"SA\",\n \"AE\",\n \"BH\",\n \"KW\",\n \"OM\",\n \"QA\",\n \"JO\",\n \"EG\",\n \"LB\",\n \"IQ\",\n ];\n\n private shippingHttp: HttpClient;\n private trackingHttp: HttpClient;\n private rateHttp: HttpClient;\n private locationHttp: HttpClient;\n\n constructor(config: AramexConfig) {\n super(config);\n const shippingBase = this.getBaseUrl();\n const common = {\n carrier: \"aramex\",\n // Aramex auth lives in the request body (ClientInfo), so no auth headers.\n };\n this.shippingHttp = new HttpClient({ ...common, baseUrl: shippingBase });\n this.trackingHttp = new HttpClient({\n ...common,\n baseUrl: this.serviceBase(shippingBase, \"Tracking\"),\n });\n this.rateHttp = new HttpClient({\n ...common,\n baseUrl: this.serviceBase(shippingBase, \"RateCalculator\"),\n });\n this.locationHttp = new HttpClient({\n ...common,\n baseUrl:\n config.locationBaseUrl ?? this.serviceBase(shippingBase, \"Location\"),\n });\n }\n\n protected getBaseUrl(): string {\n return this.config.mode === \"production\"\n ? SHIPPING_PRODUCTION_URL\n : SHIPPING_SANDBOX_URL;\n }\n\n /** Derive a sibling service base URL by swapping the `/Shipping/` segment. */\n private serviceBase(shippingBase: string, service: string): string {\n return shippingBase.replace(\"/Shipping/\", `/${service}/`);\n }\n\n private get aramexConfig(): AramexConfig {\n return this.config as AramexConfig;\n }\n\n private buildClientInfo(): AramexClientInfo {\n const cfg = this.aramexConfig;\n return buildClientInfo(cfg.credentials, {\n source: cfg.source,\n version: cfg.version,\n });\n }\n\n /**\n * Extracts the Aramex \"Fake 200 OK\" error (envelope-level `HasErrors` +\n * `Notifications`). Passed to every request so the HttpClient raises APIError.\n */\n /**\n * Aramex reports throttling inside its \"fake 200\" envelope (and sometimes on a\n * non-429 status) rather than via HTTP 429, so status-code detection misses it.\n * Match the rate-limit wording in the notifications and flag it so the\n * HttpClient raises a retryable `RateLimitError` instead of a plain APIError.\n */\n private static readonly RATE_LIMIT_PATTERN =\n /rate.?limit|too many request|throttl|quota exceeded/i;\n\n private static aramexErrorExtractor(json: unknown): {\n hasError: boolean;\n message?: string;\n errors?: Record<string, string[]>;\n rateLimited?: boolean;\n } {\n const obj = json as {\n HasErrors?: boolean;\n Notifications?: AramexNotification[];\n } | null;\n const notifications = obj?.Notifications ?? [];\n const hasError = obj?.HasErrors === true;\n const message =\n notifications\n .map((n) => n?.Message)\n .filter(Boolean)\n .join(\"; \") || (hasError ? \"Aramex returned an error\" : undefined);\n return {\n hasError,\n message,\n errors: notifications.length\n ? AramexAdapter.notificationsToErrors(notifications)\n : undefined,\n rateLimited:\n hasError && AramexAdapter.RATE_LIMIT_PATTERN.test(message ?? \"\"),\n };\n }\n\n private static notificationsToErrors(\n notifications: AramexNotification[],\n ): Record<string, string[]> {\n return {\n _aramex: notifications.map((n) =>\n `${n?.Code ?? \"\"}: ${n?.Message ?? \"\"}`.trim(),\n ),\n };\n }\n\n // =========================================================================\n // SHIPPING\n // =========================================================================\n\n protected async executeCreateShipment(\n input: CreateShipmentInput,\n ): Promise<Shipment> {\n const cfg = this.aramexConfig;\n const shipment = mapCreateShipmentRequest(input, {\n accountNumber: cfg.credentials.accountNumber,\n companyName: cfg.companyName,\n });\n\n const response = await this.shippingHttp.post<AramexCreateShipmentsResponse>(\n \"/json/CreateShipments\",\n {\n ClientInfo: this.buildClientInfo(),\n Transaction: EMPTY_TRANSACTION,\n LabelInfo: DEFAULT_LABEL_INFO,\n Shipments: [shipment],\n },\n { errorExtractor: AramexAdapter.aramexErrorExtractor },\n );\n\n const processed = response.Shipments?.[0];\n if (!processed) {\n throw new APIError(\"Aramex returned no shipment\", {\n carrier: \"aramex\",\n raw: response,\n });\n }\n\n // CreateShipments can also fail per-shipment while the envelope is clean.\n if (processed.HasErrors) {\n const notifications = processed.Notifications ?? [];\n throw new APIError(\n notifications\n .map((n) => n.Message)\n .filter(Boolean)\n .join(\"; \") || \"Failed to create shipment\",\n {\n carrier: \"aramex\",\n errors: AramexAdapter.notificationsToErrors(notifications),\n raw: processed,\n },\n );\n }\n\n return mapShipmentResponse(processed, input);\n }\n\n /**\n * Create multiple shipments in a single request. Aramex's `CreateShipments`\n * operation is natively batch — it takes a `Shipments` array and returns one\n * processed result per shipment, in request order.\n *\n * Fails loud: if ANY shipment in the batch errors, an `APIError` is thrown\n * whose `raw` holds the full response, so already-created AWBs remain\n * recoverable (the unified `Shipment` type has no per-item error channel).\n */\n async createBulkShipments(\n inputs: CreateShipmentInput[],\n ): Promise<Shipment[]> {\n if (inputs.length === 0) {\n throw new ValidationError(\n \"At least one shipment is required for bulk create\",\n { raw: { count: 0 } },\n );\n }\n for (const input of inputs) validateCreateShipmentInput(input);\n\n const cfg = this.aramexConfig;\n const shipments = inputs.map((input) =>\n mapCreateShipmentRequest(input, {\n accountNumber: cfg.credentials.accountNumber,\n companyName: cfg.companyName,\n }),\n );\n\n const response = await this.shippingHttp.post<AramexCreateShipmentsResponse>(\n \"/json/CreateShipments\",\n {\n ClientInfo: this.buildClientInfo(),\n Transaction: EMPTY_TRANSACTION,\n LabelInfo: DEFAULT_LABEL_INFO,\n Shipments: shipments,\n },\n { errorExtractor: AramexAdapter.aramexErrorExtractor },\n );\n\n const processed = response.Shipments ?? [];\n if (processed.length === 0) {\n throw new APIError(\"Aramex returned no shipments\", {\n carrier: \"aramex\",\n raw: response,\n });\n }\n\n const failed = processed.filter((p) => p.HasErrors);\n if (failed.length > 0) {\n const notifications = failed.flatMap((p) => p.Notifications ?? []);\n throw new APIError(\n notifications\n .map((n) => n.Message)\n .filter(Boolean)\n .join(\"; \") ||\n `Failed to create ${failed.length} of ${processed.length} shipments`,\n {\n carrier: \"aramex\",\n errors: AramexAdapter.notificationsToErrors(notifications),\n raw: response,\n },\n );\n }\n\n return processed.map((p, i) => mapShipmentResponse(p, inputs[i]));\n }\n\n /**\n * Aramex's classic Shipping Services API has no shipment-cancellation\n * endpoint, so this is unsupported. (Pickups can be cancelled via cancelPickup.)\n */\n cancelShipment(_trackingNumber: string): Promise<boolean> {\n throw new UnsupportedOperationError(\"aramex\", \"cancelShipment\");\n }\n\n // =========================================================================\n // LABELS\n // =========================================================================\n\n async getLabel(\n trackingNumber: string,\n _format?: \"PDF\" | \"ZPL\" | \"PNG\",\n ): Promise<string> {\n // Aramex PrintLabel returns a URL to the label document. The requested\n // `format` cannot be honored (ZPL/PNG are not selectable) — always a URL.\n const response = await this.shippingHttp.post<AramexPrintLabelResponse>(\n \"/json/PrintLabel\",\n {\n ClientInfo: this.buildClientInfo(),\n Transaction: EMPTY_TRANSACTION,\n ShipmentNumber: trackingNumber,\n LabelInfo: DEFAULT_LABEL_INFO,\n },\n // PrintLabel is a side-effect-free read (it returns a URL for an existing\n // shipment), so it's safe to retry like the other read operations.\n { retry: true, errorExtractor: AramexAdapter.aramexErrorExtractor },\n );\n\n const url = response.ShipmentLabel?.LabelURL;\n if (!url) {\n throw new APIError(\"Failed to get label\", {\n carrier: \"aramex\",\n raw: response,\n });\n }\n return url;\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 // trackMultiple now emits an \"unknown\"/not-found entry for waybills Aramex\n // returns under NonExistingWaybills, so a missing-or-not-found waybill must\n // raise a precise not-found rather than returning a misleading \"unknown\".\n if (!result || (result.status === \"unknown\" && result.events.length === 0)) {\n throw new APIError(\"Shipment not found\", {\n carrier: \"aramex\",\n raw: result?.raw ?? { trackingNumber },\n });\n }\n return result;\n }\n\n async trackMultiple(trackingNumbers: string[]): Promise<TrackingResult[]> {\n const response = await this.trackingHttp.post<AramexTrackShipmentsResponse>(\n \"/json/TrackShipments\",\n {\n ClientInfo: this.buildClientInfo(),\n Transaction: EMPTY_TRANSACTION,\n Shipments: trackingNumbers,\n GetLastTrackingUpdateOnly: false,\n },\n { retry: true, errorExtractor: AramexAdapter.aramexErrorExtractor },\n );\n\n const map = normalizeTrackingResults(response.TrackingResults);\n const found = Object.entries(map).map(([waybill, results]) =>\n mapTrackingResult(waybill, results),\n );\n\n // Aramex returns not-found waybills in a separate NonExistingWaybills bucket\n // rather than as empty TrackingResults. Surface them as \"unknown\" entries so\n // the returned array stays aligned to the input waybills (callers can map\n // inputs→results); silently dropping them desynchronizes that mapping.\n const nonExisting = (response.NonExistingWaybills ?? []).map(\n mapNonExistingWaybill,\n );\n\n return [...found, ...nonExisting];\n }\n\n async trackByReference(reference: string): Promise<TrackingResult> {\n // Aramex tracks references through the same TrackShipments operation.\n const result = await this.track(reference);\n return { ...result, reference };\n }\n\n // =========================================================================\n // RATES\n // =========================================================================\n\n async getRates(input: CreateShipmentInput): Promise<Rate[]> {\n const rateRequest = mapCalculateRateRequest(input);\n const response = await this.rateHttp.post<AramexCalculateRateResponse>(\n \"/json/CalculateRate\",\n {\n ClientInfo: this.buildClientInfo(),\n Transaction: EMPTY_TRANSACTION,\n ...rateRequest,\n },\n { retry: true, errorExtractor: AramexAdapter.aramexErrorExtractor },\n );\n\n // A clean envelope with no TotalAmount means Aramex couldn't price the\n // route. Surface it as an error rather than returning a misleading 0 rate.\n if (response.TotalAmount?.Value == null) {\n throw new APIError(\"Aramex returned no rate for this shipment\", {\n carrier: \"aramex\",\n raw: response,\n });\n }\n\n return [mapRate(response, input)];\n }\n\n // =========================================================================\n // PICKUPS\n // =========================================================================\n\n async createPickup(input: PickupRequest): Promise<Pickup> {\n validatePickupRequest(input);\n const cfg = this.aramexConfig;\n const pickup = mapPickupRequest(input, {\n accountNumber: cfg.credentials.accountNumber,\n countryCode: cfg.credentials.accountCountryCode,\n companyName: cfg.companyName,\n });\n\n const response = await this.shippingHttp.post<AramexCreatePickupResponse>(\n \"/json/CreatePickup\",\n {\n ClientInfo: this.buildClientInfo(),\n Transaction: EMPTY_TRANSACTION,\n Pickup: pickup,\n },\n { errorExtractor: AramexAdapter.aramexErrorExtractor },\n );\n\n // Judge success on the body payload, not the HTTP status: a \"Fake 200 OK\"\n // can carry an empty ProcessedPickup. A usable pickup needs a GUID — that's\n // the key CancelPickup requires (PickupGUID), so a pickup with only a\n // numeric ID can't be cancelled and isn't a usable round-trip result.\n const processed = response.ProcessedPickup;\n if (!processed || (!processed.GUID && !processed.ID)) {\n throw new APIError(\"Failed to create pickup\", {\n carrier: \"aramex\",\n raw: response,\n });\n }\n\n // A pickup can succeed at the header level (it has a GUID) while individual\n // shipments inside it fail (ProcessedShipments[].HasErrors). Those per-\n // shipment errors are otherwise swallowed — scan and surface them so a\n // partially-failed pickup isn't reported as a clean success.\n const failedShipments = (processed.ProcessedShipments ?? []).filter(\n (s) => s.HasErrors,\n );\n if (failedShipments.length > 0) {\n const notifications = failedShipments.flatMap((s) => s.Notifications ?? []);\n throw new APIError(\n notifications\n .map((n) => n.Message)\n .filter(Boolean)\n .join(\"; \") ||\n `Pickup created but ${failedShipments.length} shipment(s) failed`,\n {\n carrier: \"aramex\",\n errors: AramexAdapter.notificationsToErrors(notifications),\n raw: response,\n },\n );\n }\n\n return mapPickupResponse(processed, input);\n }\n\n async cancelPickup(pickupId: string | number): Promise<boolean> {\n const response = await this.shippingHttp.post<AramexCancelPickupResponse>(\n \"/json/CancelPickup\",\n {\n ClientInfo: this.buildClientInfo(),\n Transaction: EMPTY_TRANSACTION,\n PickupGUID: String(pickupId),\n },\n { errorExtractor: AramexAdapter.aramexErrorExtractor },\n );\n // The errorExtractor already throws on `HasErrors: true`, so reaching here\n // means the body reported no error — judge success from that, treating a\n // missing flag as success (consistent with the extractor's `=== true`).\n return response.HasErrors !== true;\n }\n\n // =========================================================================\n // CITIES & LOCATIONS\n // =========================================================================\n\n async getCities(countryCode?: string): Promise<City[]> {\n const response = await this.locationHttp.post<AramexFetchCitiesResponse>(\n \"/json/FetchCities\",\n {\n ClientInfo: this.buildClientInfo(),\n Transaction: EMPTY_TRANSACTION,\n CountryCode:\n countryCode ?? this.aramexConfig.credentials.accountCountryCode,\n },\n { retry: true, errorExtractor: AramexAdapter.aramexErrorExtractor },\n );\n\n return (response.Cities ?? []).map(mapCity);\n }\n\n async getDropoffLocations(countryCode?: string): Promise<Location[]> {\n const response = await this.locationHttp.post<AramexFetchOfficesResponse>(\n \"/json/FetchOffices\",\n {\n ClientInfo: this.buildClientInfo(),\n Transaction: EMPTY_TRANSACTION,\n CountryCode:\n countryCode ?? this.aramexConfig.credentials.accountCountryCode,\n },\n { retry: true, errorExtractor: AramexAdapter.aramexErrorExtractor },\n );\n\n return (response.Offices ?? []).map(mapOffice);\n }\n}\n"
|
|
8
8
|
],
|
|
9
|
-
"mappings": "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",
|
|
10
|
-
"debugId": "
|
|
9
|
+
"mappings": "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",
|
|
10
|
+
"debugId": "A6EBA2B597BA645F64756E2164756E21",
|
|
11
11
|
"names": []
|
|
12
12
|
}
|
|
@@ -61,6 +61,14 @@ export declare function mapTrackingResult(waybill: string, results: AramexTracki
|
|
|
61
61
|
* return a plain object map instead — accept both.
|
|
62
62
|
*/
|
|
63
63
|
export declare function normalizeTrackingResults(raw: AramexTrackShipmentsResponse["TrackingResults"]): Record<string, AramexTrackingResult[]>;
|
|
64
|
+
/**
|
|
65
|
+
* Build a placeholder `TrackingResult` for a waybill Aramex reports under
|
|
66
|
+
* `NonExistingWaybills`. Aramex splits the TrackShipments response into found
|
|
67
|
+
* (`TrackingResults`) and not-found (`NonExistingWaybills`) buckets; emitting an
|
|
68
|
+
* "unknown" entry for the latter keeps the returned array aligned to the input
|
|
69
|
+
* waybills so callers can map inputs→results positionally/by trackingNumber.
|
|
70
|
+
*/
|
|
71
|
+
export declare function mapNonExistingWaybill(waybill: string): TrackingResult;
|
|
64
72
|
export declare function mapRate(response: AramexCalculateRateResponse, input: CreateShipmentInput): Rate;
|
|
65
73
|
export declare function mapPickupResponse(processed: AramexProcessedPickup, input: PickupRequest): Pickup;
|
|
66
74
|
export declare function mapCity(name: string): City;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mappers.d.ts","sourceRoot":"","sources":["../../../src/carriers/aramex/mappers.ts"],"names":[],"mappings":"AACA;;;GAGG;AAEH,OAAO,KAAK,EAEV,IAAI,EACJ,mBAAmB,EAEnB,QAAQ,EACR,MAAM,EACN,aAAa,EACb,IAAI,EACJ,QAAQ,EACR,cAAc,EACd,aAAa,EACb,cAAc,EACf,MAAM,kBAAkB,CAAC;AAM1B,OAAO,KAAK,EACV,2BAA2B,EAC3B,gBAAgB,EAIhB,YAAY,EAEZ,kBAAkB,EAClB,kBAAkB,EAClB,qBAAqB,EACrB,uBAAuB,EACvB,cAAc,EACd,qBAAqB,EACrB,oBAAoB,EACpB,4BAA4B,EAE7B,MAAM,SAAS,CAAC;AAMjB,MAAM,WAAW,iBAAiB;IAChC,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,aAAa,EAAE,MAAM,CAAC;IACtB,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,EAAE,MAAM,CAAC;IACtB,kBAAkB,EAAE,MAAM,CAAC;CAC5B;AAED,0EAA0E;AAC1E,wBAAgB,eAAe,CAC7B,WAAW,EAAE,iBAAiB,EAC9B,IAAI,CAAC,EAAE;IAAE,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAA;CAAE,GAC3C,gBAAgB,CAWlB;AAMD,wBAAgB,eAAe,CAC7B,UAAU,EAAE,MAAM,GACjB,cAAc,GAAG,SAAS,CAG5B;AAED;;;;GAIG;AACH,wBAAgB,qBAAqB,CACnC,WAAW,EAAE,MAAM,GAAG,SAAS,GAC9B,cAAc,GAAG,SAAS,CAkB5B;AAMD,6EAA6E;AAC7E,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,IAAI,CAKtE;AA0BD;;;;GAIG;AACH,wBAAgB,0BAA0B,CAAC,KAAK,EAAE,mBAAmB,GAAG;IACtE,YAAY,EAAE,KAAK,GAAG,KAAK,CAAC;IAC5B,WAAW,EAAE,MAAM,CAAC;CACrB,CAsBA;
|
|
1
|
+
{"version":3,"file":"mappers.d.ts","sourceRoot":"","sources":["../../../src/carriers/aramex/mappers.ts"],"names":[],"mappings":"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"}
|
|
@@ -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;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"adapter.d.ts","sourceRoot":"","sources":["../../../src/carriers/aymakan/adapter.ts"],"names":[],"mappings":"AACA;;;GAGG;AAYH,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;
|
|
1
|
+
{"version":3,"file":"adapter.d.ts","sourceRoot":"","sources":["../../../src/carriers/aymakan/adapter.ts"],"names":[],"mappings":"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"}
|