# SuperLeap SDK v2.0.0

A comprehensive JavaScript SDK for interacting with SuperLeap CRM API with Django-like query builder functionality, advanced caching, and optimized performance.

## Features

- 🚀 **Django-like Query Builder**: Familiar ORM-style querying with method chaining
- ⚡ **Lazy Execution**: Await query builders directly for intuitive querying
- 📝 **Full CRUD Operations**: Create, read, update, and delete records
- 🔍 **Advanced Filtering**: Support for complex filters with AND/OR conditions
- 🎯 **TypeScript Support**: Full TypeScript definitions included
- 📊 **Pagination**: Built-in pagination support
- 🔄 **Relationship Support**: Handle related objects and foreign keys
- 🎨 **Modern API**: Clean, intuitive interface with promises/async-await
- 📦 **Zero Dependencies**: Pure JavaScript with no external dependencies
- 🚀 **Advanced Caching**: Intelligent caching with TTL support and cache invalidation
- 🔧 **Smart Schema Management**: Lazy-loaded schema with field validation
- 📈 **Performance Optimized**: Minimal API calls with opt-in caching strategies

## Installation & Usage

### For React/Vue/Angular Apps (Module Import)

#### Installation

```bash
# Via npm
npm install superleap-sdk

# Via yarn
yarn add superleap-sdk
```

#### Usage in React Component

```javascript
import { createSuperLeapSDK } from "superleap-sdk";
// or
import SuperLeapSDK from "superleap-sdk";

function MyComponent() {
  const [records, setRecords] = useState([]);

  useEffect(() => {
    // Initialize SDK with advanced caching
    const sdk = createSuperLeapSDK({
      apiKey: "your-api-key",
      baseUrl: "https://app.superleap.dev/api/v1",
      clientId: "your-client-id",
      clientSecret: "your-client-secret",
      cache: {
        enabled: true,
        maxSize: 2000,
        defaultTTL: 5 * 60 * 1000, // 5 minutes
        ttl: {
          schema: 30 * 60 * 1000, // 30 minutes
          records: 2 * 60 * 1000, // 2 minutes
          count: 60 * 1000, // 1 minute
          user: 10 * 60 * 1000, // 10 minutes
        },
      },
    });

    // Use the SDK with lazy execution and caching
    const loadData = async () => {
      const userModel = sdk.getModel("user");
      // Enable caching for this query
      const users = await userModel
        .select("name", "email", "status")
        .where({ status: "active" })
        .cache({ ttl: 60 * 1000 }); // Cache for 1 minute
      setRecords(users);
    };

    loadData();
  }, []);

  return (
    <div>
      {records.map((record) => (
        <div key={record.id}>{record.get("name")}</div>
      ))}
    </div>
  );
}
```

#### TypeScript Usage

```typescript
import {
  SuperLeapSDK,
  createSuperLeapSDK,
  Model,
  RecordInstance,
} from "superleap-sdk";

const sdk: SuperLeapSDK = createSuperLeapSDK({
  apiKey: "your-api-key",
  baseUrl: "https://app.superleap.dev/api/v1",
  clientId: "your-client-id",
  clientSecret: "your-client-secret",
});

// Full type safety
const userModel: Model = sdk.getModel("user");
const users: RecordInstance[] = await userModel.select("name", "email").cache();
```

### For Vanilla JS/HTML (Script Tag)

#### Installation

```html
<!-- Via CDN -->
<script src="https://cdn.jsdelivr.net/npm/superleap-sdk@latest/superleap.js"></script>

<!-- Or download and include locally -->
<script src="path/to/superleap.js"></script>
```

#### Usage in HTML/JavaScript

```html
<!DOCTYPE html>
<html>
  <head>
    <title>SuperLeap SDK Example</title>
    <script src="https://cdn.jsdelivr.net/npm/superleap-sdk@latest/superleap.js"></script>
  </head>
  <body>
    <div id="results"></div>

    <script>
      // SDK is automatically available as global
      const sdk = createSuperLeapSDK({
        apiKey: "your-api-key",
        baseUrl: "https://app.superleap.dev/api/v1",
        clientId: "your-client-id",
        clientSecret: "your-client-secret",
        cache: { enabled: true },
      });

      // Alternative: Direct instantiation
      // const sdk = new SuperLeapSDK({...options});

      async function loadUsers() {
        try {
          const userModel = sdk.getModel("user");
          // Await the query builder directly with caching
          const users = await userModel
            .select("name", "email")
            .where({ status: "active" })
            .cacheTTL(60 * 1000); // Cache for 1 minute

          const resultsDiv = document.getElementById("results");
          resultsDiv.innerHTML = users
            .map(
              (user) => `<div>${user.get("name")} - ${user.get("email")}</div>`
            )
            .join("");
        } catch (error) {
          console.error("Error:", error);
        }
      }

      // Load data when page loads
      loadUsers();
    </script>
  </body>
</html>
```

#### Global Variables Available

```javascript
// These are automatically available in vanilla JS:
window.SuperLeapSDK; // Constructor class
window.createSuperLeapSDK; // Factory function
window.DataType; // Data type constants
window.RelationshipType; // Relationship type constants
window.CacheManager; // Cache manager class
window.CacheEntry; // Cache entry class

// Usage examples:
const sdk1 = new SuperLeapSDK({ apiKey: "key" });
const sdk2 = createSuperLeapSDK({ apiKey: "key" });
console.log(DataType.Email); // 11
console.log(RelationshipType.OneToMany); // 2
```

## Quick Start

### Initialize the SDK

```javascript
const sdk = createSuperLeapSDK({
  apiKey: "your-bearer-token", // Required
  baseUrl: "https://app.superleap.dev/api/v1", // Optional
  clientId: "your-client-id", // Required
  clientSecret: "your-client-secret", // Required
  cache: {
    // Optional - Advanced caching
    enabled: true,
    maxSize: 2000,
    defaultTTL: 5 * 60 * 1000,
    ttl: {
      schema: 30 * 60 * 1000, // 30 minutes
      records: 2 * 60 * 1000, // 2 minutes
      count: 60 * 1000, // 1 minute
      user: 10 * 60 * 1000, // 10 minutes
    },
  },
});
```

### Basic CRUD Operations

```javascript
// Initialize the SDK
const sdk = createSuperLeapSDK({
  apiKey: "your-api-key",
  baseUrl: "https://app.superleap.dev/api/v1",
  clientId: "your-client-id",
  clientSecret: "your-client-secret",
});

// Get a model
const userModel = sdk.getModel("user");

// Create a new record
const newUser = await userModel.create({
  name: "John Doe",
  email: "john@example.com",
  status: "active",
});

// Query records with caching - await the query builder directly
const activeUsers = await userModel
  .select("name", "email", "status")
  .where({ status: "active" })
  .orderBy("-created_at")
  .limit(10)
  .cache(); // Enable caching

// Update a record (use model.update instead of deprecated record.update)
const updatedUser = await userModel.update(newUser.id, {
  name: "John Smith",
});

// Delete a record
await userModel.delete(newUser.id);
```

## Documentation

### Initialization

```javascript
const sdk = createSuperLeapSDK({
  apiKey: "your-bearer-token", // Required
  baseUrl: "https://app.superleap.dev/api/v1", // Optional
  clientId: "your-client-id", // Required
  clientSecret: "your-client-secret", // Required
  cache: {
    // Optional - Advanced caching
    enabled: true, // Enable/disable caching (default: true)
    maxSize: 2000, // Maximum cache entries (default: 1000)
    defaultTTL: 5 * 60 * 1000, // Default TTL in milliseconds (default: 5 minutes)
    ttl: {
      // Specific TTL settings
      schema: 30 * 60 * 1000, // Schema cache TTL (default: 30 minutes)
      records: 2 * 60 * 1000, // Record queries TTL (default: 2 minutes)
      count: 60 * 1000, // Count queries TTL (default: 1 minute)
      user: 10 * 60 * 1000, // User data TTL (default: 10 minutes)
    },
  },
});
```

### Models

Get a model instance for any SuperLeap object:

```javascript
const model = sdk.getModel("objectSlug");
// or
const model = sdk.model("objectSlug");
```

### Query Builder

The query builder provides a Django-like interface with **lazy execution** - you can await query builders directly:

#### Basic Queries

```javascript
// Get all records
const records = await model.selectAll();

// Get first 10 records
const records = await model.selectAll().limit(10);

// Get first record
const record = await model.selectAll().first();

// Count records
const count = await model.selectAll().count();

// Check if records exist
const exists = await model.selectAll().exists();
```

#### Field Selection

```javascript
// Select specific fields
const records = await model.select("name", "email", "created_at");

// Select all fields
const records = await model.selectAll();

// Select related fields (dot notation)
const records = await model.select("user.name", "user.email");
```

#### Filtering

```javascript
// Simple where conditions
const records = await model
  .select("name", "email")
  .where({ status: "active", type: "premium" });

// Field-specific filters
const records = await model
  .select("name", "email")
  .exact("status", "active")
  .contains("name", "John")
  .gt("age", 18)
  .in("department", ["sales", "marketing"]);
```

#### Available Filter Methods

| Method                       | Description                      | Example                                |
| ---------------------------- | -------------------------------- | -------------------------------------- |
| `exact(field, value)`        | Exact match                      | `.exact('status', 'active')`           |
| `iexact(field, value)`       | Case-insensitive exact match     | `.iexact('status', 'ACTIVE')`          |
| `notexact(field, value)`     | Not exact match                  | `.notexact('status', 'inactive')`      |
| `notiexact(field, value)`    | Case-insensitive not exact match | `.notiexact('status', 'INACTIVE')`     |
| `contains(field, value)`     | Contains text (case-sensitive)   | `.contains('name', 'John')`            |
| `icontains(field, value)`    | Case-insensitive contains        | `.icontains('name', 'john')`           |
| `startswith(field, value)`   | Starts with                      | `.startswith('name', 'John')`          |
| `endswith(field, value)`     | Ends with                        | `.endswith('email', '@gmail.com')`     |
| `in(field, values)`          | In array                         | `.in('status', ['active', 'pending'])` |
| `notin(field, values)`       | Not in array                     | `.notin('status', ['inactive'])`       |
| `gt(field, value)`           | Greater than                     | `.gt('age', 18)`                       |
| `gte(field, value)`          | Greater than or equal            | `.gte('score', 80)`                    |
| `lt(field, value)`           | Less than                        | `.lt('price', 100)`                    |
| `lte(field, value)`          | Less than or equal               | `.lte('quantity', 50)`                 |
| `between(field, [min, max])` | Between values                   | `.between('age', [18, 65])`            |
| `isempty(field)`             | Field is empty                   | `.isempty('description')`              |
| `isnotempty(field)`          | Field is not empty               | `.isnotempty('email')`                 |
| `exists(field)`              | Field exists                     | `.exists('phone')`                     |
| `notexists(field)`           | Field does not exist             | `.notexists('fax')`                    |
| `like(field, value)`         | Like pattern                     | `.like('name', 'John%')`               |
| `ilike(field, value)`        | Case-insensitive like            | `.ilike('name', 'john%')`              |
| `notcontains(field, value)`  | Does not contain                 | `.notcontains('description', 'spam')`  |

#### Complex Filtering

```javascript
// AND conditions
const records = await model.select("name", "email").whereAnd((q) => {
  q.gte("age", 18);
  q.contains("name", "John");
  q.exact("status", "active");
});

// OR conditions
const records = await model.select("name", "email").whereOr((q) => {
  q.contains("name", "John");
  q.contains("name", "Jane");
});

// Combined AND/OR
const records = await model
  .select("name", "email")
  .whereAnd((q) => {
    q.exact("status", "active");
    q.gte("age", 18);
  })
  .whereOr((q) => {
    q.contains("department", "sales");
    q.contains("department", "marketing");
  });

// Direct filter structure
const records = await model.select("name", "email").filterBy({
  and: [
    { field: "status", operator: "eq", value: "active" },
    { field: "age", operator: "gte", value: 18 },
  ],
});
```

#### Sorting

```javascript
// Single field ascending
const records = await model.select("name", "email").orderBy("name");

// Single field descending
const records = await model.select("name", "email").orderBy("-created_at");

// Multiple fields
const records = await model
  .select("name", "email")
  .orderBy("department", "-created_at", "name");
```

#### Pagination

```javascript
// Limit results
const records = await model.select("name", "email").limit(10);

// Page-based pagination
const records = await model.select("name", "email").page(2).limit(10);

// Offset-based pagination
const records = await model.select("name", "email").offset(20).limit(10);
```

#### Caching Options

```javascript
// Enable caching for this query
const records = await model
  .select("name", "email")
  .where({ status: "active" })
  .cache();

// Custom TTL for this query
const records = await model
  .select("name", "email")
  .where({ status: "active" })
  .cacheTTL(60 * 60 * 1000); // 1 hour

// Disable cache for this query
const records = await model
  .select("name", "email")
  .where({ status: "active" })
  .noCache();

// Advanced cache options
const records = await model
  .select("name", "email")
  .where({ status: "active" })
  .cacheOptions({
    useCache: true,
    cacheTTL: 60 * 60 * 1000,
  });
```

### CRUD Operations

#### Create

```javascript
// Create a single record
const record = await model.create({
  name: "John Doe",
  email: "john@example.com",
  status: "active",
});

// Bulk create
const records = await model.bulkCreate(
  [
    { name: "John", email: "john@example.com" },
    { name: "Jane", email: "jane@example.com" },
  ],
  true,
  false
); // ignoreDuplicates=true, enablePartialUpsert=false

// Bulk update (records must have IDs)
const updatedRecords = await model.bulkUpdate(
  [
    { id: "record-id-1", name: "Updated John" },
    { id: "record-id-2", email: "updated@example.com" },
  ],
  false,
  false
); // ignoreDuplicates=false, enablePartialUpsert=false
```

#### Read

```javascript
// Get by ID (deprecated - use select instead)
const record = await model.get("record-id");

// Get or create (deprecated - use select instead)
const result = await model.getOrCreate(
  { email: "john@example.com" },
  { name: "John Doe", status: "active" }
);
console.log(result.record, result.created);
```

#### Update

```javascript
// Update by ID
const updated = await model.update("record-id", {
  name: "Updated Name",
});

// Update or create (deprecated - use select + update/create instead)
const result = await model.updateOrCreate(
  { email: "john@example.com" },
  { name: "John Doe", status: "active" }
);
```

#### Delete

```javascript
// Delete by ID
const deleted = await model.delete("record-id");

// Delete multiple records
const deleted = await model.deleteMany(["id1", "id2", "id3"]);
```

### Working with Records

```javascript
// Get field values
const name = record.get("name");
const email = record.get("email");

// Set field values
record.set("name", "New Name");
record.set("status", "inactive");

// Update record (DEPRECATED - use model.update instead)
const updated = await record.update({
  name: "Updated Name",
  status: "active",
});

// Delete record
const deleted = await record.delete();

// Refresh from server (deprecated - use model.select instead)
const refreshed = await record.refresh();

// Convert to plain object
const data = record.toJSON();
```

### Schema and Field Information

```javascript
// Get object schema
const schema = await model.getSchema();

// Get all fields
const fields = await model.getFields();

// Get specific field info
const field = await model.getField("fieldSlug");
console.log(field.displayName, field.dataType, field.isRequired);
```

### Advanced Caching

```javascript
// Get cache statistics
const stats = sdk.getCacheStats();
console.log("Hit rate:", stats.hitRate);
console.log("Cache size:", stats.size);

// Clear all cache
sdk.clearCache();

// Invalidate cache for specific object
sdk.invalidateCache("user");

// Clean expired entries
const cleaned = sdk.cleanExpiredCache();

// Enable/disable caching globally
sdk.setCacheEnabled(false);

// Set client credentials
sdk.setClientCredentials("new-client-id", "new-client-secret");
```

### Transactional Operations

```javascript
// Transactional bulk create across multiple objects
const result = await sdk.transactionalBulkCreate(
  [
    {
      object_slug: "user",
      record: { name: "John", email: "john@example.com" },
    },
    {
      object_slug: "lead",
      record: { name: "Jane", email: "jane@example.com" },
    },
  ],
  false
); // partialUpsert=false

// Transactional bulk update across multiple objects
const result = await sdk.transactionalBulkUpdate(
  [
    { object_slug: "user", record: { id: "user-id", name: "Updated John" } },
    { object_slug: "lead", record: { id: "lead-id", status: "qualified" } },
  ],
  false
); // partialUpsert=false

// Transactional bulk upsert across multiple objects
const result = await sdk.transactionalBulkUpsert(
  [
    {
      object_slug: "user",
      record: { name: "John", email: "john@example.com" },
    }, // Create
    { object_slug: "lead", record: { id: "lead-id", status: "qualified" } }, // Update
  ],
  false
); // partialUpsert=false
```

### User Management

```javascript
// Get current user data
const userData = await sdk.getCurrentUserData();

// Get current user with formatted data
const user = await sdk.getCurrentUser();
console.log(user.user.name, user.orgId, user.timezone);
```

### Error Handling

```javascript
try {
  // Query with error handling
  const records = await model
    .select("name", "email")
    .filter("email", "contains", "invalid");
} catch (error) {
  console.error("Query failed:", error.message);
}

try {
  const record = await model.create({
    name: "Test User",
    email: "invalid-email",
  });
} catch (error) {
  console.error("Failed to create record:", error.message);
}
```

## TypeScript Support

The SDK includes full TypeScript definitions:

```typescript
import {
  SuperLeapSDK,
  createSuperLeapSDK,
  Model,
  RecordInstance,
  DataType,
  RelationshipType,
} from "superleap-sdk";

const sdk: SuperLeapSDK = createSuperLeapSDK({
  apiKey: "your-api-key",
  baseUrl: "https://app.superleap.dev/api/v1",
});

// TypeScript will provide full autocomplete and type checking
const model: Model = sdk.getModel("user");
const records: RecordInstance[] = await model.select("name", "email").cache();

// Use constants
console.log(DataType.Email); // 11
console.log(RelationshipType.OneToMany); // 2
```

## Browser Support

The SDK works in all modern browsers and supports:

- Chrome 60+
- Firefox 55+
- Safari 12+
- Edge 79+

## Development

### Setup for Local Development

1. Clone the repository
2. Install dependencies:

   ```bash
   yarn install
   ```

3. Link the package for local development:

   ```bash
   yarn link
   ```

4. In your consuming project:

   ```bash
   yarn link superleap-sdk
   ```

5. Start the demo server:
   ```bash
   yarn demo
   ```

### Publishing

```bash
# Build and publish to npm
yarn publish
```

## Examples

Check out the included `index.html` file for a complete interactive example with Monaco Editor integration.

## API Reference

### SuperLeapSDK Class

| Method                             | Description                          |
| ---------------------------------- | ------------------------------------ |
| `getModel(slug)`                   | Get model instance                   |
| `model(slug)`                      | Alias for getModel                   |
| `setApiKey(key)`                   | Set API key                          |
| `setClientCredentials(id, secret)` | Set client credentials               |
| `request(endpoint, options)`       | Make raw API request                 |
| `getCurrentUserData()`             | Get current user data                |
| `getCurrentUser()`                 | Get formatted current user info      |
| `getCacheStats()`                  | Get cache statistics                 |
| `clearCache()`                     | Clear all cache                      |
| `invalidateCache(objectSlug)`      | Invalidate cache for specific object |
| `cleanExpiredCache()`              | Clean expired cache entries          |
| `setCacheEnabled(enabled)`         | Enable/disable caching globally      |

### Model Class

| Method                                                       | Description                            |
| ------------------------------------------------------------ | -------------------------------------- |
| `select(...fields)`                                          | Get query builder with selected fields |
| `selectAll()`                                                | Get query builder with all fields      |
| `create(data)`                                               | Create record                          |
| `get(id)`                                                    | Get record by ID (deprecated)          |
| `update(id, data)`                                           | Update record                          |
| `delete(id)`                                                 | Delete record                          |
| `deleteMany(ids)`                                            | Delete multiple records                |
| `bulkCreate(records, ignoreDuplicates, enablePartialUpsert)` | Bulk create records                    |
| `bulkUpdate(records, ignoreDuplicates, enablePartialUpsert)` | Bulk update records                    |
| `getSchema()`                                                | Get object schema                      |
| `getFields()`                                                | Get all fields                         |
| `getField(fieldSlug)`                                        | Get specific field info                |

### QueryBuilder Class

| Method                           | Description                      |
| -------------------------------- | -------------------------------- |
| `await queryBuilder`             | Execute query and return results |
| `select(...fields)`              | Select fields                    |
| `selectAll()`                    | Select all fields                |
| `where(conditions)`              | Add WHERE conditions             |
| `whereAnd(callback)`             | Add complex AND conditions       |
| `whereOr(callback)`              | Add complex OR conditions        |
| `filter(field, operator, value)` | Add filter                       |
| `filterBy(filterObject)`         | Add complex filter structure     |
| `exact(field, value)`            | Exact match filter               |
| `contains(field, value)`         | Contains filter                  |
| `gt(field, value)`               | Greater than filter              |
| `gte(field, value)`              | Greater than or equal filter     |
| `lt(field, value)`               | Less than filter                 |
| `lte(field, value)`              | Less than or equal filter        |
| `in(field, values)`              | In array filter                  |
| `orderBy(...fields)`             | Add sorting                      |
| `limit(n)`                       | Limit results                    |
| `page(n)`                        | Set page number                  |
| `offset(n)`                      | Set offset                       |
| `first()`                        | Get first result                 |
| `count()`                        | Get count                        |
| `exists()`                       | Check if records exist           |
| `cache(options)`                 | Enable caching                   |
| `cacheTTL(ttl)`                  | Set custom cache TTL             |
| `noCache()`                      | Disable caching                  |
| `cacheOptions(options)`          | Set advanced cache options       |

### RecordInstance Class

| Method              | Description                      |
| ------------------- | -------------------------------- |
| `get(field)`        | Get field value                  |
| `set(field, value)` | Set field value                  |
| `update(data)`      | Update record (deprecated)       |
| `delete()`          | Delete record                    |
| `refresh()`         | Refresh from server (deprecated) |
| `toJSON()`          | Convert to plain object          |

### CacheManager Class

| Method                 | Description           |
| ---------------------- | --------------------- |
| `get(key)`             | Get cached value      |
| `set(key, value, ttl)` | Set cached value      |
| `delete(key)`          | Delete cached value   |
| `clear()`              | Clear all cache       |
| `getStats()`           | Get cache statistics  |
| `cleanExpired()`       | Clean expired entries |

### DataType Constants

| Constant                   | Value | Description            |
| -------------------------- | ----- | ---------------------- |
| `DataType.Int`             | 1     | Integer                |
| `DataType.Varchar`         | 5     | Variable character     |
| `DataType.Checkbox`        | 6     | Boolean/Checkbox       |
| `DataType.DateTime`        | 7     | Date and time          |
| `DataType.Date`            | 8     | Date only              |
| `DataType.Email`           | 11    | Email address          |
| `DataType.Text`            | 14    | Long text              |
| `DataType.SingleSelect`    | 15    | Single select dropdown |
| `DataType.MultiSelect`     | 16    | Multi select dropdown  |
| `DataType.Url`             | 17    | URL                    |
| `DataType.FileUpload`      | 20    | File upload            |
| `DataType.PhoneNumber`     | 21    | Phone number           |
| `DataType.Rating`          | 22    | Rating field           |
| `DataType.Decimal`         | 4     | Decimal number         |
| `DataType.Currency`        | 23    | Currency field         |
| `DataType.Stage`           | 24    | Stage field            |
| `DataType.Location`        | 18    | Location field         |
| `DataType.Region`          | 27    | Region field           |
| `DataType.MultiFileUpload` | 29    | Multiple file upload   |

### RelationshipType Constants

| Constant                      | Value | Description              |
| ----------------------------- | ----- | ------------------------ |
| `RelationshipType.OneToOne`   | 1     | One-to-one relationship  |
| `RelationshipType.OneToMany`  | 2     | One-to-many relationship |
| `RelationshipType.ManyToOne`  | 3     | Many-to-one relationship |
| `RelationshipType.Restricted` | 6     | Restricted relationship  |

## Migration Guide from v1.x

### Breaking Changes

1. **Deprecated Methods**: Several methods are now deprecated and will be removed in future versions:

   - `record.update()` → Use `model.update(id, data)` instead
   - `model.get()` → Use `model.select().first()` instead
   - `model.getOrCreate()` → Use `model.select().first()` + `model.create()` instead
   - `model.updateOrCreate()` → Use `model.select().first()` + `model.update()` or `model.create()` instead
   - `record.refresh()` → Use `model.select(id)` instead

2. **Caching**: Caching is now enabled by default with intelligent TTL management

3. **Query Builder**: Enhanced with more filter methods and better performance

### New Features

1. **Advanced Caching**: Configurable TTL per operation type
2. **New Filter Methods**: `iexact`, `notexact`, `notiexact`, `exists`, `notexists`, `like`, `ilike`, `notcontains`
3. **Complex Filtering**: `whereAnd()`, `whereOr()`, `filterBy()`
4. **Transactional Operations**: Cross-object bulk operations
5. **Schema Management**: Lazy-loaded schema with field validation
6. **Performance Optimizations**: Minimal API calls and intelligent cache invalidation

## Contributing

1. Fork the repository
2. Install dependencies: `yarn install`
3. Create your feature branch (`git checkout -b feature/amazing-feature`)
4. Commit your changes (`git commit -m 'Add some amazing feature'`)
5. Push to the branch (`git push origin feature/amazing-feature`)
6. Open a Pull Request

## License

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

## Support

For questions and support, please open an issue on GitHub or contact the SuperLeap team.
