JSPM

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

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

Package Exports

  • superleap-sdk
  • superleap-sdk/mobile
  • superleap-sdk/web

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.