@jedify/sdk
v0.1.0
Published
TypeScript SDK for Jedify semantic functions
Downloads
88
Maintainers
Readme
@jedify/sdk
TypeScript SDK for calling Jedify semantic functions (cloud functions).
Installation
npm install @jedify/sdkQuick Start
Backend Usage (Node.js)
import { Jedify } from '@jedify/sdk';
const jedify = new Jedify({
apiKey: process.env.JEDIFY_API_KEY,
});
// List available functions
const { functions } = await jedify.listFunctions();
console.log(`Found ${functions.length} functions`);
// Call a function
const result = await jedify.call('_REVENUE_BY_PRODUCT', {
region: 'North America',
start_date: '2025-01-01',
end_date: '2025-03-31',
});
if (result.success) {
console.log(`Got ${result.row_count} rows in ${result.execution_time_ms}ms`);
result.data.forEach(row => console.log(row));
} else {
console.error('Error:', result.error);
}Frontend Usage (via Proxy)
IMPORTANT: Never expose your API key in browser code!
Use a backend proxy instead:
// Frontend code
import { Jedify } from '@jedify/sdk';
const jedify = new Jedify({
baseUrl: '/api/jedify', // Your backend proxy
});
const result = await jedify.call('_REVENUE_BY_PRODUCT', {});Backend proxy example (Express.js):
import express from 'express';
import { Jedify } from '@jedify/sdk';
const app = express();
const jedify = new Jedify({ apiKey: process.env.JEDIFY_API_KEY });
app.use(express.json());
// Proxy endpoint
app.post('/api/jedify/functions/:name/call', async (req, res) => {
try {
const result = await jedify.call(req.params.name, req.body.parameters);
res.json(result);
} catch (error) {
res.status(500).json({ error: error.message });
}
});
app.listen(3000);API Reference
Constructor
const jedify = new Jedify(config: JedifyConfig);Config options:
apiKey(string, optional): Jedify API key (Descope). Required for backend usage. Never use in browser!baseUrl(string, optional): Base URL for API requests. Use for frontend proxy. Default:https://api.jedify.comtimeout(number, optional): Request timeout in milliseconds. Default:30000(30 seconds)maxRetries(number, optional): Max retry attempts for 5xx errors. Default:3headers(object, optional): Custom headers for every requestdebug(boolean, optional): Enable debug logging. Default:false
Methods
listFunctions(filters?)
List available semantic functions.
const result = await jedify.listFunctions({
search: 'revenue', // Optional: search in name/description
category: 'sales', // Optional: filter by category
limit: 100, // Optional: results per page
offset: 0, // Optional: pagination offset
});
// Returns: ListFunctionsResult
{
functions: FunctionSchema[], // Array of functions with full schemas
total: number, // Total matching functions
limit: number,
offset: number
}getSchema(functionName)
Get detailed schema for a specific function.
const schema = await jedify.getSchema('_REVENUE_BY_PRODUCT');
// Returns: FunctionSchema
{
function_id: string,
name: string,
description: string,
parameters: ParameterDefinition[], // Input parameters
output_schema: OutputColumn[], // Output columns
example_usage: {
typescript: string, // TS example code
python: string // Python example code
}
}call(functionName, parameters?, options?)
Execute a semantic function.
const result = await jedify.call(
'_REVENUE_BY_PRODUCT',
{
region: 'Europe',
start_date: '2025-01-01',
},
{
timeout: 60000, // Override default timeout
fetchAll: false, // Auto-fetch all pages?
page: 1, // Manual pagination: page number
limit: 200, // Manual pagination: rows per page
signal: abortSignal // AbortSignal for cancellation
}
);
// Returns: CallResult
{
success: boolean, // Whether execution succeeded
data?: any[], // Result rows (if success=true)
row_count?: number, // Number of rows returned
total_rows?: number, // Total rows in dataset
is_truncated?: boolean, // Whether data was truncated
truncation_reason?: string, // Why data was truncated
sql_executed: string, // SQL query executed
execution_time_ms?: number, // Query execution time
pagination?: { // Pagination metadata
page: number,
limit: number,
total_pages: number,
has_more: boolean
},
error?: string, // Error message (if success=false)
error_code?: ErrorCode // Error code for handling
}Features
Automatic Pagination
Fetch all pages automatically for large datasets:
// Without fetchAll - returns up to 200 rows
const partial = await jedify.call('_LARGE_DATASET', {});
console.log(`Got ${partial.row_count} of ${partial.total_rows} rows`);
// With fetchAll - fetches all pages automatically
const complete = await jedify.call('_LARGE_DATASET', {}, { fetchAll: true });
console.log(`Got all ${complete.row_count} rows`);Manual Pagination
Control pagination yourself:
// Page 1
const page1 = await jedify.call('_FUNCTION', {}, { page: 1, limit: 100 });
// Page 2
const page2 = await jedify.call('_FUNCTION', {}, { page: 2, limit: 100 });Error Handling
import {
JedifyError,
JedifyValidationError,
JedifyHttpError,
JedifyExecutionError,
JedifyTimeoutError,
JedifyNetworkError,
ErrorCode,
} from '@jedify/sdk';
try {
const result = await jedify.call('_FUNCTION', { param: 'value' });
if (!result.success) {
// Execution failed (SQL error, etc.)
console.error('Execution error:', result.error);
console.error('Error code:', result.error_code);
console.error('SQL:', result.sql_executed);
}
} catch (error) {
if (error instanceof JedifyValidationError) {
// Parameter validation failed
console.error('Validation errors:', error.errors);
} else if (error instanceof JedifyHttpError) {
// HTTP error (404, 401, etc.)
console.error('HTTP error:', error.status, error.message);
} else if (error instanceof JedifyTimeoutError) {
// Request timed out
console.error('Timeout:', error.message);
} else if (error instanceof JedifyNetworkError) {
// Network failure
console.error('Network error:', error.originalError);
}
}Request Cancellation
Cancel requests with AbortController:
const controller = new AbortController();
// Start request
const promise = jedify.call('_LONG_QUERY', {}, {
signal: controller.signal
});
// Cancel after 5 seconds
setTimeout(() => controller.abort(), 5000);
try {
await promise;
} catch (error) {
console.log('Request cancelled');
}Debug Mode
Enable debug logging:
const jedify = new Jedify({
apiKey: process.env.JEDIFY_API_KEY,
debug: true, // Logs all requests and responses
});
// Output:
// [Jedify] POST https://api.jedify.com/api/functions/_REVENUE/call
// [Jedify] Body: { parameters: { ... } }
// [Jedify] Response (200): { success: true, ... }TypeScript Support
Full TypeScript support with type inference:
interface RevenueRow {
product: string;
revenue: number;
region: string;
}
const result = await jedify.call<RevenueRow>('_REVENUE_BY_PRODUCT', {});
if (result.success && result.data) {
result.data.forEach((row: RevenueRow) => {
console.log(`${row.product}: $${row.revenue}`);
});
}Security
- Never expose API keys in browser code
- Always use a backend proxy for frontend applications
- API keys should be stored in environment variables
- Use HTTPS in production
Examples
See examples/ directory for complete examples:
backend-usage.ts- Backend usage with API keyfrontend-usage.ts- Frontend usage via proxyproxy-express.ts- Express.js proxy implementation
Requirements
- Node.js >= 18.0.0
- TypeScript >= 5.0 (for type definitions)
License
MIT
