npm package: @jatdalton/commerce7-api-client
Description: A clean, simple JavaScript client for the Commerce7 REST API
Author: JATD
Latest version: 1.0.1

# Commerce7 API Client

A clean, simple, and type-safe JavaScript/TypeScript client for the [Commerce7 REST API](https://developer.commerce7.com/docs/commerce7-developer-docs).

## Features

- ✅ **Type-Safe**: Full TypeScript support with type definitions
- ✅ **Simple API**: Clean, intuitive interface
- ✅ **Automatic Authentication**: Handles Basic Auth and tenant headers
- ✅ **Built-in Pagination**: Automatic cursor-based pagination
- ✅ **Rate Limiting**: Respects `Retry-After` headers
- ✅ **Error Handling**: Comprehensive error handling with typed errors
- ✅ **Zero Dependencies**: Only uses `axios` (peer dependency)

## Installation

```bash
npm install commerce7-api-client
```

## Quick Start

```typescript
import { createClient } from 'commerce7-api-client';

// Create a client
const client = createClient({
  appId: 'your-app-id',
  appSecret: 'your-app-secret',
  tenant: 'your-tenant-id'
});

// Make a request
const response = await client.get('/customer', { limit: 10 });
console.log(response.data);

// Paginate through results
const allMemberships = await client.paginate('/club-membership', {
  updatedAt: 'gte:2024-01-01'
}, {
  recordTag: 'clubMemberships'
});
```

## API Reference

### Creating a Client

```typescript
import { Commerce7Client, createClient } from 'commerce7-api-client';

// Using factory function
const client = createClient({
  appId: 'your-app-id',
  appSecret: 'your-app-secret',
  tenant: 'your-tenant-id',
  baseURL: 'https://api.commerce7.com/v1', // optional
  timeout: 30000, // optional, default 30s
  maxRetries: 3 // optional, default 3
});

// Or using class directly
const client = new Commerce7Client({
  appId: 'your-app-id',
  appSecret: 'your-app-secret',
  tenant: 'your-tenant-id'
});
```

### Making Requests

#### GET Request

```typescript
// Simple GET
const response = await client.get('/customer/{id}');

// GET with query parameters
const response = await client.get('/customer', {
  q: 'john',
  lifetimeValue: 'gt:100000',
  orderCount: 'gte:2'
});
```

#### POST Request

```typescript
const customer = await client.post('/customer', {
  firstName: 'John',
  lastName: 'Doe',
  emails: [{ email: 'john@example.com' }]
});
```

#### PUT Request

```typescript
const updated = await client.put('/customer/{id}', {
  firstName: 'Jane'
});
```

#### PATCH Request

```typescript
const patched = await client.patch('/customer/{id}', {
  metaData: { customField: 'value' }
});
```

#### DELETE Request

```typescript
await client.delete('/customer/{id}');
```

### Pagination

#### Automatic Pagination (Collect All)

```typescript
// Collects all pages automatically
const allMemberships = await client.paginate('/club-membership', {
  updatedAt: 'gte:2024-01-01'
}, {
  recordTag: 'clubMemberships', // Field containing records
  maxPages: 1000 // Safety limit
});

console.log(`Found ${allMemberships.length} memberships`);
```

#### Pagination with Callback

```typescript
// Process pages as they arrive
const allRecords = await client.paginate('/club-membership', {
  updatedAt: 'gte:2024-01-01'
}, {
  recordTag: 'clubMemberships',
  onPage: (page, pageNumber) => {
    console.log(`Processing page ${pageNumber}...`);
    // Process page.data here
  }
});
```

### Multi-Tenant Support

```typescript
// Create client for tenant 1
const client1 = createClient({
  appId: 'app-id',
  appSecret: 'secret',
  tenant: 'tenant-1'
});

// Create client for tenant 2 (reuses config)
const client2 = client1.withTenant('tenant-2');

// Both clients share the same app credentials
await client1.get('/customer');
await client2.get('/customer');
```

### Error Handling

```typescript
import { Commerce7Error } from 'commerce7-api-client';

try {
  const response = await client.get('/customer/invalid-id');
} catch (error) {
  if (error instanceof Commerce7Error) {
    console.error(`API Error ${error.statusCode}:`, error.message);
    console.error('Response:', error.responseData);
  } else {
    console.error('Network error:', error.message);
  }
}
```

## Examples

### Get Customer by ID

```typescript
const response = await client.get('/customer/a36b6ff1-7190-49a0-895e-fd2c001eb2a6');
const customer = response.data;
console.log(customer.firstName, customer.lastName);
```

### Search Customers

```typescript
const response = await client.get('/customer', {
  q: 'john',
  lifetimeValue: 'gt:100000',
  orderCount: 'gte:2',
  createdAt: 'gte:2024-01-01'
});

const customers = response.data.customers;
console.log(`Found ${response.data.totalCount} customers`);
```

### Create Customer

```typescript
const response = await client.post('/customer', {
  firstName: 'John',
  lastName: 'Doe',
  emails: [{ email: 'john@example.com' }],
  phones: [{ phone: '+15551234567' }],
  isSendTransactionEmail: false
});

const newCustomer = response.data;
console.log('Created customer:', newCustomer.id);
```

### Update Customer

```typescript
const response = await client.put('/customer/{id}', {
  firstName: 'Jane',
  metaData: {
    customField: 'value'
  }
});
```

### List Club Memberships with Pagination

```typescript
// Get all active memberships
const memberships = await client.paginate('/club-membership', {
  status: 'Active',
  updatedAt: 'gte:2024-01-01'
}, {
  recordTag: 'clubMemberships'
});

console.log(`Total memberships: ${memberships.length}`);
```

### Create Club Membership

```typescript
// 1. Create customer
const customer = await client.post('/customer', {
  firstName: 'John',
  lastName: 'Doe',
  emails: [{ email: 'john@example.com' }]
});

// 2. Create address
const address = await client.post('/customer-address', {
  customerId: customer.data.id,
  address1: '123 Main St',
  city: 'Napa',
  stateCode: 'CA',
  zipCode: '94558',
  countryCode: 'US'
});

// 3. Create credit card
const card = await client.post('/customer-credit-card', {
  customerId: customer.data.id,
  // ... card details
});

// 4. Create membership
const membership = await client.post('/club-membership', {
  customerId: customer.data.id,
  clubId: 'club-uuid',
  billToCustomerAddressId: address.data.id,
  shipToCustomerAddressId: address.data.id,
  customerCreditCardId: card.data.id,
  orderDeliveryMethod: 'Ship',
  signupDate: new Date().toISOString(),
  isSendEmailConfirmation: false
});
```

## TypeScript Support

The package includes full TypeScript definitions:

```typescript
import { Commerce7Client, Customer, ClubMembership } from 'commerce7-api-client';

const client = createClient({ /* config */ });

// Typed responses
const response = await client.get<Customer>('/customer/{id}');
const customer: Customer = response.data;

// Typed pagination
const memberships = await client.paginate<ClubMembership>('/club-membership', {}, {
  recordTag: 'clubMemberships'
});
```

## Configuration Options

```typescript
interface Commerce7Config {
  appId: string;              // Required: Your Commerce7 App ID
  appSecret: string;          // Required: Your Commerce7 App Secret
  tenant: string;            // Required: Tenant identifier
  baseURL?: string;          // Optional: API base URL (default: https://api.commerce7.com/v1)
  timeout?: number;          // Optional: Request timeout in ms (default: 30000)
  maxRetries?: number;       // Optional: Max retry attempts (default: 3)
}
```

## Error Types

### Commerce7Error

Thrown for API errors (4xx, 5xx):

```typescript
class Commerce7Error extends Error {
  statusCode: number;
  responseData?: any;
  responseHeaders?: Record<string, string>;
}
```

## Rate Limiting

The client automatically handles rate limiting:

- Detects `429 Too Many Requests` responses
- Checks for `Retry-After` header
- Automatically retries after the specified delay
- No manual retry logic needed

## Browser Support

This package is designed for Node.js environments. For browser use, you'll need to:

1. Use a bundler (webpack, rollup, etc.)
2. Provide polyfills for Node.js built-ins (Buffer, etc.)
3. Consider CORS restrictions

## License

MIT

## Links

- [Commerce7 Developer Documentation](https://developer.commerce7.com/docs/commerce7-developer-docs)
- [Commerce7 API Overview](https://developer.commerce7.com/docs/commerce7-developer-docs/api-overview)
- [App Partner Program](https://commerce7.com/partners/become-a-partner/app/)