UNPKG

@heuristical/trackit

Version:

This module allows you to connect to many shipping carriers like UPS and FedEx and download tracking data for your packages in a common schema

190 lines 8.86 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.FedexClient = void 0; const xml2js_1 = require("xml2js"); const underscore_1 = require("underscore"); const moment_timezone_1 = __importDefault(require("moment-timezone")); const shipper_1 = require("./shipper"); class FedexClient extends shipper_1.ShipperClient { constructor(options) { super(); this.STATUS_MAP = new Map([ ['AA', shipper_1.STATUS_TYPES.EN_ROUTE], ['AD', shipper_1.STATUS_TYPES.EN_ROUTE], ['AF', shipper_1.STATUS_TYPES.EN_ROUTE], ['AP', shipper_1.STATUS_TYPES.SHIPPING], ['EO', shipper_1.STATUS_TYPES.EN_ROUTE], ['EP', shipper_1.STATUS_TYPES.SHIPPING], ['FD', shipper_1.STATUS_TYPES.EN_ROUTE], ['HL', shipper_1.STATUS_TYPES.DELIVERED], ['IT', shipper_1.STATUS_TYPES.EN_ROUTE], ['LO', shipper_1.STATUS_TYPES.EN_ROUTE], ['OC', shipper_1.STATUS_TYPES.SHIPPING], ['DL', shipper_1.STATUS_TYPES.DELIVERED], ['DP', shipper_1.STATUS_TYPES.EN_ROUTE], ['DS', shipper_1.STATUS_TYPES.EN_ROUTE], ['ED', shipper_1.STATUS_TYPES.OUT_FOR_DELIVERY], ['OD', shipper_1.STATUS_TYPES.OUT_FOR_DELIVERY], ['PF', shipper_1.STATUS_TYPES.EN_ROUTE], ['PL', shipper_1.STATUS_TYPES.EN_ROUTE], ['PU', shipper_1.STATUS_TYPES.EN_ROUTE], ['SF', shipper_1.STATUS_TYPES.EN_ROUTE], ['AR', shipper_1.STATUS_TYPES.EN_ROUTE], ['CD', shipper_1.STATUS_TYPES.EN_ROUTE], ['CC', shipper_1.STATUS_TYPES.EN_ROUTE], ['DE', shipper_1.STATUS_TYPES.DELAYED], ['CA', shipper_1.STATUS_TYPES.DELAYED], ['CH', shipper_1.STATUS_TYPES.DELAYED], ['DY', shipper_1.STATUS_TYPES.DELAYED], ['SE', shipper_1.STATUS_TYPES.DELAYED], ['AX', shipper_1.STATUS_TYPES.EN_ROUTE], ['OF', shipper_1.STATUS_TYPES.EN_ROUTE], ['RR', shipper_1.STATUS_TYPES.EN_ROUTE], ['OX', shipper_1.STATUS_TYPES.EN_ROUTE], ['CP', shipper_1.STATUS_TYPES.EN_ROUTE] ]); this.options = options; this.parser = new xml2js_1.Parser(); this.builder = new xml2js_1.Builder({ renderOpts: { pretty: false } }); } get key() { return this.options.key; } ; get password() { return this.options.password; } ; get account() { return this.options.account; } ; get meter() { return this.options.meter; } ; generateRequest(trk, reference) { if (reference == null) { reference = 'n/a'; } return this.builder.buildObject({ 'ns:TrackRequest': { $: { 'xmlns:ns': 'http://fedex.com/ws/track/v5', 'xmlns:xsi': 'http://www.w3.org/2001/XMLSchema-instance', 'xsi:schemaLocation': 'http://fedex.com/ws/track/v4 TrackService_v4.xsd' }, 'ns:WebAuthenticationDetail': { 'ns:UserCredential': { 'ns:Key': this.key, 'ns:Password': this.password } }, 'ns:ClientDetail': { 'ns:AccountNumber': this.account, 'ns:MeterNumber': this.meter }, 'ns:TransactionDetail': { 'ns:CustomerTransactionId': reference }, 'ns:Version': { 'ns:ServiceId': 'trck', 'ns:Major': 5, 'ns:Intermediate': 0, 'ns:Minor': 0 }, 'ns:PackageIdentifier': { 'ns:Value': trk, 'ns:Type': 'TRACKING_NUMBER_OR_DOORTAG' }, 'ns:IncludeDetailedScans': true } }); } validateResponse(response, cb) { function handleResponse(xmlErr, trackResult) { var _a, _b; if ((xmlErr != null) || (trackResult == null)) { return cb(xmlErr); } const notifications = trackResult.TrackReply != null ? trackResult.TrackReply.Notifications : undefined; const success = underscore_1.find(notifications, notice => { var _a; return ((_a = notice === null || notice === void 0 ? void 0 : notice.Code) === null || _a === void 0 ? void 0 : _a[0]) === '0'; }); if (!success) { return cb(notifications || 'invalid reply'); } return cb(null, (_b = (_a = trackResult === null || trackResult === void 0 ? void 0 : trackResult.TrackReply) === null || _a === void 0 ? void 0 : _a.TrackDetails) === null || _b === void 0 ? void 0 : _b[0]); } this.parser.reset(); return this.parser.parseString(response, handleResponse); } presentAddress(address) { if (address == null) { return; } let city = address.City != null ? address.City[0] : undefined; if (city != null) { city = city.replace('FEDEX SMARTPOST ', ''); } const stateCode = address.StateOrProvinceCode != null ? address.StateOrProvinceCode[0] : undefined; const countryCode = address.CountryCode != null ? address.CountryCode[0] : undefined; const postalCode = address.PostalCode != null ? address.PostalCode[0] : undefined; return this.presentLocation({ city, stateCode, countryCode, postalCode }); } getStatus(shipment) { var _a; const statusCode = (_a = shipment === null || shipment === void 0 ? void 0 : shipment.StatusCode) === null || _a === void 0 ? void 0 : _a[0]; if (statusCode == null) { return; } return this.STATUS_MAP.has(statusCode) ? this.STATUS_MAP.get(statusCode) : shipper_1.STATUS_TYPES.UNKNOWN; } getActivitiesAndStatus(shipment) { const activities = []; for (const rawActivity of ((shipment === null || shipment === void 0 ? void 0 : shipment.Events) || [])) { let datetime, timestamp; const location = this.presentAddress(rawActivity.Address != null ? rawActivity.Address[0] : undefined); const rawTimestamp = rawActivity.Timestamp != null ? rawActivity.Timestamp[0] : undefined; if (rawTimestamp != null) { const eventTime = moment_timezone_1.default(rawTimestamp); timestamp = eventTime.toDate(); datetime = rawTimestamp.slice(0, 19); } const details = rawActivity.EventDescription != null ? rawActivity.EventDescription[0] : undefined; if ((details != null) && (timestamp != null)) { const activity = { timestamp, datetime, location, details }; activities.push(activity); } } return { activities, status: this.getStatus(shipment) }; } getEta(shipment) { var _a; const ts = (_a = shipment === null || shipment === void 0 ? void 0 : shipment.EstimatedDeliveryTimestamp) === null || _a === void 0 ? void 0 : _a[0]; if (ts == null) { return; } return moment_timezone_1.default(`${ts.slice(0, 19)}Z`).toDate(); } getService(shipment) { return (shipment === null || shipment === void 0 ? void 0 : shipment.ServiceInfo) ? shipment === null || shipment === void 0 ? void 0 : shipment.ServiceInfo[0] : undefined; } getWeight(shipment) { var _a, _b, _c; const weightData = (_a = shipment === null || shipment === void 0 ? void 0 : shipment.PackageWeight) === null || _a === void 0 ? void 0 : _a[0]; if (weightData == null) { return; } const units = (_b = weightData === null || weightData === void 0 ? void 0 : weightData.Units) === null || _b === void 0 ? void 0 : _b[0]; const value = (_c = weightData === null || weightData === void 0 ? void 0 : weightData.Value) === null || _c === void 0 ? void 0 : _c[0]; if ((units != null) && (value != null)) { return `${value} ${units}`; } } getDestination(shipment) { return this.presentAddress(shipment.DestinationAddress != null ? shipment.DestinationAddress[0] : undefined); } requestOptions({ trackingNumber, reference }) { return { method: 'POST', uri: 'https://ws.fedex.com/xml', body: this.generateRequest(trackingNumber, reference) }; } } exports.FedexClient = FedexClient; //# sourceMappingURL=fedex.js.map