ObjectOS LogoObjectOS

SDK Reference

This document provides a complete reference for the ObjectOS Kernel SDK. Use the Kernel to programmatically interact with your data and business logic.

Installation

npm install @objectos/kernel @objectql/driver-sql

Basic Setup

import { ObjectOS } from '@objectos/kernel';
import { PostgresDriver } from '@objectql/driver-sql';

// Create kernel instance
const kernel = new ObjectOS();

// Configure database driver
const driver = new PostgresDriver({
  client: 'pg',
  connection: {
    host: 'localhost',
    port: 5432,
    user: 'postgres',
    password: 'password',
    database: 'myapp'
  }
});

// Connect driver to kernel
kernel.useDriver(driver);
await driver.connect();

// Load object definitions
await kernel.load(objectConfig);

Core Methods

kernel.load(config)

Load an object definition into the registry.

Parameters:

  • config: Object configuration (ObjectConfig)

Returns: Promise<void>

Example:

await kernel.load({
  name: 'contacts',
  label: 'Contact',
  fields: {
    first_name: { type: 'text', required: true },
    last_name: { type: 'text', required: true },
    email: { type: 'email', unique: true }
  }
});

kernel.find(objectName, options, user?)

Query multiple records.

Parameters:

  • objectName: String - Object API name
  • options: FindOptions - Query options
  • user?: User - Current user context (for permissions)

Returns: Promise<Record\<string, any\>[]>

Example:

const contacts = await kernel.find('contacts', {
  filters: {
    status: 'active',
    age: { $gte: 18 }
  },
  fields: ['first_name', 'last_name', 'email'],
  sort: [{ field: 'last_name', order: 'asc' }],
  limit: 50,
  skip: 0
}, currentUser);

FindOptions Interface:

interface FindOptions {
  filters?: FilterExpression;
  fields?: string[];
  sort?: SortExpression[];
  limit?: number;
  skip?: number;
  include?: string[];
}

kernel.findOne(objectName, id, options?, user?)

Get a single record by ID.

Parameters:

  • objectName: String - Object API name
  • id: String - Record ID
  • options?: FindOptions - Optional query options
  • user?: User - Current user context

Returns: Promise<Record\<string, any\>>

Example:

const contact = await kernel.findOne('contacts', 'contact_123', {
  fields: ['first_name', 'last_name', 'email'],
  include: ['account']
}, currentUser);

kernel.insert(objectName, data, user?)

Create a new record.

Parameters:

  • objectName: String - Object API name
  • data: Object - Record data
  • user?: User - Current user context

Returns: Promise<Record\<string, any\>>

Example:

const newContact = await kernel.insert('contacts', {
  first_name: 'John',
  last_name: 'Doe',
  email: 'john@example.com',
  phone: '+1234567890'
}, currentUser);

console.log(newContact.id);  // Generated ID

kernel.update(objectName, id, data, user?)

Update an existing record.

Parameters:

  • objectName: String - Object API name
  • id: String - Record ID
  • data: Object - Fields to update
  • user?: User - Current user context

Returns: Promise<Record\<string, any\>>

Example:

const updated = await kernel.update('contacts', 'contact_123', {
  phone: '+1987654321',
  status: 'inactive'
}, currentUser);

kernel.delete(objectName, id, user?)

Delete a record.

Parameters:

  • objectName: String - Object API name
  • id: String - Record ID
  • user?: User - Current user context

Returns: Promise<void>

Example:

await kernel.delete('contacts', 'contact_123', currentUser);

kernel.count(objectName, filters?, user?)

Count records matching filters.

Parameters:

  • objectName: String - Object API name
  • filters?: FilterExpression - Filter criteria
  • user?: User - Current user context

Returns: Promise<number>

Example:

const activeCount = await kernel.count('contacts', {
  status: 'active'
}, currentUser);

console.log(`${activeCount} active contacts`);

Hook Methods

kernel.on(event, handler, options?)

Register a lifecycle hook.

Parameters:

  • event: String - Hook event name
  • handler: Function - Hook callback
  • options?: HookOptions - Hook configuration

Returns: void

Events:

  • beforeFind, afterFind
  • beforeInsert, afterInsert
  • beforeUpdate, afterUpdate
  • beforeDelete, afterDelete

Example:

kernel.on('beforeInsert', async (ctx) => {
  ctx.data.created_at = new Date();
  ctx.data.created_by = ctx.user.id;
});

kernel.on('afterInsert:contacts', async (ctx) => {
  await sendWelcomeEmail(ctx.result.email);
});

Hook Context:

interface HookContext {
  objectName: string;
  user: User;
  data?: Record\<string, any\>;
  id?: string;
  filters?: any;
  result?: any;
  oldValues?: Record\<string, any\>;
}

kernel.off(event, handler?)

Unregister a hook.

Parameters:

  • event: String - Hook event name
  • handler?: Function - Specific handler to remove (optional)

Returns: void

Example:

// Remove all handlers for event
kernel.off('beforeInsert');

// Remove specific handler
kernel.off('beforeInsert', myHandler);

Action Methods

kernel.registerAction(name, handler, options?)

Register a custom action.

Parameters:

  • name: String - Action name (e.g., 'contacts.sendEmail')
  • handler: Function - Action callback
  • options?: ActionOptions - Action configuration

Returns: void

Example:

kernel.registerAction('contacts.sendEmail', async (ctx) => {
  const { id, subject, body } = ctx.params;
  
  const contact = await ctx.kernel.findOne('contacts', id);
  
  await sendEmail({
    to: contact.email,
    subject: subject,
    body: body
  });
  
  return {
    success: true,
    message: 'Email sent'
  };
});

kernel.executeAction(name, params, user?)

Execute a registered action.

Parameters:

  • name: String - Action name
  • params: Object - Action parameters
  • user?: User - Current user context

Returns: Promise<any>

Example:

const result = await kernel.executeAction('contacts.sendEmail', {
  id: 'contact_123',
  subject: 'Hello',
  body: 'Welcome!'
}, currentUser);

console.log(result.message);

Registry Methods

kernel.getObjects()

Get list of all registered objects.

Returns: string[]

Example:

const objects = kernel.getObjects();
console.log(objects);  // ['contacts', 'accounts', 'opportunities']

kernel.getObjectConfig(objectName)

Get configuration for a specific object.

Parameters:

  • objectName: String - Object API name

Returns: ObjectConfig

Example:

const config = kernel.getObjectConfig('contacts');
console.log(config.label);        // 'Contact'
console.log(config.fields.email); // { type: 'email', unique: true, ... }

kernel.hasObject(objectName)

Check if an object is registered.

Parameters:

  • objectName: String - Object API name

Returns: boolean

Example:

if (kernel.hasObject('contacts')) {
  console.log('Contacts object is available');
}

Driver Methods

kernel.useDriver(driver)

Set the database driver.

Parameters:

  • driver: ObjectQLDriver - Driver instance

Returns: void

Example:

import { PostgresDriver } from '@objectql/driver-sql';

const driver = new PostgresDriver({ /* config */ });
kernel.useDriver(driver);
await driver.connect();

kernel.getDriver()

Get the current database driver.

Returns: ObjectQLDriver | null

Example:

const driver = kernel.getDriver();
if (driver) {
  console.log('Driver connected');
}

Transaction Methods

kernel.transaction(callback)

Execute operations in a database transaction.

Parameters:

  • callback: Function - Callback with transaction context

Returns: Promise<any>

Example:

await kernel.transaction(async (trx) => {
  // Create account
  const account = await trx.insert('accounts', {
    name: 'Acme Corp'
  });
  
  // Create contact
  const contact = await trx.insert('contacts', {
    first_name: 'John',
    last_name: 'Doe',
    account: account.id
  });
  
  // If any operation fails, all changes are rolled back
  return { account, contact };
});

Validation Methods

kernel.validate(objectName, data)

Validate data against object schema.

Parameters:

  • objectName: String - Object API name
  • data: Object - Data to validate

Returns: ValidationResult

Example:

const result = kernel.validate('contacts', {
  first_name: 'John',
  // Missing required 'last_name'
  email: 'invalid-email'  // Invalid email format
});

if (!result.valid) {
  console.log(result.errors);
  // [
  //   { field: 'last_name', message: 'Field is required' },
  //   { field: 'email', message: 'Invalid email format' }
  // ]
}

Permission Methods

kernel.checkPermission(objectName, action, user)

Check if user has permission for an action.

Parameters:

  • objectName: String - Object API name
  • action: String - Action ('read', 'create', 'update', 'delete')
  • user: User - User context

Returns: boolean

Example:

const canCreate = kernel.checkPermission('contacts', 'create', currentUser);

if (!canCreate) {
  throw new Error('Permission denied');
}

Type Definitions

User

interface User {
  id: string;
  email: string;
  name?: string;
  roles: string[];
  [key: string]: any;
}

FilterExpression

type FilterExpression = {
  [field: string]: any | {
    $eq?: any;
    $ne?: any;
    $gt?: any;
    $gte?: any;
    $lt?: any;
    $lte?: any;
    $in?: any[];
    $nin?: any[];
    $like?: string;
    $ilike?: string;
    $null?: boolean;
    $between?: [any, any];
  };
  $and?: FilterExpression[];
  $or?: FilterExpression[];
  $not?: FilterExpression;
};

SortExpression

interface SortExpression {
  field: string;
  order: 'asc' | 'desc';
}

ObjectConfig

interface ObjectConfig {
  name: string;
  label?: string;
  icon?: string;
  description?: string;
  enable_api?: boolean;
  enable_audit?: boolean;
  fields: {
    [fieldName: string]: FieldConfig;
  };
  permission_set?: PermissionSet;
}

FieldConfig

interface FieldConfig {
  type: FieldType;
  label?: string;
  description?: string;
  required?: boolean;
  unique?: boolean;
  default?: any;
  readonly?: boolean;
  hidden?: boolean;
  // Type-specific attributes
  [key: string]: any;
}

type FieldType =
  | 'text' | 'textarea' | 'email' | 'url' | 'phone'
  | 'number' | 'currency' | 'percent'
  | 'date' | 'datetime' | 'time'
  | 'boolean' | 'select' | 'multiselect'
  | 'lookup' | 'master_detail'
  | 'autonumber' | 'formula' | 'rollup_summary';

Complete Example

import { ObjectOS } from '@objectos/kernel';
import { PostgresDriver } from '@objectql/driver-sql';

// Initialize
const kernel = new ObjectOS();
const driver = new PostgresDriver({
  connection: process.env.DATABASE_URL
});

kernel.useDriver(driver);
await driver.connect();

// Load objects
await kernel.load({
  name: 'contacts',
  label: 'Contact',
  fields: {
    first_name: { type: 'text', required: true },
    last_name: { type: 'text', required: true },
    email: { type: 'email', unique: true }
  }
});

// Register hooks
kernel.on('beforeInsert', async (ctx) => {
  ctx.data.created_at = new Date();
  ctx.data.created_by = ctx.user.id;
});

// Register actions
kernel.registerAction('contacts.sendEmail', async (ctx) => {
  const contact = await ctx.kernel.findOne('contacts', ctx.params.id);
  await sendEmail(contact.email, ctx.params.subject, ctx.params.body);
  return { success: true };
});

// Use the kernel
const currentUser = { id: 'user_123', roles: ['sales'] };

// Create
const contact = await kernel.insert('contacts', {
  first_name: 'John',
  last_name: 'Doe',
  email: 'john@example.com'
}, currentUser);

// Query
const contacts = await kernel.find('contacts', {
  filters: { status: 'active' },
  sort: [{ field: 'last_name', order: 'asc' }],
  limit: 50
}, currentUser);

// Update
await kernel.update('contacts', contact.id, {
  phone: '+1234567890'
}, currentUser);

// Execute action
await kernel.executeAction('contacts.sendEmail', {
  id: contact.id,
  subject: 'Welcome',
  body: 'Hello!'
}, currentUser);

// Delete
await kernel.delete('contacts', contact.id, currentUser);

Error Handling

The SDK throws specific error types:

try {
  await kernel.insert('contacts', data);
} catch (error) {
  if (error instanceof ValidationError) {
    console.log('Validation failed:', error.errors);
  } else if (error instanceof PermissionDeniedError) {
    console.log('Permission denied');
  } else if (error instanceof NotFoundError) {
    console.log('Record not found');
  } else {
    console.log('Unexpected error:', error);
  }
}

On this page