npm package: @mixcore/sdk-client
Description: A powerful, type-safe TypeScript SDK for interacting with the Mixcore API. Built with modern best practices, comprehensive error handling, and developer-friendly features.
Latest version: 1.0.0-dev.11

# 🚀 Mixcore SDK Client

A powerful, type-safe TypeScript SDK for interacting with the Mixcore API. Built with modern best practices, comprehensive error handling, and developer-friendly features.

## ✨ Features

- 🔐 **Authentication Management** - Automatic token handling and refresh
- 📊 **Database Operations** - Full CRUD operations with validation
- 💾 **File Storage** - Upload and manage files
- 🔍 **Type-Safe Queries** - Strongly typed query builder
- ⚡ **Caching System** - Built-in response caching for performance
- 🛡️ **Error Handling** - Comprehensive error types and handling
- 📝 **Input Validation** - Automatic parameter validation
- 🧪 **Fully Tested** - Comprehensive unit test coverage
- 📚 **TypeScript First** - Full TypeScript support with detailed types

## 📦 Installation

```bash
npm install @mixcore/sdk-client
# or
pnpm add @mixcore/sdk-client
# or
yarn add @mixcore/sdk-client
```

## 🏃‍♂️ Quick Start

```typescript
import { MixcoreClient, MixQuery } from '@mixcore/sdk-client';

// Initialize the client
const client = new MixcoreClient({
  endpoint: 'https://your-api-endpoint.com/api/v2',
  tokenKey: 'your_token_key',
  refreshTokenKey: 'your_refresh_token_key'
});

// Login
const tokenInfo = await client.auth.login({
  email: 'user@example.com',
  password: 'password'
});

// Fetch data from a database
const query = new MixQuery().take(10);
const users = await client.database.getData('users', query);
```

## 🔧 Configuration

```typescript
const client = new MixcoreClient({
  endpoint: 'https://api.mixcore.io/api/v2',     // API endpoint
  tokenKey: 'mix_access_token',                  // Token storage key
  refreshTokenKey: 'mix_refresh_token',          // Refresh token key
  tokenType: 'Bearer',                           // Token type
  events: {                                      // Event handlers
    onAuthSuccess: () => console.log('Authenticated'),
    onAuthError: () => console.log('Auth failed')
  }
});
```

## 🗃️ Database Operations

### Basic CRUD Operations

```typescript
import { MixQuery } from '@mixcore/sdk-client';

// Get data with query
const query = new MixQuery()
  .where('status', 'active')
  .orderBy('createdDate', 'desc')
  .take(10);

const users = await client.database.getData('users', query);

// Get by ID
const user = await client.database.getDataById('users', 123);

// Create new record
const newUser = await client.database.createData('users', {
  name: 'John Doe',
  email: 'john@example.com'
});

// Update record
const updatedUser = await client.database.updateData('users', 123, {
  name: 'Jane Doe'
});

// Update multiple records
const updates = [
  { id: 1, name: 'Updated Name 1' },
  { id: 2, name: 'Updated Name 2' }
];
const bulkUpdateResult = await client.database.updateManyData('users', updates);

// Delete record
const success = await client.database.deleteData('users', 123);

// Export data
const exportQuery = new MixQuery().where('active', true);
const exportResult = await client.database.exportData('users', exportQuery);
```

### Advanced Queries

```typescript
const query = new MixQuery()
  .where('age', '>=', 18)
  .where('status', 'active')
  .orWhere('vip', true)
  .orderBy('createdDate', 'desc')
  .skip(20)
  .take(10);

const results = await client.database.getData('users', query);

// Search by column
const userByEmail = await client.database.getDataByColumn('users', 'email', 'john@example.com');
```

## 🔐 Authentication

```typescript
// Login
const tokenInfo = await client.auth.login({
  email: 'user@example.com',
  password: 'password'
});

// Login with callback handling
await client.auth.login({
  email: 'user@example.com',
  password: 'password'
}, {
  success: (data) => console.log('Login successful:', data),
  error: (error) => console.error('Login failed:', error),
  finally: () => console.log('Login attempt completed')
});

// Register
await client.auth.register({
  username: 'newuser',
  email: 'newuser@example.com',
  password: 'securepassword'
});

// Get current user
const currentUser = await client.auth.initUserData();

// Check authentication status
console.log('Is authenticated:', !!client.auth.tokenInfo);
console.log('Current user:', client.auth.currentUser);

// Logout
client.auth.logout(() => {
  console.log('Logged out successfully');
});
```

## 💾 File Storage

```typescript
// Upload file
const fileInput = document.getElementById('fileInput') as HTMLInputElement;
const file = fileInput.files?.[0];

if (file) {
  const fileData = new FormData();
  fileData.append('file', file);
  
  const uploadResult = await client.storage.uploadFile(fileData);
  console.log('File uploaded:', uploadResult);
}

// Delete file
await client.storage.deleteFile('path/to/file.jpg');
```

## 🔧 Error Handling

The SDK provides specific error types for better error handling:

```typescript
import { 
  MixcoreSDKError, 
  AuthenticationError, 
  NetworkError, 
  ValidationError 
} from '@mixcore/sdk-client';

try {
  const data = await client.database.getData('users', query);
} catch (error) {
  if (error instanceof AuthenticationError) {
    // Handle authentication errors
    console.log('Please login again');
    // Redirect to login page
  } else if (error instanceof ValidationError) {
    // Handle validation errors
    console.log('Invalid input:', error.message);
    // Show user-friendly error message
  } else if (error instanceof NetworkError) {
    // Handle network errors
    console.log('Network issue:', error.message);
    // Show retry option
  } else if (error instanceof MixcoreSDKError) {
    // Handle other SDK errors
    console.log('SDK error:', error.message, 'Code:', error.code);
  } else {
    // Handle unexpected errors
    console.error('Unexpected error:', error);
  }
}
```

## ⚡ Performance Features

### Automatic Caching

```typescript
import { defaultCache, generateCacheKey } from '@mixcore/sdk-client';

// Cache is automatically used for repeated requests
const data1 = await client.database.getData('users', query); // API call
const data2 = await client.database.getData('users', query); // From cache

// Manual cache control
const cacheKey = generateCacheKey('users', query);
defaultCache.set(cacheKey, data, 600000); // Cache for 10 minutes
const cached = defaultCache.get(cacheKey);

// Cache management
console.log('Cache stats:', defaultCache.getStats());
defaultCache.cleanup(); // Clean expired entries
defaultCache.clear(); // Clear all cache
```

### Request Interceptors

```typescript
import { requestInterceptor, responseInterceptor, errorInterceptor } from '@mixcore/sdk-client';

// Interceptors are automatically applied and provide:
// - Authentication header injection
// - Request/response logging (in development)
// - Automatic error handling and token cleanup
// - Custom error type conversion
```

## 🧪 Testing

```bash
# Install dependencies first
pnpm install

# Run tests
pnpm test

# Run tests in watch mode
pnpm test:watch

# Run tests with coverage
pnpm test:coverage

# Build and test
pnpm build
```

## 📝 Validation

Input validation is automatic and helps prevent common errors:

```typescript
// These will throw ValidationError with helpful messages
try {
  await client.database.getData('', query);           // Empty database name
  await client.database.createData('users', null);    // Invalid data
  await client.database.updateData('users', '', {});  // Empty ID
  await client.database.getData('invalid-name!', query); // Invalid characters
} catch (error) {
  console.log(error.message); // Descriptive validation error
}
```

## 🔄 Migration Guide

### From v0.0.1-dev.20 to v0.0.1-dev.21+

The SDK has been significantly improved with breaking changes:

```typescript
// OLD: Database methods returned different types
const result = await database.deleteData('users', 123); // Returned Partial<T>

// NEW: Database methods have consistent return types
const success = await database.deleteData('users', 123); // Returns boolean

// OLD: Mixed async patterns
const data = await API.get('/endpoint').then(res => res.data);

// NEW: Consistent async/await
const response = await API.get('/endpoint');
const data = response.data;

// OLD: No validation
await database.createData('', invalidData); // Would make API call

// NEW: Input validation
await database.createData('', invalidData); // Throws ValidationError immediately
```

## 🔧 Development

See [DEVELOPMENT.md](./DEVELOPMENT.md) for development guidelines and best practices.

### Building

```bash
# Install dependencies
pnpm install

# Build the SDK
pnpm build

# Development mode with watch
pnpm dev

# Lint code
pnpm lint

# Clean artifacts
pnpm clean
```

### Project Structure

```
src/
├── api/                          # API layer and interceptors
├── auth.ts                       # Authentication module
├── client.ts                     # Main client class
├── config/                       # Configuration constants
├── crypto/                       # Encryption utilities
├── database.ts                   # Database schema/management operations
├── database-data.ts              # Database data records operations (MixcoreTable)
├── database-data-associations.ts # Database data associations (MixcoreMixDBAssociation)
├── helpers/                      # Utility functions and validation
├── query/                        # Query builder
├── storage.ts                    # File storage operations
├── types/                        # TypeScript type definitions
└── __tests__/                    # Unit tests
```

## 📄 API Reference

### MixcoreClient

Main SDK client class with the following modules:

- `client.auth` - Authentication operations
- `client.database` - Database schema/management operations  
- `client.mixdb` - Enhanced database data operations
- `client.mixdbAssociation` - Database data association management
- `client.storage` - File storage operations

#### Constructor Options

```typescript
interface IClientConfig {
  endpoint?: string;           // API endpoint URL
  tokenKey: string;           // Local storage key for access token
  refreshTokenKey: string;    // Local storage key for refresh token
  tokenType?: string;         // Token type (default: 'Bearer')
  events?: Record<MixcoreEvent, () => void>; // Event handlers
}
```

### Error Types

- `MixcoreSDKError` - Base error class with code and statusCode
- `AuthenticationError` - Authentication failures (401, 403)
- `NetworkError` - Network-related errors (timeouts, server errors)
- `ValidationError` - Input validation errors (400)

### Utilities

- `validateRequired(value, paramName)` - Validate required parameters
- `validateDatabaseSystemName(name)` - Validate database names
- `validateMinLength(value, minLength, paramName)` - Validate string length
- `validateObject(obj, paramName)` - Validate object parameters
- `SimpleCache` - In-memory caching with TTL
- `generateCacheKey(prefix, ...params)` - Generate cache keys
- `defaultCache` - Global cache instance

## 📊 Examples

### Complete User Management Example

```typescript
import { MixcoreClient, MixQuery, ValidationError } from '@mixcore/sdk-client';

const client = new MixcoreClient({
  endpoint: 'https://api.example.com/api/v2',
  tokenKey: 'app_token',
  refreshTokenKey: 'app_refresh_token'
});

async function userManagement() {
  try {
    // Login
    await client.auth.login({
      email: 'admin@example.com',
      password: 'secure_password'
    });

    // Create a new user
    const newUser = await client.database.createData('users', {
      name: 'John Doe',
      email: 'john@example.com',
      role: 'user'
    });

    // Search for users
    const activeUsers = await client.database.getData('users', 
      new MixQuery()
        .where('status', 'active')
        .where('role', 'user')
        .orderBy('createdDate', 'desc')
        .take(20)
    );

    // Update user
    const updatedUser = await client.database.updateData('users', newUser.id, {
      lastLoginDate: new Date().toISOString()
    });

    // Get user by email
    const userByEmail = await client.database.getDataByColumn('users', 'email', 'john@example.com');

    console.log('User operations completed successfully');

  } catch (error) {
    if (error instanceof ValidationError) {
      console.error('Validation error:', error.message);
    } else {
      console.error('Operation failed:', error);
    }
  }
}

userManagement();
```

## 🤝 Contributing

We welcome contributions! Please follow these steps:

1. Fork the repository
2. Create your feature branch (`git checkout -b feature/amazing-feature`)
3. Make your changes and add tests
4. Ensure all tests pass (`pnpm test`)
5. Lint your code (`pnpm lint`)
6. Commit your changes (`git commit -m 'Add some amazing feature'`)
7. Push to the branch (`git push origin feature/amazing-feature`)
8. Open a Pull Request

### Development Guidelines

- Follow the existing code style and patterns
- Add unit tests for new features
- Update documentation for API changes
- Use conventional commit messages
- Ensure TypeScript types are properly defined

## 📄 License

This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.

## 📈 Changelog

### v0.0.1-dev.21+
- ✨ Added comprehensive input validation
- 🛡️ Enhanced error handling with custom error types
- ⚡ Built-in caching system for improved performance
- 🔧 Request/response interceptors
- 🧪 Added unit testing framework
- 📚 Improved TypeScript types and documentation
- 🔄 Consistent async/await patterns
- 🏗️ Better code organization and maintainability

### v0.0.1-dev.20
- Initial TypeScript SDK implementation
- Basic CRUD operations
- Authentication support
- File storage operations

## 🆘 Support

- 📚 [Documentation](https://docs.mixcore.io)
- 💬 [Discord Community](https://discord.gg/mixcore)
- 🐛 [Issue Tracker](https://github.com/mixcore/sdk-client/issues)
- 📧 [Email Support](mailto:support@mixcore.io)

## 🙏 Acknowledgments

- Built with ❤️ by the Mixcore team
- Powered by TypeScript and modern web standards
- Inspired by the best practices from the community

---

**Ready to build amazing applications with Mixcore? Get started now! 🚀**

## 📚 Enhanced Database Operations

The SDK includes enhanced database data operations through specialized modules:

### Database Data Operations

Advanced data operations beyond basic CRUD:

```typescript
// Get multiple records by IDs
const users = await client.mixdb.getDataByIds('users', {
  ids: [1, 2, 3, 4, 5],
  loadNestedData: true,
  selectColumns: ['id', 'name', 'email']
});

// Get data by column value
const user = await client.mixdb.getDataByColumn('users', 'email', 'john@example.com');

// Export data
const exportResult = await client.mixdb.exportData('users', {
  format: 'csv',
  query: new MixQuery().where('status', 'active')
});
```

### Database Data Associations

Manage relationships between database entities:

```typescript
// Create association
const association = await client.mixdbAssociation.createAssociation({
  parentDbName: 'users',
  childDbName: 'posts',
  parentId: 123,
  childId: 456,
  metadata: { relationship: 'author' }
});

// Filter associations
const associations = await client.mixdbAssociation.filterAssociations({
  parentDbName: 'users',
  pageSize: 25
});
```

For complete documentation, see [Database Data Operations Guide](./MIX-DB-README.md).