> ## Documentation Index
> Fetch the complete documentation index at: https://docs.heylua.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Baskets API

> Shopping cart management for e-commerce

## Overview

The Baskets API provides complete shopping cart functionality with item management, status tracking, and checkout capabilities. Returns **BasketInstance** objects with direct property access.

```typescript theme={null}
import { Baskets, BasketStatus } from 'lua-cli';

// Create basket - returns BasketInstance
const basket = await Baskets.create({ currency: 'USD' });

// Direct property access
console.log(basket.itemCount);    // 0
console.log(basket.totalAmount);  // 0
console.log(basket.status);       // "active"

// Add item using instance method
await basket.addItem({
  id: productId,
  price: 29.99,
  quantity: 2
});

// Access updated properties directly
console.log(basket.itemCount);    // 2
console.log(basket.totalAmount);  // 59.98

// Checkout using instance method
const order = await basket.placeOrder({
  shippingAddress: {...},
  paymentMethod: 'stripe'
});
```

<CardGroup cols={2}>
  <Card title="Direct Access" icon="bolt">
    Access `basket.itemCount` not `basket.common.itemCount`
  </Card>

  <Card title="Instance Methods" icon="wrench">
    Built-in methods like `addItem()`, `placeOrder()`
  </Card>

  <Card title="Auto-Sync" icon="sync">
    Properties update after method calls
  </Card>

  <Card title="Type-Safe" icon="shield">
    Full TypeScript support
  </Card>
</CardGroup>

## Basket Statuses

```typescript theme={null}
import { BasketStatus } from 'lua-cli';
```

<Tabs>
  <Tab title="ACTIVE">
    Currently being used for shopping

    Default status for new baskets
  </Tab>

  <Tab title="CHECKED_OUT">
    Converted to an order

    Set automatically during checkout
  </Tab>

  <Tab title="ABANDONED">
    User left without completing purchase

    Can be set manually or by TTL
  </Tab>

  <Tab title="EXPIRED">
    TTL (time-to-live) exceeded

    Automatically set after expiration
  </Tab>
</Tabs>

## Methods

### create()

Create a new shopping basket.

```typescript theme={null}
Baskets.create(data: CreateBasketRequest): Promise<BasketInstance>
```

<ParamField path="data.currency" type="string" default="USD">
  Currency code (USD, EUR, GBP, etc.)
</ParamField>

<ParamField path="data.metadata" type="object">
  Custom metadata to store with basket
</ParamField>

**Returns:** `BasketInstance` with direct property access and methods

**Example:**

```typescript theme={null}
const basket = await Baskets.create({
  currency: 'USD',
  metadata: {
    source: 'web',
    campaign: 'summer_sale'
  }
});

// Direct property access
console.log(basket.id);          // "basket_abc123"
console.log(basket.itemCount);   // 0
console.log(basket.totalAmount); // 0
console.log(basket.status);      // "active"
console.log(basket.metadata.campaign); // "summer_sale"

// Instance methods available
await basket.addItem({...});
await basket.updateMetadata({...});
```

### get()

Retrieve baskets, optionally filtered by status.

```typescript theme={null}
Baskets.get(status?: BasketStatus): Promise<BasketInstance[]>
```

**Examples:**

```typescript theme={null}
// Get all baskets
const allBaskets = await Baskets.get();

// Get only active baskets
const activeBaskets = await Baskets.get(BasketStatus.ACTIVE);

// Get abandoned baskets
const abandoned = await Baskets.get(BasketStatus.ABANDONED);
```

### getById()

Get a specific basket by ID.

```typescript theme={null}
Baskets.getById(basketId: string): Promise<BasketInstance>
```

**Returns:** `BasketInstance` with direct property access

**Example:**

```typescript theme={null}
const basket = await Baskets.getById('basket_abc123');

// Direct property access (no .common needed!)
console.log(basket.totalAmount);  // 59.98
console.log(basket.itemCount);    // 2
console.log(basket.status);       // "active"
console.log(basket.items);        // Array of items

// Instance methods
await basket.addItem({...});
await basket.clear();
```

### addItem()

Add an item to a basket.

```typescript theme={null}
Baskets.addItem(basketId: string, item: BasketItem): Promise<Basket>
```

Or use instance method (recommended — returns enriched instance):

```typescript theme={null}
basket.addItem(item: BasketItem): Promise<BasketInstance>
```

<ParamField path="basketId" type="string" required>
  ID of the basket
</ParamField>

<ParamField path="item.id" type="string" required>
  Product ID
</ParamField>

<ParamField path="item.price" type="number" required>
  Item price
</ParamField>

<ParamField path="item.quantity" type="number" required>
  Quantity to add
</ParamField>

<ParamField path="item.SKU" type="string">
  Stock keeping unit
</ParamField>

**Returns:** Static method returns raw `Basket` data. Instance method returns `BasketInstance` with updated item count and total.

**Example:**

```typescript theme={null}
// Using static method
const basket = await Baskets.addItem('basket_abc123', {
  id: 'product_xyz',
  price: 29.99,
  quantity: 2,
  SKU: 'SHIRT-M-BLUE'
});

// Or using instance method (recommended)
await basket.addItem({
  id: 'product_xyz',
  price: 29.99,
  quantity: 2
});

// Direct property access
console.log(basket.totalAmount);  // 59.98
console.log(basket.itemCount);    // 2
console.log(basket.items);        // Array of items
```

### removeItem()

Remove an item from a basket.

```typescript theme={null}
Baskets.removeItem(basketId: string, itemId: string): Promise<Basket>
```

**Example:**

```typescript theme={null}
await Baskets.removeItem('basket_abc123', 'item_xyz');
```

### clear()

Remove all items from a basket.

```typescript theme={null}
Baskets.clear(basketId: string): Promise<Basket>
```

**Example:**

```typescript theme={null}
const emptyBasket = await Baskets.clear('basket_abc123');

console.log(emptyBasket.common.itemCount); // 0
```

### updateStatus()

Update basket status.

```typescript theme={null}
Baskets.updateStatus(basketId: string, status: BasketStatus): Promise<BasketStatus>
```

**Example:**

```typescript theme={null}
await Baskets.updateStatus('basket_abc123', BasketStatus.ABANDONED);
```

### updateMetadata()

Update basket metadata.

```typescript theme={null}
Baskets.updateMetadata(basketId: string, metadata: Record<string, any>): Promise<Record<string, any>>
```

**Example:**

```typescript theme={null}
await Baskets.updateMetadata('basket_abc123', {
  notes: 'Gift wrapping requested',
  giftMessage: 'Happy Birthday!',
  deliveryDate: '2025-12-25'
});
```

### placeOrder()

Convert basket to order (checkout).

```typescript theme={null}
Baskets.placeOrder(orderData: Record<string, any>, basketId: string): Promise<OrderInstance>
```

<ParamField path="orderData.shippingAddress" type="object" required>
  Shipping address information
</ParamField>

<ParamField path="orderData.paymentMethod" type="string" required>
  Payment method (e.g., 'stripe', 'paypal')
</ParamField>

<ParamField path="basketId" type="string" required>
  Basket ID to convert to order
</ParamField>

**Example:**

```typescript theme={null}
const order = await Baskets.placeOrder({
  shippingAddress: {
    street: '123 Main St',
    city: 'New York',
    state: 'NY',
    zip: '10001',
    country: 'USA'
  },
  paymentMethod: 'stripe'
}, 'basket_abc123');

console.log(order.id);     // "order_def456"
console.log(order.common.status); // "pending"
```

## BasketInstance

All basket methods return `BasketInstance` objects with:

**Direct Property Access:**

```typescript theme={null}
basket.id
basket.totalAmount    // No .common needed!
basket.itemCount      // Direct access
basket.status         // Direct access
basket.items          // Array of items
basket.currency
basket.metadata
basket.createdAt      // Via proxy
basket.updatedAt      // Via proxy
```

**Instance Methods:**

```typescript theme={null}
await basket.addItem({...});
await basket.removeItem(itemId);
await basket.updateMetadata({...});
await basket.updateStatus(status);
await basket.clear();
await basket.placeOrder({...});
```

**Backward Compatible:**

```typescript theme={null}
basket.totalAmount;         // ✅ New way
basket.common.totalAmount;  // ✅ Old way still works
```

## Complete Shopping Flow Example

```typescript theme={null}
import { LuaTool, Products, Baskets } from 'lua-cli';
import { z } from 'zod';

// Tool 1: Create Basket
export class CreateBasketTool implements LuaTool {
  name = "create_basket";
  description = "Start a new shopping session";
  inputSchema = z.object({});

  async execute(input: any) {
    const basket = await Baskets.create({
      currency: 'USD',
      metadata: { createdBy: 'chat' }
    });
    
    return {
      basketId: basket.id,
      message: "Shopping basket created! Start adding items."
    };
  }
}

// Tool 2: Add to Basket
export class AddToBasketTool implements LuaTool {
  name = "add_to_basket";
  description = "Add a product to shopping basket";
  
  inputSchema = z.object({
    basketId: z.string(),
    productId: z.string(),
    quantity: z.number().min(1).default(1)
  });

  async execute(input: z.infer<typeof this.inputSchema>) {
    // Get product details
    const product = await Products.getById(input.productId);
    
    // Check stock
    if (!product.inStock) {
      return {
        success: false,
        message: `${product.name} is out of stock`
      };
    }
    
    // Add to basket
    const basket = await Baskets.addItem(input.basketId, {
      id: input.productId,
      price: product.price,
      quantity: input.quantity,
      SKU: product.sku
    });
    
    return {
      basketId: basket.id,
      itemCount: basket.common.itemCount,
      total: `$${basket.common.totalAmount.toFixed(2)}`,
      message: `Added ${input.quantity}x ${product.name} to basket`
    };
  }
}

// Tool 3: Checkout
export class CheckoutTool implements LuaTool {
  name = "checkout";
  description = "Complete purchase and create order";
  
  inputSchema = z.object({
    basketId: z.string(),
    shippingAddress: z.object({
      street: z.string(),
      city: z.string(),
      state: z.string(),
      zip: z.string()
    }),
    paymentMethod: z.string().default('stripe')
  });

  async execute(input: z.infer<typeof this.inputSchema>) {
    // Get basket
    const basket = await Baskets.getById(input.basketId);
    
    // Verify basket has items
    if (basket.common.itemCount === 0) {
      return {
        success: false,
        message: "Cannot checkout empty basket"
      };
    }
    
    // Place order
    const order = await Baskets.placeOrder({
      shippingAddress: input.shippingAddress,
      paymentMethod: input.paymentMethod
    }, input.basketId);
    
    return {
      success: true,
      orderId: order.id,
      total: `$${basket.common.totalAmount.toFixed(2)}`,
      status: order.common.status,
      message: "Order placed successfully!"
    };
  }
}
```

## Best Practices

<AccordionGroup>
  <Accordion title="Verify Basket Exists">
    ```typescript theme={null}
    const basket = await Baskets.getById(basketId);

    if (!basket) {
      throw new Error(`Basket not found: ${basketId}`);
    }
    ```
  </Accordion>

  <Accordion title="Check Items Before Checkout">
    ```typescript theme={null}
    const basket = await Baskets.getById(basketId);

    if (basket.common.itemCount === 0) {
      return {
        success: false,
        message: "Cannot checkout empty basket"
      };
    }
    ```
  </Accordion>

  <Accordion title="Store Metadata">
    Use metadata for tracking:

    ```typescript theme={null}
    await Baskets.updateMetadata(basketId, {
      source: 'mobile_app',
      promotionCode: 'SUMMER2025',
      referralSource: 'instagram'
    });
    ```
  </Accordion>

  <Accordion title="Handle Abandoned Baskets">
    ```typescript theme={null}
    // Mark as abandoned after timeout
    setTimeout(async () => {
      await Baskets.updateStatus(
        basketId,
        BasketStatus.ABANDONED
      );
    }, 30 * 60 * 1000); // 30 minutes
    ```
  </Accordion>
</AccordionGroup>

## Common Patterns

### View Cart

```typescript theme={null}
export class ViewCartTool implements LuaTool {
  async execute(input: { basketId: string }) {
    const basket = await Baskets.getById(input.basketId);
    
    return {
      items: basket.items.map(item => ({
        product: item.id,
        quantity: item.quantity,
        price: `$${item.price}`,
        subtotal: `$${(item.price * item.quantity).toFixed(2)}`
      })),
      total: `$${basket.common.totalAmount.toFixed(2)}`,
      itemCount: basket.common.itemCount
    };
  }
}
```

### Apply Discount

```typescript theme={null}
export class ApplyDiscountTool implements LuaTool {
  async execute(input: { basketId: string; code: string }) {
    const basket = await Baskets.getById(input.basketId);
    
    // Apply discount logic
    const discountPercent = getDiscountForCode(input.code);
    const discountAmount = basket.common.totalAmount * (discountPercent / 100);
    
    await Baskets.updateMetadata(input.basketId, {
      discountCode: input.code,
      discountAmount,
      originalTotal: basket.common.totalAmount
    });
    
    return {
      discount: `${discountPercent}%`,
      saved: `$${discountAmount.toFixed(2)}`,
      newTotal: `$${(basket.common.totalAmount - discountAmount).toFixed(2)}`
    };
  }
}
```

## Next Steps

<CardGroup cols={2}>
  <Card title="Orders API" icon="receipt" href="/api/orders">
    Manage orders after checkout
  </Card>

  <Card title="Basket Examples" icon="layer-group" href="/examples/baskets">
    See complete workflow examples
  </Card>
</CardGroup>
