@nodius/server
v1.0.1
Published
[](https://www.npmjs.com/package/@nodius/server) [](https://www.typescriptlang.org/) [
- Operating System: Windows, macOS, or Linux
Quick Start
Minimal Configuration
# Start ArangoDB (if not already running)
arangod
# From packages/server folder
npm run devThe server starts on:
- HTTP/HTTPS:
https://localhost:8426 - WebSocket:
wss://localhost:10426 - Cluster Manager: Port
9426(internal)
Custom Configuration
# With CLI arguments
npm run dev -- port=3000 host=0.0.0.0 https=true
# With custom certificates
npm run dev -- https=true cert=./path/to/cert.pem key=./path/to/key.pem
# With custom database
npm run dev -- arangodb=http://db-server:8529 arangodb_name=my_nodius_db arangodb_user=admin arangodb_pass=secretVerify Server is Running
# Check server health
curl https://localhost:8426/api/health
# Should return:
# {"status":"ok","timestamp":1234567890}Architecture
Nodius server is built on several key components:
┌─────────────────────────────────────────────────────┐
│ Nodius Server │
├─────────────────────────────────────────────────────┤
│ │
│ ┌──────────────────┐ ┌──────────────────┐ │
│ │ HttpServer │ │ WebSocket │ │
│ │ (REST API) │ │ Manager │ │
│ │ │ │ (Real-time) │ │
│ └────────┬─────────┘ └─────────┬────────┘ │
│ │ │ │
│ │ │ │
│ ┌────────▼──────────────────────────▼────────┐ │
│ │ Request Handlers │ │
│ │ ┌──────┐ ┌──────┐ ┌──────┐ ┌──────┐ │ │
│ │ │Workflow│ │Category│ │Sync │ │Auth│ │ │
│ │ └──────┘ └──────┘ └──────┘ └──────┘ │ │
│ └────────────────────┬────────────────────── │ │
│ │ │
│ ┌────────────────────▼──────────────────────┐ │
│ │ Auth Manager │ │
│ │ - JWT Tokens │ │
│ │ - Pluggable Providers │ │
│ │ - bcrypt Hashing │ │
│ └────────────────────┬──────────────────────┘ │
│ │ │
│ ┌────────────────────▼──────────────────────┐ │
│ │ ArangoDB Connection │ │
│ │ - Graph database │ │
│ │ - Collections: nodes, edges, workflows │ │
│ └────────────────────┬──────────────────────┘ │
│ │ │
│ ┌────────────────────▼──────────────────────┐ │
│ │ Cluster Manager (ZeroMQ) │ │
│ │ - Pub/Sub for broadcasts │ │
│ │ - Router/Dealer for coordination │ │
│ └───────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────┘Data Flow
- HTTP Client → HttpServer → Request Handler → ArangoDB
- WebSocket Client → WebSocket Manager → Validation → Broadcast to all clients
- Sync Instructions → Validation → Application → Save (auto-save)
- Cluster Events → ZeroMQ Pub/Sub → All cluster servers
Main Components
HttpServer
Custom HTTP server with Express-like support for routing and middlewares.
Features
- Express-like API: Routes with
get(),post(),put(),delete() - Middlewares: CORS, logging, rate limiting, error handling
- Body Parsing: Automatic JSON and text parsing
- File Upload: Multipart/form-data support with Sharp for images
- Static Files: Serve static files
- HTTPS: SSL support with automatic self-signed certificate generation
- Route Parameters: Parameter extraction (
/api/workflow/:id) - Query Strings: Automatic parsing
Usage
import { HttpServer, cors, logger } from '@nodius/server';
const app = new HttpServer();
// Middlewares
app.use(logger());
app.use(cors());
// Routes
app.get('/api/hello', (req, res) => {
res.json({ message: 'Hello World' });
});
app.post('/api/data', async (req, res) => {
const data = req.body;
// Process data
res.json({ success: true, data });
});
// Route parameters
app.get('/api/workflow/:id', (req, res) => {
const workflowId = req.params?.id;
res.json({ workflowId });
});
// Start server
app.listen({
port: 8426,
host: '0.0.0.0',
https: {
key: certKey,
cert: certFile
}
});Available Middlewares
// CORS
app.use(cors({
origin: '*',
methods: 'GET,POST,PUT,DELETE,OPTIONS',
allowedHeaders: 'Content-Type,Authorization'
}));
// Logger
app.use(logger());
// Rate limiting
app.use(rateLimit({
windowMs: 60000, // 1 minute
max: 100 // 100 requests per window
}));
// Static files
app.use(staticFiles('./public'));
// Auth middleware (provided by AuthManager)
app.use(authManager.authMiddleware());WebSocket Manager
WebSocket connection manager for real-time collaboration.
Features
- Real-time Synchronization: Broadcast instructions to all connected clients
- Sessions per Workflow: Manage user sessions per workflow
- Auto-Save: Automatic save every 30 seconds with diff computation
- Instruction Validation: Consistency checking before application
- Reconnection: Automatic reconnection support
- Broadcasting: Selective broadcast per workflow
Architecture
import { WebSocketManager } from '@nodius/server';
import { Database } from 'arangojs';
const db = new Database(/* config */);
const wsManager = new WebSocketManager(db, httpServer);WebSocket Protocol
Connection Message
{
"type": "connect",
"workflowKey": "workflow_123",
"token": "jwt_token_here"
}Instructions Message
{
"type": "instructions",
"workflowKey": "workflow_123",
"instructions": [
{
"o": 1,
"p": ["nodes", "node_1", "posX"],
"v": 100
}
],
"clientId": "client_abc",
"timestamp": 1234567890
}Broadcast Message (server → clients)
{
"type": "update",
"workflowKey": "workflow_123",
"instructions": [...],
"sourceClientId": "client_abc"
}Auto-Save Operation
The WebSocket Manager:
- Receives instructions from client
- Validates and applies instructions in memory
- Broadcasts to other connected clients
- Every 30 seconds:
- Compares in-memory state with ArangoDB
- Calculates diff (missing instructions)
- Saves only changes
// Auto-save configuration
const AUTO_SAVE_INTERVAL = 30000; // 30 seconds
// System automatically handles:
// - Change detection
// - Diff calculation
// - Batch saving
// - Error handlingCluster Manager
Distributed cluster manager using ZeroMQ for server coordination.
Features
- Pub/Sub Pattern: Event broadcasting between servers
- Router/Dealer Pattern: Point-to-point communication
- Discovery: Automatic peer discovery
- Health Checks: Node health monitoring
- Message Routing: Intelligent message routing
Architecture
Server 1 (Port 9426) Server 2 (Port 9427)
│ │
│ ┌─────────────────────┐ │
└──┤ ZeroMQ Pub/Sub ├────┘
└─────────────────────┘
│ │
▼ ▼
Broadcast SubscribeUsage
import { ClusterManager } from '@nodius/server';
const clusterManager = new ClusterManager({
pubPort: 9426,
subPort: 9427,
routerPort: 9428,
dealerPort: 9429
});
// Publish message
clusterManager.publish('workflow.update', {
workflowKey: 'workflow_123',
data: { ... }
});
// Subscribe to topic
clusterManager.subscribe('workflow.update', (message) => {
console.log('Received update:', message);
});Auth Manager
JWT authentication system with pluggable providers.
Features
- JWT Tokens: Token generation and validation
- bcrypt Hashing: Secure password hashing
- Pluggable Providers: Customizable provider system
- Default Provider: Default provider with database users
- Middleware: Automatic route protection
- Refresh Tokens: Token refresh support
Usage
Initialization
import { AuthManager } from '@nodius/server';
import { Database } from 'arangojs';
const db = new Database(/* config */);
const authManager = AuthManager.getInstance();
await authManager.initialize(db, 'your-jwt-secret');Create Admin
# Via CLI
npm run create-admin
# Or programmatically
import { createAdmin } from '@nodius/server';
await createAdmin(db, 'admin', 'secure_password');Protect Routes
// All /api/* routes are automatically protected
// except /api/auth/*
app.use(authManager.authMiddleware());
// Protected route
app.get('/api/protected', (req, res) => {
const userId = req.user?.id; // Injected by middleware
res.json({ userId });
});Custom Auth Provider
import { AuthProvider, AuthManager } from '@nodius/server';
class MyCustomAuthProvider implements AuthProvider {
async authenticate(username: string, password: string): Promise<{ id: string; username: string } | null> {
// Your authentication logic
// Ex: LDAP, OAuth, etc.
return { id: 'user_123', username };
}
async getUserById(id: string): Promise<{ id: string; username: string } | null> {
// Get user by ID
return { id, username: 'user' };
}
}
// Use custom provider
const authManager = AuthManager.getInstance();
authManager.setProvider(new MyCustomAuthProvider());API Endpoints
Authentication
POST /api/auth/login
Authenticate a user and obtain a JWT token.
Request:
{
"username": "admin",
"password": "secure_password"
}Response:
{
"token": "eyJhbGciOiJIUzI1NiIs...",
"user": {
"id": "user_123",
"username": "admin"
}
}POST /api/auth/refresh
Refresh an expired token.
Request:
{
"token": "eyJhbGciOiJIUzI1NiIs..."
}Response:
{
"token": "eyJhbGciOiJIUzI1NiIs..."
}Workflows
GET /api/workflow
List all workflows.
Query params:
category(optional): Filter by categorylimit(optional): Number of resultsoffset(optional): Pagination
Response:
{
"workflows": [
{
"_key": "workflow_123",
"name": "My Workflow",
"category": "automation",
"createdAt": 1234567890,
"updatedAt": 1234567890
}
],
"total": 1
}GET /api/workflow/:key
Get a specific workflow with all its nodes and edges.
Response:
{
"workflow": {
"_key": "workflow_123",
"name": "My Workflow",
"nodes": [...],
"edges": [...]
}
}POST /api/workflow
Create a new workflow.
Request:
{
"name": "New Workflow",
"category": "automation"
}Response:
{
"workflowKey": "workflow_456"
}PUT /api/workflow/:key
Update a workflow.
Request:
{
"name": "Updated Name",
"category": "new_category"
}DELETE /api/workflow/:key
Delete a workflow.
Categories
GET /api/category
List all categories.
POST /api/category
Create a new category.
Request:
{
"name": "automation",
"description": "Automation workflows"
}Node Configurations
GET /api/nodeconfig
List all node configurations.
POST /api/nodeconfig
Create a new node configuration.
Request:
{
"type": "textNode",
"name": "Text Node",
"process": "await next('0', incoming?.data);",
"version": 1
}Data Types
GET /api/datatype
List all data types.
POST /api/datatype
Create a new data type.
Images
POST /api/image/upload
Upload an image.
Request: multipart/form-data
file: Image filename(optional): Image name
Response:
{
"imageKey": "image_123",
"url": "/api/image/image_123"
}GET /api/image/:key
Get an image (public endpoint, no auth required).
GET /api/image
List all images.
DELETE /api/image/:key
Delete an image.
PUT /api/image/:key/rename
Rename an image.
Request:
{
"name": "new_name.png"
}History
GET /api/history/:workflowKey
Get modification history for a workflow.
Response:
{
"history": [
{
"timestamp": 1234567890,
"instructions": [...],
"userId": "user_123"
}
]
}Configuration
Environment Variables
The server can be configured via CLI arguments or environment variables:
| CLI Argument | Env Variable | Default | Description |
|-------------|--------------|---------|-------------|
| port | PORT | 8426 | HTTP/HTTPS port |
| host | HOST | localhost | Server host |
| https | HTTPS | false | Enable HTTPS |
| cert | SSL_CERT | - | SSL certificate path |
| key | SSL_KEY | - | SSL key path |
| arangodb | ARANGO_URL | http://127.0.0.1:8529 | ArangoDB URL |
| arangodb_user | ARANGO_USER | root | ArangoDB user |
| arangodb_pass | ARANGO_PASS | azerty | ArangoDB password |
| arangodb_name | ARANGO_DB | nodius | Database name |
| jwt_secret | JWT_SECRET | (generated) | Secret for JWT tokens |
Startup Example
# Local development
node dist/server.js
# Production with HTTPS and custom DB
node dist/server.js \
port=443 \
host=0.0.0.0 \
https=true \
cert=/etc/ssl/cert.pem \
key=/etc/ssl/key.pem \
arangodb=https://db.example.com:8529 \
arangodb_user=nodius \
arangodb_pass=secure_pass \
jwt_secret=my_super_secret_keyCLI Tools
The server package includes several CLI tools:
Create Admin
Create an administrator user:
npm run create-admin
# Or with tsx
npx tsx src/cli/createAdmin.tsExport Data
Export all workflows and configurations:
npx tsx src/cli/export.ts output.jsonImport Data
Import workflows from a file:
npx tsx src/cli/import.ts input.jsonDevelopment
Package Structure
packages/server/
├── src/
│ ├── auth/ # Authentication system
│ │ ├── AuthManager.ts # Main manager
│ │ ├── AuthProvider.ts # Provider interface
│ │ └── DefaultAuthProvider.ts
│ ├── cli/ # CLI tools
│ │ ├── createAdmin.ts
│ │ ├── export.ts
│ │ └── import.ts
│ ├── cluster/ # Distributed cluster
│ │ ├── clusterManager.ts # ZeroMQ cluster
│ │ └── webSocketManager.ts # WebSocket server
│ ├── http/ # HTTP server
│ │ └── HttpServer.ts # Custom implementation
│ ├── request/ # Request handlers
│ │ ├── requestAuth.ts
│ │ ├── requestWorkFlow.ts
│ │ ├── requestCategory.ts
│ │ ├── requestDataType.ts
│ │ ├── requestNodeConfig.ts
│ │ ├── requestSync.ts
│ │ ├── requestHistory.ts
│ │ └── requestImage.ts
│ ├── utils/ # Utilities
│ │ ├── arangoUtils.ts
│ │ ├── env.ts
│ │ ├── generateCert.ts
│ │ └── image/
│ │ ├── imageCompression.ts
│ │ └── imageValidation.ts
│ ├── server.ts # Main entry point
│ └── index.ts # Exports
├── certs/ # Generated SSL certificates
├── package.json
├── tsconfig.json
└── README.mdDevelopment Scripts
# Start in development mode
npm run dev
# Build package
npm run build
# Generate barrel files
npm run barrelize
# Create admin
npm run create-adminAdding a New Endpoint
- Create a file in
src/request/:
// src/request/requestMyFeature.ts
import { HttpServer } from '../http/HttpServer';
import { db } from '../server';
export class RequestMyFeature {
static init(app: HttpServer) {
app.get('/api/myfeature', async (req, res) => {
// Your logic
res.json({ data: 'Hello' });
});
app.post('/api/myfeature', async (req, res) => {
const data = req.body;
// Process data
res.json({ success: true });
});
}
}- Register in
server.ts:
import { RequestMyFeature } from './request/requestMyFeature';
// After app initialization
RequestMyFeature.init(app);- Export in
index.ts:
export * from './request/requestMyFeature';Deployment
Deployment with PM2
# Install PM2
npm install -g pm2
# Start server
pm2 start dist/server.js --name nodius-server -- port=8426 https=true
# View logs
pm2 logs nodius-server
# Restart
pm2 restart nodius-server
# Stop
pm2 stop nodius-serverDeployment with Docker
FROM node:18-alpine
WORKDIR /app
# Copy files
COPY package*.json ./
COPY packages/server ./packages/server
COPY packages/utils ./packages/utils
COPY packages/process ./packages/process
# Install and build
RUN npm install
RUN npm run build
# Expose ports
EXPOSE 8426 9426 10426
# Environment variables
ENV PORT=8426
ENV HTTPS=true
ENV ARANGO_URL=http://arangodb:8529
# Start
CMD ["node", "packages/server/dist/server.js"]Deployment with Systemd
# /etc/systemd/system/nodius-server.service
[Unit]
Description=Nodius Server
After=network.target arangodb.service
[Service]
Type=simple
User=nodius
WorkingDirectory=/opt/nodius
ExecStart=/usr/bin/node /opt/nodius/packages/server/dist/server.js port=8426 https=true
Restart=on-failure
RestartSec=10
StandardOutput=syslog
StandardError=syslog
SyslogIdentifier=nodius-server
Environment=NODE_ENV=production
Environment=ARANGO_URL=http://localhost:8529
Environment=ARANGO_USER=nodius
Environment=ARANGO_PASS=secure_password
[Install]
WantedBy=multi-user.target# Enable and start
sudo systemctl enable nodius-server
sudo systemctl start nodius-server
# View logs
sudo journalctl -u nodius-server -fCluster Deployment
To deploy multiple instances in cluster:
- Configure ZeroMQ on each server
- Share the same ArangoDB database
- Load Balancer in front of instances (nginx, HAProxy)
# nginx configuration for load balancing
upstream nodius_backend {
server server1.example.com:8426;
server server2.example.com:8426;
server server3.example.com:8426;
}
server {
listen 443 ssl http2;
server_name nodius.example.com;
ssl_certificate /etc/ssl/cert.pem;
ssl_certificate_key /etc/ssl/key.pem;
location /api {
proxy_pass https://nodius_backend;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
}
location /ws {
proxy_pass https://nodius_backend;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
proxy_set_header Host $host;
}
}Security
Best Practices
- JWT Secret: Use a strong and unique secret
- HTTPS: Always enable HTTPS in production
- Rate Limiting: Configure appropriate limits
- CORS: Restrict allowed origins
- Validation: Validate all user inputs
- ArangoDB: Use strong credentials
- Updates: Keep dependencies up to date
Secure Configuration Example
// Strict rate limiting
app.use(rateLimit({
windowMs: 60000, // 1 minute
max: 30 // 30 requests max
}));
// Restricted CORS
app.use(cors({
origin: 'https://your-domain.com',
methods: 'GET,POST,PUT,DELETE',
allowedHeaders: 'Content-Type,Authorization'
}));
// Strong JWT secret
const jwtSecret = process.env.JWT_SECRET || crypto.randomBytes(64).toString('hex');Contributing
Contributions are welcome! To contribute:
- Respect the modular architecture
- Add tests if applicable
- Document new endpoints
- Maintain compatibility with existing clients
Support
- Issues: https://github.com/Nodius-kit/Nodius/issues
- API Documentation: See types in
@nodius/utils
License
ISC - See LICENSE
Creator
Hugo MATHIEU
- Email: [email protected]
- LinkedIn: https://www.linkedin.com/in/hugo-mathieu-fullstack/
Note: This server is designed to be deployed in a secure cloud environment. Make sure to follow security best practices in production.
