# B44 SDK

A TypeScript SDK for interacting with the B44 API. Designed to work with both JavaScript and TypeScript projects.

## Installation

```bash
npm install @b44/sdk
# or
yarn add @b44/sdk
```

## Usage

### Basic Setup

```javascript
import { createClient } from '@b44/sdk';

// Create a client instance
const b44 = createClient({
  serverUrl: 'https://base44.app', // Optional, defaults to 'https://base44.app'
  appId: 'your-app-id',  // Required
  env: 'prod',           // Optional, defaults to 'prod'
  token: 'your-token',   // Optional
  requiresAuth: false,   // Optional, defaults to false
});
```

### Working with Entities

```javascript
// List all products
const products = await b44.entities.Product.list();

// Filter products by category
const filteredProducts = await b44.entities.Product.filter({
  category: ['electronics', 'computers']
});

// Get a specific product
const product = await b44.entities.Product.get('product-id');

// Create a new product
const newProduct = await b44.entities.Product.create({
  name: 'New Product',
  price: 99.99,
  category: 'electronics'
});

// Update a product
const updatedProduct = await b44.entities.Product.update('product-id', {
  price: 89.99
});

// Delete a product
await b44.entities.Product.delete('product-id');

// Bulk create products
const newProducts = await b44.entities.Product.bulkCreate([
  { name: 'Product 1', price: 19.99 },
  { name: 'Product 2', price: 29.99 }
]);
```

## Authentication

The SDK provides comprehensive authentication capabilities to help you build secure applications.

### Creating an Authenticated Client

To create a client with authentication:

```javascript
import { createClient, getAccessToken } from '@b44/sdk';

// Create a client with authentication
const b44 = createClient({
  appId: 'your-app-id',
  token: getAccessToken() // Automatically retrieves token from localStorage or URL
});

// Check authentication status
const isAuthenticated = await b44.auth.isAuthenticated();
console.log('Authenticated:', isAuthenticated);

// Get current user information (requires authentication)
if (isAuthenticated) {
  const user = await b44.auth.me();
  console.log('Current user:', user);
}
```

### Login and Logout

```javascript
import { createClient, getAccessToken, saveAccessToken, removeAccessToken } from '@b44/sdk';

const b44 = createClient({ appId: 'your-app-id' });

// Redirect to the login page
function handleLogin() {
  b44.auth.login('/dashboard');
}

// Handle successful login (on return from B44 login)
function handleLoginReturn() {
  const token = getAccessToken();
  if (token) {
    console.log('Successfully logged in with token:', token);
    // The token is automatically saved to localStorage and removed from URL
  }
}

// Logout
function handleLogout() {
  removeAccessToken();
  window.location.href = '/login';
}
```

## TypeScript Support

This SDK includes TypeScript definitions out of the box:

```typescript
import { createClient, B44Error } from '@b44/sdk';
import type { Entity, B44Client, AuthModule } from '@b44/sdk';

// Create a typed client
const b44: B44Client = createClient({
  appId: 'your-app-id'
});

// Using the entities module with type safety
async function fetchProducts() {
  try {
    const products: Entity[] = await b44.entities.Product.list();
    console.log(products.map(p => p.name));
    
    const product: Entity = await b44.entities.Product.get('product-id');
    console.log(product.name);
  } catch (error) {
    if (error instanceof B44Error) {
      console.error(`Error ${error.status}: ${error.message}`);
    }
  }
}
```

### Advanced TypeScript Usage

You can define your own entity interfaces for better type safety:

```typescript
// Define custom entity interfaces
interface User extends Entity {
  name: string;
  email: string;
  role: 'admin' | 'editor' | 'viewer';
  preferences?: {
    theme: 'light' | 'dark';
    notifications: boolean;
  };
}

interface Product extends Entity {
  name: string;
  price: number;
  category: string;
  inStock: boolean;
}

// Use your custom interfaces with the SDK
async function getLoggedInUser(): Promise<User | null> {
  const b44 = createClient({ appId: 'your-app-id' });
  
  try {
    const user = await b44.auth.me() as User;
    return user;
  } catch (error) {
    console.error('Failed to get user:', error);
    return null;
  }
}
```

## Error Handling

The SDK provides a custom `B44Error` class for error handling:

```javascript
import { createClient, B44Error } from '@b44/sdk';

const b44 = createClient({ appId: 'your-app-id' });

try {
  const result = await b44.entities.NonExistentEntity.list();
} catch (error) {
  if (error instanceof B44Error) {
    console.error(`Status: ${error.status}`);
    console.error(`Message: ${error.message}`);
    console.error(`Code: ${error.code}`);
    console.error(`Data: ${JSON.stringify(error.data)}`);
  } else {
    console.error('Unexpected error:', error);
  }
}