npm package: @omnissiah404/smartmoving-sdk
Description: Unofficial Node.js SDK for SmartMoving API v1.0 - Easy integration for moving companies and webapps
Author: Josep
Latest version: 1.0.0

# SmartMoving SDK for Node.js

[![npm version](https://badge.fury.io/js/smartmoving-sdk.svg)](https://badge.fury.io/js/smartmoving-sdk)
[![TypeScript](https://img.shields.io/badge/%3C%2F%3E-TypeScript-%230074c1.svg)](http://www.typescriptlang.org/)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)

Official Node.js SDK for the SmartMoving API v1.0. This SDK provides easy access to all SmartMoving API endpoints with full TypeScript support, comprehensive error handling, and built-in utilities for common tasks.

## 🚀 Features

- **Full TypeScript Support** - Complete type definitions for all API responses
- **Modular Architecture** - Organized clients for different API areas (customers, opportunities, leads)
- **Built-in Pagination** - Automatic pagination helpers and utilities
- **Error Handling** - Comprehensive error handling with detailed error information
- **Retry Logic** - Configurable retry logic for failed requests
- **Date Utilities** - Easy conversion between JavaScript dates and SmartMoving API formats
- **Validation Helpers** - Built-in validation for UUIDs, emails, phone numbers, and dates
- **Premium Support** - Full support for both basic and premium API endpoints

## 📦 Installation

```bash
npm install smartmoving-sdk
```

Or with yarn:

```bash
yarn add smartmoving-sdk
```

## 🔧 Quick Start

```typescript
import { SmartMovingSDK } from 'smartmoving-sdk';

// Initialize the SDK
const sdk = new SmartMovingSDK({
  apiKey: 'your-api-key-here',
  subscriptionKey: 'your-subscription-key-here',
  timeout: 30000, // optional, default: 30000ms
  retries: 3,     // optional, default: 3
});

// Test the connection
const status = await sdk.testConnection();
console.log(status); // { status: 'success', message: '...' }

// Get all customers
const customers = await sdk.customers.getAll({ Page: 1, PageSize: 10 });

// Get customer by ID
const customer = await sdk.customers.getById('customer-uuid');

// Get opportunity details with additional data
const opportunity = await sdk.opportunities.getById('opportunity-uuid', {
  IncludeTripInfo: true,
  IncludePayments: true,
  IncludeJobs: true,
});

// Get leads with pagination
const leads = await sdk.leads.getAll({ Page: 1, PageSize: 20 });
```

## 🏗️ API Overview

### Configuration

```typescript
interface SmartMovingConfig {
  apiKey: string;              // Required: Your SmartMoving API key
  subscriptionKey: string;     // Required: Your SmartMoving subscription key
  baseURL?: string;           // Optional: Custom API base URL
  timeout?: number;           // Optional: Request timeout in ms (default: 30000)
  retries?: number;           // Optional: Number of retries (default: 3)
  retryDelay?: number;        // Optional: Delay between retries in ms (default: 1000)
}
```

### Customers API

```typescript
// Get customer by ID
const customer = await sdk.customers.getById('customer-uuid');

// Get all customers with filtering
const customers = await sdk.customers.getAll({
  Page: 1,
  PageSize: 50,
  FromServiceDate: 20240101,
  ToServiceDate: 20241231,
  IncludeOpportunityInfo: true,
});

// Get customer opportunities
const opportunities = await sdk.customers.getOpportunities('customer-uuid');

// Get customer storage accounts
const storageAccounts = await sdk.customers.getStorageAccounts('customer-uuid');

// Premium features
const newCustomer = await sdk.customers.create({
  name: 'John Doe',
  phoneNumber: '555-123-4567',
  phoneType: PhoneType.Mobile,
  emailAddress: 'john@example.com',
  address: '123 Main St, City, State 12345',
});

await sdk.customers.update('customer-uuid', { name: 'John Smith' });

const searchResults = await sdk.customers.search('john doe');
```

### Opportunities API

```typescript
// Get opportunity by ID
const opportunity = await sdk.opportunities.getById('opportunity-uuid', {
  IncludeTripInfo: true,
  IncludePayments: true,
  IncludeSurveys: true,
  IncludeJobs: true,
});

// Get opportunity by quote number
const opportunity = await sdk.opportunities.getByQuoteNumber(12345);

// Get opportunity payments
const payments = await sdk.opportunities.getPayments('opportunity-uuid');

// Get opportunity jobs
const jobs = await sdk.opportunities.getJobs('opportunity-uuid');

// Premium features
const followUps = await sdk.opportunities.getFollowUps('opportunity-uuid');
await sdk.opportunities.createFollowUp('opportunity-uuid', followUpData);
await sdk.opportunities.createJob('opportunity-uuid', jobData);
```

### Leads API

```typescript
// Get all leads with pagination
const leadsPage = await sdk.leads.getAll({ Page: 1, PageSize: 25 });

// Get lead by ID
const lead = await sdk.leads.getById('lead-uuid');

// Get available lead statuses
const statuses = await sdk.leads.getStatuses();

// Premium: Get leads by salesperson
const salesLeads = await sdk.leads.getBySalesperson('salesperson-uuid');
```

## 🛠️ Utilities

### Pagination Helper

```typescript
import { PaginationHelper } from 'smartmoving-sdk';

// Create pagination parameters
const params = PaginationHelper.createParams(1, 50);

// Get all results automatically (handles pagination)
const allCustomers = await PaginationHelper.getAllResults(
  (params) => sdk.customers.getAll(params),
  { Page: 1, PageSize: 100 }
);

// Check if more pages are available
const hasMore = PaginationHelper.hasNextPage(leadsPage);
```

### Date Helper

```typescript
import { DateHelper } from 'smartmoving-sdk';

// Convert JavaScript Date to API format
const apiDate = DateHelper.toApiDate(new Date()); // Returns: 20240731

// Convert API date to JavaScript Date
const jsDate = DateHelper.fromApiDate(20240731);

// Get current month date range
const monthRange = DateHelper.getCurrentMonthRange();
// Returns: { FromServiceDate: 20240701, ToServiceDate: 20240731 }

// Get date range for next 30 days
const futureRange = DateHelper.getDateRange(30);
```

### Validation Helper

```typescript
import { ValidationHelper } from 'smartmoving-sdk';

// Validate UUID
const isValid = ValidationHelper.isValidUUID('customer-uuid');

// Validate email
const isValidEmail = ValidationHelper.isValidEmail('test@example.com');

// Validate phone number
const isValidPhone = ValidationHelper.isValidPhone('555-123-4567');

// Validate API date format
const isValidDate = ValidationHelper.isValidApiDate(20240731);
```

## 🎯 Advanced Usage

### Error Handling

```typescript
import { SmartMovingAPIError } from 'smartmoving-sdk';

try {
  const customer = await sdk.customers.getById('invalid-uuid');
} catch (error) {
  if (error instanceof SmartMovingAPIError) {
    console.log('Status:', error.status);    // HTTP status code
    console.log('Code:', error.code);        // API error code
    console.log('Message:', error.message);  // Error message
    console.log('Details:', error.details);  // Additional error details
  }
}
```

### Custom Configuration

```typescript
const sdk = new SmartMovingSDK({
  apiKey: process.env.SMARTMOVING_API_KEY,
  subscriptionKey: process.env.SMARTMOVING_SUBSCRIPTION_KEY,
  baseURL: 'https://custom-api.smartmoving.com/v1',
  timeout: 60000,  // 60 seconds
  retries: 5,
  retryDelay: 2000, // 2 seconds between retries
});
```

### Bulk Operations

```typescript
// Get all customers across all pages
const allCustomers = await PaginationHelper.getAllResults(
  (params) => sdk.customers.getAll(params)
);

// Process customers in batches
const batchSize = 10;
for (let i = 0; i < allCustomers.length; i += batchSize) {
  const batch = allCustomers.slice(i, i + batchSize);
  
  // Process batch
  await Promise.all(
    batch.map(customer => processCustomer(customer))
  );
}
```

## 📚 TypeScript Support

The SDK is built with TypeScript and provides comprehensive type definitions:

```typescript
import { 
  CustomerViewModel, 
  OpportunityDetailsViewModel,
  LeadViewModel,
  PhoneType,
  OpportunityStatus 
} from 'smartmoving-sdk';

// Fully typed responses
const customer: CustomerViewModel = await sdk.customers.getById('uuid');
const opportunity: OpportunityDetailsViewModel = await sdk.opportunities.getById('uuid');

// Enum support
const phoneType: PhoneType = PhoneType.Mobile;
const status: OpportunityStatus = OpportunityStatus.Booked;
```

## 🔐 Authentication

The SDK uses dual authentication with both an API key and subscription key. You can obtain these keys from the SmartMoving developer dashboard.

```typescript
// Environment variables (recommended)
const sdk = new SmartMovingSDK({
  apiKey: process.env.SMARTMOVING_API_KEY,
  subscriptionKey: process.env.SMARTMOVING_SUBSCRIPTION_KEY,
});

// Direct configuration (not recommended for production)
const sdk = new SmartMovingSDK({
  apiKey: 'your-api-key-here',
  subscriptionKey: 'your-subscription-key-here',
});
```

### Authentication Headers

The SDK automatically sets the following headers for authentication:
- `x-api-key`: Your API key
- `Ocp-Apim-Subscription-Key`: Your subscription key

### Configuration Helper

Use the `ConfigHelper` utility for advanced configuration management:

```typescript
import { SmartMovingSDK, ConfigHelper } from 'smartmoving-sdk';

// Load from environment variables
const config = ConfigHelper.fromEnvironment();
const sdk = new SmartMovingSDK(config);

// Environment-specific configuration
const prodConfig = ConfigHelper.forEnvironment('production', {
  apiKey: 'your-api-key',
  subscriptionKey: 'your-subscription-key',
});

// Validate configuration
ConfigHelper.validate(config);

// Safely log configuration (hides sensitive data)
console.log('Config:', ConfigHelper.sanitize(config));
```

## 📊 Rate Limiting

The SDK includes built-in retry logic for rate-limited requests. Configure retry behavior:

```typescript
const sdk = new SmartMovingSDK({
  apiKey: 'your-api-key',
  retries: 5,        // Number of retries
  retryDelay: 1000,  // Initial delay in ms (increases with each retry)
});
```

## 🧪 Testing

```bash
# Run tests
npm test

# Run tests in watch mode
npm run test:watch

# Run tests with coverage
npm run test:coverage
```

## 🤝 Contributing

1. Fork the repository
2. Create your feature branch (`git checkout -b feature/amazing-feature`)
3. Commit your changes (`git commit -m 'Add some amazing feature'`)
4. Push to the branch (`git push origin feature/amazing-feature`)
5. Open a Pull Request

## 📝 License

This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.

## 🆘 Support

- 📧 Email: support@smartmoving.com
- 📖 Documentation: [https://developer.smartmoving.com](https://developer.smartmoving.com)
- 🐛 Issues: [GitHub Issues](https://github.com/smartmoving/smartmoving-sdk-node/issues)

## 🔄 Changelog

See [CHANGELOG.md](CHANGELOG.md) for a list of changes and version history.

---

Made with ❤️ by the SmartMoving team