Skip to main content

Overview

The Products API provides complete CRUD operations for managing an e-commerce product catalog. Returns ProductInstance objects with direct property access.
import { Products } from 'lua-cli';

// Search products - returns ProductSearchInstance
const results = await Products.search('laptop');

// Direct property access on results
const names = results.map(p => p.name);
const prices = results.map(p => p.price);

// Create product - returns ProductInstance
const product = await Products.create({
  name: 'MacBook Pro',
  price: 1999.99
});

// Direct property access
console.log(product.name);   // "MacBook Pro"
console.log(product.price);  // 1999.99

// Instance methods
await product.update({ price: 1799.99 });
await product.save();
await product.delete();

Direct Access

Access properties with product.name not product.data.name

Array Methods

Use .map(), .filter() on search results

Instance Methods

Built-in update(), save(), and delete()

Iteration

Use for...of loops

Methods

Search products by name or description using semantic search.
Products.search(query: string, limit?: number): Promise<ProductSearchInstance>
query
string
required
Search query to match against product names and descriptions
limit
number
default:5
Maximum number of products to return
Returns: ProductSearchInstance - Array-like collection with direct access to products Example:
// Search with default limit (5)
const results = await Products.search('laptop');

// Search with custom limit
const moreResults = await Products.search('laptop', 10);

// Direct array methods
results.forEach(product => {
  console.log(`${product.name} - $${product.price}`);
});

// Or use .map()
const names = results.map(p => p.name);
const prices = results.map(p => p.price);

// Filter
const affordable = results.filter(p => p.price < 1000);

// Find
const specific = results.find(p => p.sku === 'LAP-001');

// Check length
console.log(`Found ${results.length} products`);

// For...of iteration
for (const product of results) {
  console.log(product.name);
}

get()

Retrieve all products with pagination.
Products.get(page?: number, limit?: number): Promise<ProductPaginationInstance>
page
number
default:1
Page number (1-indexed)
limit
number
default:10
Number of products per page
Returns: ProductPaginationInstance - Array-like collection with pagination support Example:
// Get first 20 products (page 1, limit 20)
const page = await Products.get(1, 20);

// Direct array methods
page.forEach(product => {
  console.log(`${product.name} - $${product.price}`);
});

// Access pagination info
console.log(`Page ${page.pagination.currentPage} of ${page.pagination.totalPages}`);
console.log(`Showing ${page.length} of ${page.pagination.totalCount} products`);

// Navigate pages
if (page.pagination.hasNextPage) {
  const nextPage = await page.nextPage();
}

if (page.pagination.hasPrevPage) {
  const prevPage = await page.prevPage();
}

// Use array methods
const names = page.map(p => p.name);
const inStock = page.filter(p => p.inStock);

getById()

Get a specific product by ID.
Products.getById(id: string): Promise<ProductInstance>
Returns: ProductInstance with direct property access and methods Example:
const product = await Products.getById('product_abc123');

// Direct property access
console.log(product.name);   // "MacBook Pro"
console.log(product.price);  // 1999.99
console.log(product.sku);    // "MBP-14"

// Instance methods
await product.update({ price: 1799.99 });
await product.delete();

create()

Create a new product.
Products.create(product: ProductInput): Promise<ProductInstance>
product.name
string
required
Product name
product.price
number
required
Product price
product.category
string
Product category
product.sku
string
Stock keeping unit
product.inStock
boolean
default:true
Whether product is in stock
product.description
string
Product description
Returns: ProductInstance with direct property access and methods Example:
const product = await Products.create({
  name: 'Wireless Mouse',
  price: 29.99,
  category: 'Electronics',
  sku: 'MOUSE-001',
  inStock: true,
  description: 'Ergonomic wireless mouse'
});

// Direct property access
console.log(product.id);      // "product_xyz789"
console.log(product.name);    // "Wireless Mouse"
console.log(product.price);   // 29.99

// Instance methods available
await product.update({ price: 24.99 });

update()

Update an existing product. Returns updated ProductInstance.
Products.update(data: Partial<Product>, id: string): Promise<ProductInstance>
data
object
required
Partial product data to update
id
string
required
Product ID to update
Returns: ProductInstance with updated data Example:
const product = await Products.update({
  price: 24.99,
  inStock: false
}, 'product_xyz789');

// Access updated properties
console.log(product.price);   // 24.99
console.log(product.inStock); // false

save() (Instance Method)

Save the current state of the product to the server. This is a convenience method that persists all changes made to the product instance.
product.save(): Promise<boolean>
Returns: Promise resolving to true if successful Example:
const product = await Products.getById('product_xyz789');

// Modify product properties directly
product.price = 24.99;
product.inStock = false;
product.description = "Updated description";

// Save all changes at once
await product.save();

// Much cleaner workflow!
New in Latest Version: The save() method provides a simpler workflow - modify properties then save, rather than calling Products.update() with the product ID.

delete()

Delete a product.
Products.delete(id: string): Promise<void>
Example:
await Products.delete('product_xyz789');

ProductInstance

All product methods return ProductInstance objects with: Direct Property Access:
product.name
product.price
product.sku
product.inStock
product.category
product.description
// Any custom fields
Instance Methods:
await product.update({ price: 999.99 });
await product.save();
await product.delete();
Backward Compatible:
product.name;        // ✅ New way
product.data.name;   // ✅ Old way still works

Complete Examples

Search Tool

import { LuaTool, Products } from 'lua-cli';
import { z } from 'zod';

export class SearchProductsTool implements LuaTool {
  name = "search_products";
  description = "Search for products by name or description";
  
  inputSchema = z.object({
    query: z.string().describe("Search query"),
    maxPrice: z.number().optional()
  });

  async execute(input: z.infer<typeof this.inputSchema>) {
    const results = await Products.search(input.query);
    
    // Filter by price if specified
    let products = results.data;
    if (input.maxPrice) {
      products = products.filter(p => p.price <= input.maxPrice);
    }
    
    return {
      products: products.map(p => ({
        id: p.id,
        name: p.name,
        price: `$${p.price.toFixed(2)}`,
        inStock: p.inStock ? '✅ In Stock' : '❌ Out of Stock'
      })),
      total: products.length
    };
  }
}

Create Product Tool

export class CreateProductTool implements LuaTool {
  name = "create_product";
  description = "Add a new product to the catalog";
  
  inputSchema = z.object({
    name: z.string(),
    price: z.number().positive(),
    category: z.string().optional(),
    sku: z.string().optional(),
    description: z.string().optional()
  });

  async execute(input: z.infer<typeof this.inputSchema>) {
    const result = await Products.create({
      ...input,
      inStock: true
    });
    
    return {
      success: true,
      productId: result.product.id,
      message: `Product "${input.name}" created successfully`
    };
  }
}

Update Stock Tool

export class UpdateStockTool implements LuaTool {
  name = "update_stock";
  description = "Update product stock status";
  
  inputSchema = z.object({
    productId: z.string(),
    inStock: z.boolean()
  });

  async execute(input: z.infer<typeof this.inputSchema>) {
    await Products.update(
      { inStock: input.inStock },
      input.productId
    );
    
    return {
      success: true,
      message: `Stock status updated to ${input.inStock ? 'in stock' : 'out of stock'}`
    };
  }
}

Use Cases

E-commerce Catalog

// Browse products (page 1, limit 20)
const products = await Products.get(1, 20);

// Search specific items
const laptops = await Products.search('laptop');

// Get product details
const product = await Products.getById(laptops.data[0].id);

Inventory Management

// Update product price
await Products.update({ price: 899.99 }, productId);

// Mark as out of stock
await Products.update({ inStock: false }, productId);

// Update multiple fields
await Products.update({
  price: 799.99,
  inStock: true,
  category: 'Electronics - Sale'
}, productId);

Product Recommendations

// Search similar products
const similar = await Products.search(product.category);

// Filter by price range
const affordable = similar.data.filter(p => 
  p.price < product.price * 1.2 &&
  p.price > product.price * 0.8
);

Best Practices

Always check if product exists:
const product = await Products.getById(input.productId);

if (!product) {
  throw new Error(`Product not found: ${input.productId}`);
}
const product = await Products.getById(productId);

if (!product.inStock) {
  return {
    success: false,
    message: `${product.name} is currently out of stock`
  };
}
return {
  products: products.map(p => ({
    ...p,
    price: `$${p.price.toFixed(2)}`,
    formattedPrice: new Intl.NumberFormat('en-US', {
      style: 'currency',
      currency: 'USD'
    }).format(p.price)
  }))
};
const results = await Products.search(query);

if (results.data.length === 0) {
  return {
    products: [],
    message: `No products found for "${query}". Try different search terms.`
  };
}

Next Steps