npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@optilogic/opti-js

v1.0.1

Published

TypeScript/JavaScript SDK for the Optilogic platform public API.

Readme

@optilogic/opti-js

A comprehensive TypeScript/JavaScript SDK for interacting with the Optilogic platform API. This SDK provides convenient access to all Optilogic services including storage management, workspace operations, job execution, and utility functions.

Table of Contents

Installation

npm install @optilogic/opti-js

Quick Start

import OptiJs from '@optilogic/opti-js';

// Initialize the SDK with API Key (legacy)
const api = new OptiJs({
  environment: 'user', // or 'dev'
  apiKey: process.env.OPTILOGIC_API_KEY || '',
  version: 0,
  // Optional: only needed for refreshApiKey()
  userId: process.env.OPTILOGIC_USER_ID || null,
  userPassword: process.env.OPTILOGIC_USER_PASSWORD || null,
});

// Or initialize with App Key (recommended)
const apiWithAppKey = new OptiJs({
  environment: 'user', // or 'dev'
  appKey: process.env.OPTILOGIC_APP_KEY || '',
  version: 0,
  // Optional: only needed for refreshApiKey()
  userId: process.env.OPTILOGIC_USER_ID || null,
  userPassword: process.env.OPTILOGIC_USER_PASSWORD || null,
});

// Example: Get all storage connection strings
const connections = await api.getAllConnectionStrings();
console.log('Available storages:', connections);

// Example: Create and run a workspace job
const job = await api.createWorkspaceJob(
  'Studio',           // workspace
  '/projects',        // directory path
  'my_script.py',     // filename
  undefined,          // command
  undefined,          // command args
  'mini',            // resource config (smallest)
  'sdk,example',     // tags
  60                 // timeout in seconds
);
console.log('Job created:', job);

Configuration

Constructor Options

interface Config {
  environment: "user" | "dev";  // API environment
  apiKey?: string;              // Your Optilogic API key (legacy)
  appKey?: string;              // Your Optilogic App key (new)
  version?: number;             // API version (default: 0)
  userId?: string | null;       // User ID (required for refreshApiKey)
  userPassword?: string | null; // User password (required for refreshApiKey)
}

Note: You must provide either apiKey or appKey for authentication. The appKey is the newer authentication method and is recommended for new applications.

Environment Variables

For convenience, you can use these environment variables:

# Authentication (use either API_KEY or APP_KEY)
OPTILOGIC_API_KEY=your_api_key_here      # Legacy authentication
OPTILOGIC_APP_KEY=your_app_key_here      # New authentication (recommended)

# Environment and optional settings
OPTILOGIC_ENV=user  # or 'dev'
OPTILOGIC_USER_ID=your_user_id  # optional
OPTILOGIC_USER_PASSWORD=your_password  # optional

Authentication Priority: If both OPTILOGIC_API_KEY and OPTILOGIC_APP_KEY are provided, OPTILOGIC_API_KEY will be used for backward compatibility.

API Reference

Authentication

The SDK supports two authentication methods:

API Key Authentication (Legacy)

const api = new OptiJs({
  environment: 'user',
  apiKey: 'your-api-key-here'
});

App Key Authentication (Recommended)

const api = new OptiJs({
  environment: 'user',
  appKey: 'your-app-key-here'
});

refreshApiKey()

Refreshes your API key using user credentials. This method works with both authentication types.

// Requires userId and userPassword in constructor
const newKey = await api.refreshApiKey();
console.log('New API key:', newKey.apiKey);

Storage Management

The storage API provides comprehensive database and storage management capabilities.

Connection Strings

// Get all connection strings
const allConnections = await api.getAllConnectionStrings();

// Get connection string for specific storage
const connection = await api.getStorageConnectionString('my-storage');

Database Operations

// Get database objects (tables, views, stats)
const objects = await api.getDbObjects('my-storage', 'tables');

// Get tables with row counts
const tables = await api.getTables('my-storage', true);

// Get database schema information
const schema = await api.getSchemaInfo('my-storage', 'public', 'users');

Custom Tables and Columns

// Create a custom table
await api.createCustomTable('my-storage', 'my_custom_table');

// Create a custom column
await api.createCustomColumn(
  'my-storage',
  'my_custom_table',
  'new_column',
  'varchar',
  255,        // max length
  true,       // nullable
  'default',  // default value
  false,      // is key column
  'text',     // true data type
  false       // is required
);

// Get custom tables and columns
const customTables = await api.getCustomTables('my-storage');
const customColumns = await api.getCustomColumns('my-storage', 'my_table');

Database Management

// Get all storage devices
const allStorages = await api.getAllStorages();

// Get single database details
const database = await api.getDatabase('db-id');

// Create a new database from template
const templates = await api.getAllDbTemplates(true);
const emptyTemplate = templates.templates.find(t => t.name === 'Empty Database');
await api.createDatabase('new-db', {
  id: String(emptyTemplate!.id),
  type: 'sql',
  description: 'My new database'
});

// Update database
await api.updateDatabase('db-id', 'New Name', 'New description');

// Clone a database
await api.duplicateDatabase('source-db');

// Clone with custom name and description
await api.duplicateDatabase('source-db', 'Clone Name', 'Clone description');

// Archive database (soft delete)
await api.archiveDatabase('db-id');

// Restore archived database
await api.unarchiveDatabase('db-id');

// Get all archived databases
const archived = await api.getArchivedDatabases();

// Share database with another user
await api.shareDatabaseAccess('my-db', '[email protected]');

// Share database with read-only access
await api.shareDatabaseAccess('my-db', '[email protected]', 'readonly');

// Revoke database access from a user
await api.revokeDbAccess('my-db', '[email protected]');

// Reassign database ownership
await api.reassignDatabaseOwner('my-db', '[email protected]');

// Send a copy of database to another user
await api.sendDatabaseCopy('my-db', '[email protected]');

// Delete a database
await api.deleteDatabase('db-id-or-name');

Tags and Labels

// Get database tags
const tags = await api.getStorageTags('my-storage');

// Add tags to a database
await api.addDatabaseTags('my-storage', 'tag1,tag2,tag3');

// Replace all tags on a database
await api.replaceDatabaseTags('my-storage', 'newtag1,newtag2');

// Remove tags from a database
await api.removeDbTags('my-storage', 'tag1,tag2');

// Get database labels
const labels = await api.getStorageLabels('my-storage');

// Add labels to a database
await api.addDatabaseLabels('my-storage', 'label1,label2');

// Replace all labels on a database
await api.replaceDatabaseLabels('my-storage', 'newlabel1,newlabel2');

// Remove labels from a database
await api.removeDbLabels('my-storage', ['label1', 'label2']);

Data Export

// Export data from tables
const exportJob = await api.dbDataExport(
  'my-storage',
  { sourceList: ['table1', 'table2'], sourceQuery: '' },
  'public',  // schema
  null,      // group
  'csv'      // format
);

// Get export job status
const jobStatus = await api.getDbDataExportJob(jobKey);

SQL Query Execution

// Execute a simple SQL query
const queryResult = await api.queryDbStorage(
  'my-storage-id',
  'SELECT * FROM users WHERE active = true'
);

// Execute query with schema and table targeting
const targetedQuery = await api.queryDbStorage(
  'my-storage-id',
  'SELECT COUNT(*) as total FROM shipments',
  'public',    // schema name
  'shipments'  // table name
);

// Handle query results
if (queryResult && typeof queryResult === 'object' && 'result' in queryResult) {
  console.log('Query successful:', queryResult.result);
  console.log('Row count:', queryResult.rowCount);
  console.log('Results:', queryResult.queryResults);
} else if (queryResult === 504) {
  console.log('Query timed out');
} else {
  console.log('Query failed');
}

Empty Tables

// Empty all data from specified tables (dry run first)
const dryRunResult = await api.emptyDbTables(
  'my-storage',
  { tables: ['table1', 'table2'] },
  true  // dry run - won't actually delete
);

// Actually empty the tables
const result = await api.emptyDbTables(
  'my-storage',
  { tables: ['table1', 'table2'] },
  false  // execute
);

Database Validation & Migration

Validate and migrate database schemas to newer versions.

// Get available schema upgrade versions for a database
const versions = await api.getSchemaVersions('db-id');
console.log('Available versions:', versions);

// Validate database schema and data
const validationJob = await api.validateDatabase('db-id');
console.log('Validation job key:', validationJob.jobKey);

// Get detailed validation results
const validationDetails = await api.getValidationDetails('db-id');
console.log('Validation output:', validationDetails);

// Migrate database to a specific schema version
const migrationJob = await api.migrateDatabase('db-id', '2.0.0');
console.log('Migration job key:', migrationJob.jobKey);

// Poll for validation job status
const maintainStatus = await api.getDbMaintainJobStatus(validationJob.jobKey);
console.log('Validation status:', maintainStatus);

// Poll for migration job status
const migrateStatus = await api.getDbMigrateJobStatus(migrationJob.jobKey);
console.log('Migration status:', migrateStatus);

Database Connections

Manage active database connections.

// Get active connections for a database
const connections = await api.getConnections('db-id');
console.log('Active connections:', connections);

// Close all active connections for a database
const closeResult = await api.closeConnections('db-id');
console.log('Connections closed:', closeResult);

Firewall Management

Manage database firewall rules for controlling access.

// Get all firewall rules
const rules = await api.getFirewallRules();
console.log('Firewall rules:', rules);

// Add a new firewall rule with IP address
await api.addFirewallRule(
  '192.168.1.100',    // IP address or CIDR
  'Office IP',         // rule name (optional)
  undefined,           // end IP for ranges (optional)
  null                 // expiration timestamp (null = never expires)
);

// Add a firewall rule with CIDR notation
await api.addFirewallRule(
  '10.0.0.0/24',      // CIDR block
  'VPN Range'          // rule name
);

// Add a firewall rule with IP range
await api.addFirewallRule(
  '192.168.1.1',      // start IP
  'Office Range',      // rule name
  '192.168.1.255',    // end IP
  Date.now() + 86400000  // expires in 24 hours
);

// Update an existing firewall rule
await api.updateFirewallRule(
  'rule-uuid-123',    // rule ID (required)
  'Updated Name',      // new name
  '10.0.0.0/16',      // new IP/CIDR
  undefined,           // new end IP
  null                 // new expiration (null = never)
);

// Bulk update multiple firewall rules
await api.bulkUpdateFirewallRules([
  { id: 'rule-1', name: 'Updated Rule 1', startIpOrCIDR: '192.168.1.1' },
  { id: 'rule-2', name: 'Updated Rule 2', startIpOrCIDR: '10.0.0.0/24' }
]);

// Delete a single firewall rule
await api.deleteFirewallRule('rule-uuid-123');

// Bulk delete multiple firewall rules
await api.bulkDeleteFirewallRules(['rule-1', 'rule-2', 'rule-3']);

Workspace Operations

Workspace operations allow you to manage files, run jobs, and interact with the Optilogic development environment.

Workspace Information

// Get all workspaces
const workspaces = await api.getWorkspaces();

// Get workspace information
const info = await api.getWorkspaceInfo('Studio');

File Management

// Get files in workspace
const files = await api.getWorkspaceFiles(
  'Studio',
  '*.py',     // filter
  3,          // max depth
  '/projects', // base directory
  'true'      // include directories
);

// Get specific file
const file = await api.getWorkspaceFile('Studio', '/projects', 'script.py', 'status');

// Create or update file content
await api.updateWorkspaceFileContent(
  'Studio',
  '/projects',
  'new_file.py',
  'print("Hello, World!")',
  false  // overwrite if exists
);

// Move or rename file
await api.moveWorkspaceFile(
  'Studio',
  '/old_dir', 'old_name.py',  // source
  '/new_dir', 'new_name.py'   // destination
);

// Copy file
await api.copyWorkspaceFile(
  'Studio',
  '/source', 'file.py',      // source
  '/destination', 'copy.py', // destination
  false  // overwrite
);

// Share file with users
await api.shareWorkspaceFile(
  'Studio',
  '/projects',
  'shared_script.py',
  '[email protected],[email protected]'
);

// Delete file
await api.deleteWorkspaceFile('Studio', '/projects', 'old_script.py');

Folder Management

// Create a new folder
await api.createWorkspaceFolder('Studio', '/projects', 'new_folder');

// Move folder
await api.moveWorkspaceFolder(
  'Studio',
  '/old_location/folder',
  '/new_location/folder'
);

// Share folder with users
await api.shareWorkspaceFolder(
  'Studio',
  '/projects/shared_folder',
  '[email protected],[email protected]',
  true  // include hidden files
);

// Delete folder and all contents
await api.deleteWorkspaceFolder('Studio', '/projects/old_folder');

Job Execution

// Create a single job
const job = await api.createWorkspaceJob(
  'Studio',
  '/projects',
  'optimization_script.py',
  undefined,           // command
  '--hours 48',        // command args
  'M',                 // resource config (medium)
  'production,urgent', // tags
  3600                 // timeout (1 hour)
);

// Create multiple jobs
const batchJobs = await api.createWorkspaceJobs('Studio', {
  batchItems: [
    {
      pyModulePath: '/projects/script1.py',
      commandArgs: '--param1 value1',
      timeout: 300
    },
    {
      pyModulePath: '/projects/script2.py',
      timeout: 600
    }
  ]
}, 'L', 'batch,processing'); // resource config and tags

// Search and run jobs
const searchJobs = await api.workspaceSearchAndRun('Studio', {
  batchItems: [
    {
      pySearchTerm: 'Transportation',
      commandArgs: '--hours 48'
    },
    {
      pySearchTerm: 'MIP Optimization/flow_shop_scheduling',
      timeout: 300
    }
  ]
}, 'XL', 'search,automation');

// Run jobs back-to-back (sequentially)
const backToBack = await api.workspaceBackToBack('Studio', {
  batchItems: [
    { pyModulePath: '/projects/step1.py' },
    { pyModulePath: '/projects/step2.py', commandArgs: '--input step1' }
  ]
}, 'M', 'sequential', 7200, true);

// Search and run jobs back-to-back
const searchBackToBack = await api.workspaceBackToBackSearch('Studio', {
  batchItems: [
    { pySearchTerm: 'preprocessing' },
    { pySearchTerm: 'optimization' }
  ]
}, 'L', 'pipeline', 3600, true);

Job Monitoring

// Get workspace jobs with filters
const jobs = await api.getWorkspaceJobs(
  'Studio',
  undefined,  // command filter
  '7',        // history (days)
  '3600',     // max runtime (seconds)
  '60',       // min runtime (seconds)
  'completed', // status
  'production' // tags
);

// Get job details
const jobDetails = await api.getWorkspaceJob('Studio', 'job-key-123', 'status');

// Get job metrics and stats
const metrics = await api.getJobMetrics('Studio', 'job-key-123');
const stats = await api.getJobStats('Studio', 'job-key-123');

// Get workspace job statistics
const workspaceStats = await api.getWorkspaceJobStats(
  'Studio',
  undefined,   // command filter
  '30',        // history (days)
  undefined,   // max runtime
  undefined,   // min runtime
  undefined,   // status
  'production' // tags
);

// Get job logs/ledger
const logs = await api.getWorkspaceJobLog('Studio', 'job-key-123', 'error,warning', 100);

// Stop a running job
await api.stopWorkspaceJob('Studio', 'job-key-123');

Job Management

Data Export Jobs

// Get list of data export jobs
const exportJobs = await api.getDbDataExportJobList();

// Get specific export job details
const exportJob = await api.getDbDataExportJob('export-job-key');

Job Status Methods

Generic job status polling methods.

// Get validation job status
const maintainStatus = await api.getDbMaintainJobStatus('job-key');
console.log('Validation job status:', maintainStatus);

// Get migration job status
const migrateStatus = await api.getDbMigrateJobStatus('job-key');
console.log('Migration job status:', migrateStatus);

// Generic job status polling (works for any job type)
const jobStatus = await api.getJobStatus('db-data-export', 'job-key');
console.log('Job status:', jobStatus);

// Common job types: 'db-maintain', 'db-migrate', 'db-data-export'

Utility Functions

Secret Management

// Create a secret
await api.createSecret(
  'MY_API_KEY',
  'secret-value-123',
  'api-key',           // type
  '{"env": "prod"}',   // metadata
  'Production API key' // description
);

// Get all secrets
const allSecrets = await api.getAllSecrets('api-key');

// Get specific secret
const secret = await api.getOneSecret('MY_API_KEY');

// Update secret
await api.updateSecret(
  'MY_API_KEY',
  'MY_NEW_API_KEY',    // new name
  'database',          // new type
  'new-secret-value',  // new value
  '{"env": "dev"}',    // new metadata
  'Development API key' // new description
);

// Delete secret
await api.deleteSecret('MY_API_KEY');

Database Password Management

// Regenerate database password
const newPassword = await api.regenerateDatabasePassword('db-id');
console.log('New password generated:', newPassword);

Storage Device Operations

Manage different types of storage devices (Azure File Share, OneDrive, etc.).

// Get all storage devices
const allStorages = await api.getAllStorages();

// Create a new storage device
await api.createStorage('my-azure-storage', 'Azure storage for data', 'azure_afs');

// Connect to an existing storage device
await api.connectStorage('existing-storage', 'Description', 'azure_workspace');

// Disconnect from a storage device
await api.disconnectStorage('storage-name');

Storage File Operations

Manage files within non-SQL storage devices.

// Get file structure for a storage device
const files = await api.getStorageFiles('my-storage');
console.log('Files:', files);

// Get files in a specific directory
const subFiles = await api.getStorageFiles('my-storage', 'item-id-123');

// Get tracking information for files
const tracking = await api.getStorageTracking('my-storage');
console.log('Tracking info:', tracking);

// Get tracking for specific directory
const dirTracking = await api.getStorageTracking('my-storage', 'item-id-123');

// Update tracking state for files
await api.updateStorageTracking('my-storage', {
  // tracking configuration object
});

// Delete a directory from storage
await api.deleteStorageDirectory('my-storage', '/path/to/directory', true);  // recursive

// Move a file within storage
await api.databaseMoveFile('my-storage', '/source/file.txt', '/dest/file.txt');

// Move a folder within storage
await api.databaseMoveFolder('my-storage', '/source/folder', '/dest/folder');

// Copy a folder within storage or to another storage
await api.databaseCopyFolder(
  'source-storage',
  '/source/folder',
  '/dest/folder',
  'dest-storage'  // optional, defaults to same storage
);

Database Shortcuts

Create and manage shortcuts to databases (e.g., .frog files).

// Get all database shortcuts
const shortcuts = await api.getDatabaseShortcuts();
console.log('Shortcuts:', shortcuts.shortcuts);

// Create a database shortcut
await api.createDatabaseShortcut('db-uuid-123', {
  type: 'frog',
  driveName: 'Studio',
  path: '/models/supply-chain',
  targetId: 'db-uuid-123'
});

// Update a database shortcut
await api.updateDatabaseShortcut('db-uuid-123', 'shortcut-id', {
  path: '/models/new-location'
});

// Delete a database shortcut
await api.deleteDatabaseShortcut('db-uuid-123', 'shortcut-id');

SQL Bookmarks

Save and manage SQL query snippets/bookmarks.

// Ensure SQL bookmarks schema exists
await api.ensureSqlBookmarksSchema('db-id');

// Get all SQL bookmarks for a database
const bookmarks = await api.getSqlBookmarks('db-id');
console.log('Bookmarks:', bookmarks.bookmarks);

// Save a SQL bookmark
await api.saveSqlBookmark(
  'db-id',
  'Get Active Users',
  'SELECT * FROM users WHERE active = true',
  'Query to retrieve all active users'  // optional description
);

// Delete a SQL bookmark
await api.deleteSqlBookmark('db-id', 'Get Active Users');

Backup Operations

Create and manage database backups. These use the standard API endpoints.

// Create a backup of a database
const backup = await api.createBackup(
  'db-id',
  'Pre-Migration Backup',     // name (optional)
  'Backup before schema migration'  // description (optional)
);
console.log('Backup created:', backup);

// List all backups for a database
const backups = await api.listBackups('db-id');
console.log('Available backups:', backups);

// Get a single backup by ID
const backupDetails = await api.getBackup('db-id', 'backup-uuid-123');
console.log('Backup details:', backupDetails);

// Update a backup's name and description
await api.updateBackup(
  'db-id',
  'backup-uuid-123',
  'Updated Backup Name',
  'Updated description'
);

// Delete one or more backups by IDs (comma-separated)
await api.deleteBackups('db-id', 'backup-uuid-1,backup-uuid-2');

// Bulk delete backups
await api.bulkDeleteBackups('db-id', ['backup-uuid-1', 'backup-uuid-2', 'backup-uuid-3']);

// Restore a backup to the same database
await api.restoreBackup('db-id', 'backup-uuid-123');

// Restore a backup to a new database
const newDb = await api.restoreBackupToNewDatabase('backup-uuid-123', 'restored-database');
console.log('New database created:', newDb);

Conversation Management

The conversation API provides access to AI-powered conversations and chat functionality.

Getting Conversations

// Get conversations by tags
const conversations = await api.getConversations('project-123');
console.log('Found conversations:', conversations.count);
console.log('Conversations:', conversations.items);

// Get messages from a specific conversation
const messages = await api.getConversationMessages('conversation-id-123');
console.log('Message count:', messages.count);
console.log('Messages:', messages.items);

// Get available AI models
const models = await api.getAiModels();
console.log('Available models:', models);

Creating and Managing Conversations

The conversation API supports various parameters for customization:

  • targetModel: The AI model to use (default: 'vanilla', other options include 'leapfrog')
  • preview: When true, creates a preview conversation that doesn't affect the main conversation flow (default: false)
// Create a new conversation with default settings
const newConversation = await api.createConversation(
  'Help me optimize my supply chain model',
  'supply-chain,optimization',
  'Supply Chain Optimization Discussion'
);
console.log('New conversation ID:', newConversation.conversationId);

// Create a conversation with custom model and preview
const previewConversation = await api.createConversation(
  'Test this optimization approach',
  'test,preview',
  'Test Conversation',
  'leapfrog',  // targetModel
  true         // preview
);

// Create a leapfrog conversation with database context
const leapfrogConversation = await api.createLeapfrogConversation(
  'Analyze this supply chain data',
  'db-uuid-123',               // database ID
  'analysis,supply-chain',     // tags
  'Data Analysis Session',     // name
  'leapfrog',                  // targetModel
  false                        // preview
);
console.log('Leapfrog conversation:', leapfrogConversation);

// Continue an existing conversation
const response = await api.continueConversation(
  'conversation-id-123',
  'Can you also help me with inventory management?',
  'vanilla',  // targetModel (optional, defaults to 'vanilla')
  false       // preview
);
console.log('New message ID:', response.messageId);

// Continue with a different model
const leapfrogResponse = await api.continueConversation(
  'conversation-id-123',
  'Can you analyze this database?',
  'leapfrog'  // targetModel
);

// Continue with preview mode
const previewResponse = await api.continueConversation(
  'conversation-id-123',
  'What if we try a different approach?',
  'vanilla',  // targetModel
  true        // preview
);

Conversation Data Structure

// Conversation items contain:
interface ConversationItem {
  id: string;
  databaseId: string | null;
  name: string | null;
  tags: string[];
  counts: {
    prompts: number;
    responses: number;
    supplements: number;
  };
  created: string; // ISO timestamp
  updated: string | null; // ISO timestamp
}

// Message items can be prompts or responses:
interface MessageItemPrompt {
  id: string;
  type: 'prompt';
  parent: string | null;
  childrenCount: number;
  created: string;
  prompt: string;
  targetModel: string;
}

interface MessageItemResponse {
  id: string;
  type: 'response';
  parent: string | null;
  created: string;
  respondingModel: string;
  respondingModelVersion: string;
  data: {
    type?: string;
    text?: string;
    [key: string]: any;
  };
}

Deleting Conversations

// Delete a conversation
await api.deleteConversation('conversation-id-123');

Notifications

Manage user notifications, including fetching, creating, acknowledging, and deleting notifications.

Get Notifications

// Get user notifications (with optional limit)
const notifications = await api.getUserNotifications(50);
console.log('Notifications:', notifications.notifications);

// Get a single notification by ID
const notification = await api.getSingleUserNotification('notification-uuid');
console.log('Notification:', notification.notification);

Create Notification

// Create a custom notification
const newNotification = await api.createUserNotification({
  topics: ['custom'],
  level: 'info',
  data: {
    title: 'Custom Notification',
    message: 'This is a custom notification',
    callbacks: [],
  },
});
console.log('Created notification:', newNotification.notification);

Update Notification

// Update a field in notification data
await api.updateUserNotification('notification-uuid', 'progress', 75, 'number');
await api.updateUserNotification('notification-uuid', 'status', 'completed', 'string');

Acknowledge Notifications

// Acknowledge a single notification (mark as read)
await api.acknowledgeUserNotification('notification-uuid');

// Acknowledge all notifications
const result = await api.acknowledgeAllNotifications();
console.log('Acknowledged count:', result.count);

// Acknowledge multiple notifications
await api.acknowledgeManyNotifications(['uuid-1', 'uuid-2', 'uuid-3']);

Delete Notifications

// Delete a single notification
await api.deleteUserNotification('notification-uuid', 'user');

// Delete all notifications
const result = await api.deleteAllNotifications();
console.log('Deleted count:', result.count);

// Delete multiple notifications
await api.deleteManyUserNotifications(['uuid-1', 'uuid-2'], 'dismissed');

Notification Types

import type {
  SystemNotification,
  SystemNotificationData,
  SystemNotificationCallback,
  NotificationLevel,
  DeletionReason,
  GetNotificationsResponse,
  GetNotificationResponse,
  BulkNotificationResponse,
  DeleteNotificationResponse,
} from '@optilogic/opti-js';

// DeletionReason: 'expired' | 'dismissed' | 'user'
// NotificationLevel: 'critical' | 'error' | 'warning' | 'info' | 'debug' | null

TypeScript Support

This SDK is built with TypeScript and provides full type definitions. All API methods return properly typed responses:

import OptiJs from '@optilogic/opti-js';
import type {
  StorageGetTablesResponse,
  QueryDbStorageResponse,
  WorkspacePostJobResponse,
  ConversationGetConversationsResponse,
  ConversationCreateResponse,
} from '@optilogic/opti-js';

const api = new OptiJs({ /* config */ });

// Fully typed responses
const tables: StorageGetTablesResponse = await api.getTables('storage', true);
const queryResult: QueryDbStorageResponse | number | null = await api.queryDbStorage('storage-id', 'SELECT * FROM users');
const job: WorkspacePostJobResponse = await api.createWorkspaceJob(/* ... */);
const conversations: ConversationGetConversationsResponse = await api.getConversations('project-123');
const newConversation: ConversationCreateResponse = await api.createConversation('Hello', 'test');

Available Types

All response types are exported from the main module:

  • StorageGet*Response - Storage operation responses
  • StoragePost*Response - Storage creation/mutation responses
  • StoragePut*Response - Storage update responses
  • StorageDelete*Response - Storage deletion responses
  • QueryDbStorageResponse - SQL query execution responses
  • StorageValidateDatabaseResponse - Database validation responses
  • StorageMigrateDatabaseResponse - Database migration responses
  • StorageGetSchemaVersionsResponse - Schema version responses
  • StorageGetConnectionsResponse - Connection management responses
  • StorageGetFilesResponse - Storage file operation responses
  • WorkspaceGet*Response - Workspace operation responses
  • WorkspacePost*Response - Workspace creation responses
  • WorkspaceDelete*Response - Workspace deletion responses
  • JobsGet*Response - Job operation responses (data exports, system jobs)
  • UtilityGet*Response - Utility (secret) responses
  • UtilityPost*Response / UtilityPut*Response / UtilityDelete*Response - Secret CRUD responses
  • ConversationGet*Response - Conversation operation responses
  • ConversationCreate*Response - Conversation creation responses
  • ConversationContinue*Response - Conversation continuation responses
  • ConversationDelete*Response - Conversation deletion responses
  • LeapfrogConversationCreateResponse - Leapfrog conversation responses
  • RefreshApiKeyResponse - Authentication responses
  • SystemNotification / SystemNotificationData / SystemNotificationCallback - Notification object types
  • NotificationLevel / DeletionReason - Notification severity / deletion reason types
  • GetNotificationsResponse / GetNotificationResponse - Notification fetch responses
  • BulkNotificationResponse / DeleteNotificationResponse - Bulk/delete responses
  • Get*FirewallRule*Response - Firewall rule CRUD responses
  • GetDataStar*Response - DataStar project / macro responses
  • GetAccountInfoResponse - Account info from /v0/account

Error Handling

The SDK provides comprehensive error handling with detailed error information:

try {
  const result = await api.getTables('non-existent-storage', false);
} catch (error) {
  if (error instanceof MissingCredentialsError) {
    console.error('Missing credentials:', error.details);
  } else {
    console.error('API Error:', error.message);
    // Error object contains correlationId for support
  }
}

Error Types

  • MissingCredentialsError - Thrown when required credentials are missing
  • Standard HTTP errors with correlation IDs for support

Testing

This package includes comprehensive test suites:

Unit Tests

Run unit tests (mocked, no network calls):

npm test

Integration Tests

Run integration tests against the real API:

# Set required environment variables (use either API_KEY or APP_KEY)
export OPTILOGIC_API_KEY=your_api_key      # Legacy authentication
# OR
export OPTILOGIC_APP_KEY=your_app_key      # New authentication (recommended)

export OPTILOGIC_ENV=user
export OPTILOGIC_WORKSPACE=Studio
export OPTILOGIC_STORAGE_NAME=your_storage_name

# Optional for refreshApiKey tests
export OPTILOGIC_USER_ID=your_user_id
export OPTILOGIC_USER_PASSWORD=your_password

# Run integration tests
RUN_INTEGRATION=1 npm test

Test Coverage

npm run test:coverage

Resource Configurations

When running jobs, you can specify resource configurations:

| Config | CPU | RAM | Use Case | |--------|-----|-----|----------| | mini | 0.5 | 1GB | Quick scripts, testing | | 4XS | 1 | 2GB | Small optimization models | | 3XS | 2 | 4GB | Medium optimization models | | 2XS | 4 | 8GB | Large optimization models | | XS | 8 | 16GB | Very large models | | S | 16 | 32GB | Enterprise models | | M | 32 | 64GB | Large enterprise models | | L | 64 | 128GB | Very large enterprise models | | XL | 128 | 256GB | Massive models | | 2XL | 256 | 512GB | Extreme scale models | | 3XL | 512 | 1TB | Maximum scale models | | 4XL | 1024 | 2TB | Ultra scale models |

Best Practices

Environment Management

// Use environment-specific configurations
const config = {
  environment: process.env.NODE_ENV === 'production' ? 'user' : 'dev',
  // Use appKey for new applications (recommended)
  appKey: process.env.OPTILOGIC_APP_KEY!,
  // Or use apiKey for legacy applications
  // apiKey: process.env.OPTILOGIC_API_KEY!,
  version: 0
};

const api = new OptiJs(config);

Authentication Best Practices

// Recommended: Use App Key for new applications
const api = new OptiJs({
  environment: 'user',
  appKey: process.env.OPTILOGIC_APP_KEY!
});

// Legacy: Use API Key for existing applications
const legacyApi = new OptiJs({
  environment: 'user',
  apiKey: process.env.OPTILOGIC_API_KEY!
});

// Never hardcode credentials in your code
// Always use environment variables

Error Handling

// Always handle errors appropriately
async function runOptimization() {
  try {
    const job = await api.createWorkspaceJob(/* ... */);
    return job;
  } catch (error) {
    console.error('Failed to create job:', error);
    throw error; // Re-throw or handle as needed
  }
}

Resource Management

// Use appropriate resource configurations
const resourceConfig = modelSize === 'small' ? 'mini' : 
                      modelSize === 'medium' ? 'M' : 'XL';

await api.createWorkspaceJob(workspace, path, file, undefined, undefined, resourceConfig);

Cleanup

// Always clean up test resources
afterAll(async () => {
  if (tempResourceId) {
    await api.deleteDatabase(tempResourceId);
  }
});

Contributing

  1. Fork the repository
  2. Create a feature branch
  3. Make your changes
  4. Add tests for new functionality
  5. Run the test suite
  6. Submit a pull request

License

MIT


For more information about the Optilogic platform, visit optilogic.app.