JSPM

  • Created
  • Published
  • Downloads 63
  • Score
    100M100P100Q71885F
  • License ISC

A comprehensive JavaScript SDK for interacting with SuperLeap CRM API with Django-like query builder

Package Exports

    This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (superleap-sdk) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.

    Readme

    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

    # Via npm
    npm install superleap-sdk
    
    # Via yarn
    yarn add superleap-sdk

    Usage in React Component

    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

    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

    <!-- 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

    <!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

    // 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

    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

    // 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

    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:

    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

    // 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

    // 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

    // 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

    // 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

    // 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

    // 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

    // 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

    // 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

    // 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

    // 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

    // Delete by ID
    const deleted = await model.delete("record-id");
    
    // Delete multiple records
    const deleted = await model.deleteMany(["id1", "id2", "id3"]);

    Working with Records

    // 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

    // 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

    // 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

    // 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

    // 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

    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:

    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:

      yarn install
    3. Link the package for local development:

      yarn link
    4. In your consuming project:

      yarn link superleap-sdk
    5. Start the demo server:

      yarn demo

    Publishing

    # 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 file for details.

    Support

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