farm-orchestrator
v1.1.14
Published
Hub package with PostgreSQL and Sequelize support
Readme
@device-farm/hub
Hub package with PostgreSQL database support using Sequelize ORM.
Features
- PostgreSQL database connection management
- Sequelize ORM integration
- Type-safe database configuration
- Connection pooling
- Model initialization support
Installation
Dependencies are managed at the root level. Run:
npm installUsage
Basic Setup
import { Database, initializeModels } from '@device-farm/hub';
// Create database instance
const db = new Database({
host: 'localhost',
port: 5432,
database: 'device_farm',
username: 'postgres',
password: 'password',
pool: {
max: 5,
min: 0,
acquire: 30000,
idle: 10000,
},
logging: console.log, // Optional: log SQL queries
});
// Initialize models
initializeModels(db.getSequelize());
// Connect to database
await db.connect();
// Sync models (development only - use migrations in production)
await db.sync({ alter: true });
// ... use your database connection
// Disconnect when done
await db.disconnect();Creating Models
Create models in src/models/ directory:
import { Model, DataTypes, Sequelize } from 'sequelize';
export class User extends Model {
public id!: number;
public name!: string;
public email!: string;
public readonly createdAt!: Date;
public readonly updatedAt!: Date;
}
export const initUser = (sequelize: Sequelize): typeof User => {
User.init(
{
id: {
type: DataTypes.INTEGER,
autoIncrement: true,
primaryKey: true,
},
name: {
type: DataTypes.STRING,
allowNull: false,
},
email: {
type: DataTypes.STRING,
allowNull: false,
unique: true,
},
},
{
sequelize,
modelName: 'User',
tableName: 'users',
}
);
return User;
};Then register it in src/models/index.ts:
import { initUser } from './user';
export const initializeModels = (sequelize: Sequelize): void => {
initUser(sequelize);
// Add more models here
};Configuration
Environment Variables
It's recommended to use environment variables for database configuration:
DB_HOST=localhost
DB_PORT=5432
DB_NAME=device_farm
DB_USER=postgres
DB_PASSWORD=your_password
DB_POOL_MAX=5
DB_POOL_MIN=0Then use them in your code:
const db = new Database({
host: process.env.DB_HOST || 'localhost',
port: parseInt(process.env.DB_PORT || '5432', 10),
database: process.env.DB_NAME || 'device_farm',
username: process.env.DB_USER || 'postgres',
password: process.env.DB_PASSWORD || '',
pool: {
max: parseInt(process.env.DB_POOL_MAX || '5', 10),
min: parseInt(process.env.DB_POOL_MIN || '0', 10),
},
});WebDriver Session Path Configuration
The WebDriver session endpoint path is configurable. The webdriverSessionPath specifies the base path, and the router automatically appends /session to it. For example, if webdriverSessionPath is /wd/hub, the final endpoint will be /wd/hub/session.
You can set it via:
Configuration File (
hub.config.json):{ "webdriverSessionPath": "/wd/hub" }CLI Arguments:
npm run start -- --webdriver-session-path /custom/path # or short form: npm run start -- -w /custom/pathEnvironment Variable:
WEBDRIVER_SESSION_PATH=/wd/hubCustom Config File:
npm run start -- --config /path/to/hub.config.json # or short form: npm run start -- -c /path/to/hub.config.json
Priority Order: Environment variables > CLI arguments > Config file > Default (/wd/hub)
Note: The router automatically appends /session to the configured path, so the default endpoint will be available at POST /wd/hub/session.
Prepare WDA Command (iOS)
The hub includes a command to build and sign WebDriverAgent (WDA) for iOS real device testing. This command:
- Finds or builds WebDriverAgent from Appium
- Signs it with a mobile provisioning profile
- Creates a signed IPA file ready for deployment
Usage:
# Interactive mode (will prompt for provisioning profile)
npm run start -- prepare-wda
# With specific provisioning file
npm run start -- prepare-wda --mobile-provisioning-file /path/to/profile.mobileprovision
# With custom WDA project path
npm run start -- prepare-wda --wda-project-path /path/to/WebDriverAgent
# Specify platform (ios, tvos, or both)
npm run start -- prepare-wda --platform bothOptions:
| Option | Short | Description |
| ---------------------------- | ----- | -------------------------------------------------------- |
| --mobile-provisioning-file | -m | Path to the mobile provisioning file for signing |
| --wda-project-path | -p | Path to WebDriverAgent Xcode project |
| --platform | | Platform type: ios, tvos, or both (default: ios) |
Requirements:
- macOS with Xcode installed
- Valid Apple Developer provisioning profile
- Appium with XCUITest driver installed (for automatic WDA discovery)
Node Monitor Configuration
The hub includes a node monitor service that tracks node liveness by checking for heartbeat signals. You can configure it using environment variables:
# Node monitor check interval (default: 60000ms = 60 seconds)
NODE_MONITOR_INTERVAL=60000
# Timeout before marking a node as offline (default: 120000ms = 2 minutes)
NODE_TIMEOUT_MS=120000The node monitor service is configured as follows:
export const nodeMonitorService = new NodeMonitorService({
checkInterval: parseInt(process.env.NODE_MONITOR_INTERVAL || '60000', 10),
timeoutMs: parseInt(process.env.NODE_TIMEOUT_MS || '120000', 10),
});Configuration Details:
NODE_MONITOR_INTERVAL: How often the monitor checks for offline nodes (in milliseconds). Default is 60 seconds.NODE_TIMEOUT_MS: How long a node can go without sending a heartbeat before being marked offline (in milliseconds). Default is 2 minutes.
The monitor waits for the first interval before checking, giving nodes a grace period after hub restart to register and start sending heartbeats.
Development
# Build the package
npm run build
# Watch mode
npm run build:watch
# Type check
npm run typecheck
# Lint
npm run lintDependencies
- sequelize: ORM for Node.js
- pg: PostgreSQL client for Node.js
- pg-hstore: Serialization/deserialization of hstore data type
