trackbox
v1.0.4
Published
A TypeScript library for normalizing parcel tracking data from major North American carriers
Maintainers
Readme
📦 Trackbox
A powerful, type-safe TypeScript library for normalizing parcel tracking data from major North American carriers. Get consistent tracking information regardless of the carrier.
✨ Features
- 🚀 Full FedEx Integration - Complete OAuth2 + Track API implementation
- 🔧 Multiple Carriers - Support for FedEx, UPS, USPS, Canada Post, Purolator, DHL, Amazon
- 🎯 Auto-Detection - Automatically detects carrier from tracking number
- 📊 Normalized Data - Consistent response format across all carriers
- 💾 Smart Caching - Built-in response and token caching
- 🔒 Type Safe - 100% TypeScript with strict typing
- ⚡ Modern Stack - ES2022, async/await, latest dependencies
- 🧪 Well Tested - Comprehensive test suite with 29+ tests
- 📦 Zero Dependencies - Only axios for HTTP requests
🚀 Quick Start
Installation
npm install trackboxBasic Usage
import { TrackingClient } from 'trackbox';
const client = new TrackingClient({
carriers: {
fedex: {
clientId: process.env.FEDEX_CLIENT_ID!,
clientSecret: process.env.FEDEX_CLIENT_SECRET!,
sandbox: true // Use false for production
},
ups: {
clientId: process.env.UPS_CLIENT_ID!,
clientSecret: process.env.UPS_CLIENT_SECRET!,
accessLicenseNumber: process.env.UPS_ACCESS_LICENSE!
}
}
});
// Auto-detect carrier and track
const tracking = await client.track('123456789012');
console.log(`Status: ${tracking.status}`);
console.log(`Carrier: ${tracking.carrier}`);
console.log(`Events: ${tracking.events.length}`);
// Track with specific carrier
const fedexTracking = await client.trackWithCarrier('123456789012', 'fedex');📋 Supported Carriers
| Carrier | Status | Auto-Detection | Features | |---------|--------|----------------|----------| | FedEx | ✅ Fully Implemented | ✅ | OAuth2, Real-time tracking, Event history | | UPS | 🚧 Implemented* | ✅ | OAuth2, Tracking API | | USPS | 🚧 Implemented* | ✅ | XML API, Track & Confirm | | Canada Post | 🚧 Implemented* | ✅ | XML API, Tracking details | | Purolator | 🚧 Implemented* | ✅ | SOAP API, Package tracking | | DHL | 🚧 Implemented* | ✅ | REST API, Global tracking | | Amazon | 🚧 Implemented* | ✅ | SP-API integration |
*Implementation ready but requires API credentials for testing
🎯 Response Format
All carriers return data in this consistent format:
interface NormalizedTrackingInfo {
trackingNumber: string;
carrier: string;
status: 'unknown' | 'info_received' | 'in_transit' | 'out_for_delivery' | 'delivered' | 'exception';
statusDescription?: string;
estimatedDelivery?: string;
actualDelivery?: string;
signedBy?: string;
origin?: {
city?: string;
state?: string;
country?: string;
};
destination?: {
city?: string;
state?: string;
country?: string;
};
events: Array<{
status: string;
description?: string;
timestamp?: string;
location?: string;
}>;
raw?: Record<string, unknown>; // Original API response
}⚙️ Configuration
Carrier Credentials
const client = new TrackingClient({
carriers: {
fedex: {
clientId: 'your-fedex-client-id',
clientSecret: 'your-fedex-client-secret',
sandbox: true // Set to false for production
},
ups: {
clientId: 'your-ups-client-id',
clientSecret: 'your-ups-client-secret',
accessLicenseNumber: 'your-ups-access-license'
},
usps: {
userId: 'your-usps-user-id',
password: 'your-usps-password'
},
canadapost: {
customerId: 'your-customer-id',
username: 'your-username',
password: 'your-password'
},
purolator: {
key: 'your-api-key',
keyPassword: 'your-key-password',
account: 'your-account-number'
},
dhl: {
apiKey: 'your-dhl-api-key',
sandbox: true
},
amazon: {
accessToken: 'your-sp-api-token',
clientId: 'your-client-id',
clientSecret: 'your-client-secret',
sellerId: 'your-seller-id'
}
}
});Cache Configuration
// Set cache timeout (default: 5 minutes)
client.setCacheTimeout(10 * 60 * 1000); // 10 minutes
// Clear cache manually
client.clearCache();🔧 Advanced Usage
Error Handling
import { TrackingError } from 'trackbox';
try {
const tracking = await client.track('INVALID123');
} catch (error) {
if (error instanceof TrackingError) {
console.log(`Carrier: ${error.carrier}`);
console.log(`Tracking Number: ${error.trackingNumber}`);
console.log(`Message: ${error.message}`);
console.log(`Original Error:`, error.originalError);
}
}Using Individual Adapters
import { FedExAdapter } from 'trackbox';
const fedex = new FedExAdapter({
clientId: 'your-client-id',
clientSecret: 'your-client-secret',
sandbox: true
});
if (fedex.detect('123456789012')) {
const tracking = await fedex.track('123456789012');
}Carrier Detection
// Check configured carriers
const carriers = client.getConfiguredCarriers();
console.log('Available carriers:', carriers);
// Check if specific carrier is configured
if (client.isCarrierConfigured('fedex')) {
const tracking = await client.trackWithCarrier('123456789012', 'fedex');
}🔍 Tracking Number Patterns
The library automatically detects carriers based on tracking number patterns:
- FedEx: 12-22 digits, 96xxxxxxxxxxxxxxxxxx
- UPS: 1Zxxxxxxxxxxxxxxxx, Txxxxxxxxxx
- USPS: 20-35 digits, various formats
- Canada Post: 16 digits, XXxxxxxxxxXX format
- Purolator: 9-12 alphanumeric characters
- DHL: 10-11 digits, various formats
- Amazon: TBA format and various patterns
🧪 Testing
# Run tests
npm test
# Run tests in watch mode
npm run test:watch
# Run tests with coverage
npm run test:coverage🛠️ Development
# Install dependencies
npm install
# Build the project
npm run build
# Run linting
npm run lint
# Format code
npm run format
# Type checking
npm run type-check
# Run full CI pipeline locally
npm run ci📦 Release Process
# Patch release (1.0.0 → 1.0.1)
npm run release:patch
# Minor release (1.0.0 → 1.1.0)
npm run release:minor
# Major release (1.0.0 → 2.0.0)
npm run release:major🤝 Contributing
We welcome contributions! Please see CONTRIBUTING.md for details.
- Fork the repository
- Create your feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add some amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
📄 License
This project is licensed under the MIT License - see the LICENSE file for details.
