Type Reference
All TypeScript types exported from @elcto/api.
Configuration
ApiClientConfig
The config-first object that every transport (apiRequest, graphqlRequest, gql,
createWebSocket, useWebSocket) and every route helper takes as its first argument.
The library itself reads no environment variables.
interface ApiClientConfig {
/** Base URL of the Heimdall API, e.g. "http://localhost:3000" (NO trailing /v1). */
baseUrl: string;
/** WebSocket URL, e.g. "ws://localhost:3000/v1/ws". Optional; derived from baseUrl if absent. */
wsUrl?: string;
/** System API key for service-to-service / SSR calls. Optional. */
systemApiKey?: string;
}
Each app builds this from its own src/lib/config.ts (which resolves
HEIMDALL_* → NEXT_PUBLIC_* → localhost default) and exposes a getApiConfig() helper
via @/lib/api:
// platform/<app>/src/lib/api/index.ts
import type { ApiClientConfig } from "@elcto/api";
import { getApiUrl, getWsUrl, getSystemApiKey } from "@/lib/config";
export function getApiConfig(): ApiClientConfig {
return {
baseUrl: getApiUrl(),
wsUrl: getWsUrl(),
systemApiKey: getSystemApiKey() || undefined,
};
}
Then pass getApiConfig() as the first argument everywhere:
import { getApiConfig, gql } from "@/lib/api";
const data = await gql<{ user: User }>(getApiConfig(), query, { id: "123" });
REST Types
ApiResponse
Response wrapper for REST API calls.
interface ApiResponse<T> {
data?: T;
error?: string;
status: number;
}
ApiRequestOptions
Options for REST API requests.
interface ApiRequestOptions {
method?: "GET" | "POST" | "PUT" | "PATCH" | "DELETE";
body?: unknown;
headers?: Record<string, string>;
/** Override auth - use specific token instead of config.systemApiKey */
accessToken?: string;
/** Original User-Agent from the client browser (forwarded as X-Original-User-Agent) */
userAgent?: string;
/** Original IP address from the client (forwarded as X-Forwarded-For) */
clientIp?: string;
/** Source service making the request (e.g., "id", "backend"). Sent as X-Source-Service header. */
sourceService?: string;
}
GraphQL Types
GraphQLResponse
Response wrapper for GraphQL queries.
interface GraphQLResponse<T> {
data?: T;
errors?: Array<{ message: string; path?: string[] }>;
}
GraphQLRequestOptions
Options for GraphQL requests.
interface GraphQLRequestOptions {
/** OAuth access token for user context */
accessToken?: string;
/** Custom headers */
headers?: Record<string, string>;
/** Original User-Agent from the client browser (forwarded as X-Original-User-Agent) */
userAgent?: string;
/** Original IP address from the client (forwarded as X-Forwarded-For) */
clientIp?: string;
/** Source service making the request (e.g., "id", "backend"). Sent as X-Source-Service header. */
sourceService?: string;
/** User ID from the authenticated session (sent as X-User-Id for audit logging) */
userId?: string;
}
WebSocket Types
WebSocketConfig
Configuration for WebSocket connections.
interface WebSocketConfig {
accessToken?: string;
autoReconnect?: boolean;
reconnectDelay?: number;
maxReconnectAttempts?: number;
}
WebSocketClient
WebSocket client interface.
interface WebSocketClient {
socket: WebSocket;
send: (data: unknown) => boolean;
readonly isOpen: boolean;
close: () => void;
onOpen: (handler: () => void) => void;
onMessage: (handler: WebSocketMessageHandler) => void;
onError: (handler: WebSocketErrorHandler) => void;
onClose: (handler: WebSocketCloseHandler) => void;
}
Handler Types
type WebSocketMessageHandler = (data: unknown) => void;
type WebSocketErrorHandler = (error: Event) => void;
type WebSocketCloseHandler = (event: CloseEvent) => void;
Server Message Types
// User status
type UserStatusMessageType = "accountDeleted" | "accountBanned" | "sessionRevoked" | "forceLogout";
type UserStatusMessage = AccountDeletedMessage | AccountBannedMessage | SessionRevokedMessage | ForceLogoutMessage;
// Permissions
type PermissionMessageType = "rolesUpdated" | "permissionsUpdated" | "rolePermissionsChanged";
type PermissionMessage = RolesUpdatedMessage | PermissionsUpdatedMessage | RolePermissionsChangedMessage;
// Account linking
type AccountLinkMessageType = "emailLinkVerified" | "emailChangeVerified";
type AccountLinkMessage = EmailLinkVerifiedMessage | EmailChangeVerifiedMessage;
// OAuth consent
type OAuthConsentRevokedMessage = { type: "oAuthConsentRevoked"; /* ... */ };
// GPS / AIS / geofence
type GpsMessage = GpsUpdateMessage | VesselsUpdateMessage | GeofenceEventMessage;
// All server messages
type ServerMessage =
| UserStatusMessage
| PermissionMessage
| AccountLinkMessage
| OAuthConsentRevokedMessage
| GpsMessage;
ServerMessage and OAuthConsentRevokedMessage are exported from @elcto/api. The
GPS variants (GpsMessage, GpsUpdateMessage, VesselsUpdateMessage,
GeofenceEventMessage) are not exported as standalone names — narrow them out of
the ServerMessage union by switching on the type discriminator.
User Types
UserProfile
User profile information.
interface UserProfile {
name: string | null;
picture: string | null;
provider: string | null;
primary_provider: string | null;
last_login_at: string | null;
created_at: string | null;
}
UserPermissions
User permissions and roles.
interface UserPermissions {
/** Role names (e.g., "Admin", "Developer") - for display */
roles: string[];
/** Role IDs (e.g., "role_admin", "role_developer") - for programmatic checks */
role_ids: string[];
permissions: string[];
is_super_admin: boolean;
}
Use role_ids instead of roles for programmatic role checks. Role IDs are immutable and won't change if role names are renamed.
PlatformAccount
Connected platform account.
interface PlatformAccount {
id: string;
platform_id: string;
platform_name: string;
platform_slug: string;
is_oauth: boolean;
is_primary: boolean;
username: string;
email: string | null;
avatar_url: string | null;
created_at: string;
}
ActiveSession
Active login session information.
interface ActiveSession {
id: string;
ipAddress: string | null;
userAgent: string | null;
deviceType: string | null;
browserName: string | null;
osName: string | null;
/** Auth provider slug used for this session (twitch, discord, email, etc.) */
provider: string | null;
/** Auth provider display name (Twitch, Discord, Email, etc.) */
providerName: string | null;
lastActivityAt: string | null;
createdAt: string;
expiresAt: string;
isCurrent: boolean;
}
ActiveSessionsResponse
Response from active sessions API.
interface ActiveSessionsResponse {
sessions: ActiveSession[];
currentSessionId: string | null;
}
RevokeSessionResponse
Response from revoking a single session.
interface RevokeSessionResponse {
success: boolean;
message: string;
}
RevokeAllSessionsResponse
Response from revoking all other sessions.
interface RevokeAllSessionsResponse {
success: boolean;
revokedCount: number;
message: string;
}
Audit Types
AuditEvent
Audit event record from the activity log.
interface AuditUser {
id: string;
username?: string;
avatarUrl?: string;
}
interface AuditEvent {
id: string;
/** Heimdall user ID, external service user ID, or null for system events */
userId?: string | null;
eventType: string;
resourceType?: string;
resourceId?: string;
actorId?: string;
ipAddress?: string;
userAgent?: string;
description?: string;
metadata?: Record<string, unknown>;
status: "success" | "failure";
errorMessage?: string;
countryCode?: string;
countryName?: string;
city?: string;
region?: string;
sourceService?: string;
createdAt: string;
/** Whether this event has been reported by the user */
isReported?: boolean;
/** User information (username, avatar) - only when user_id is a valid Heimdall user */
user?: AuditUser;
/** Actor information (username, avatar) - the user who performed the action */
actor?: AuditUser;
}
sourceService Values:
| Value | Description |
|---|---|
api | Direct API calls |
id | Heimdall ID app (account management) |
backend | Heimdall Backend (admin console) |
policies | Policies app |
discord_bot | Discord bot |
twitch_bot | Twitch bot |
AuditEventPage
Paginated audit event response.
interface AuditEventPage {
events: AuditEvent[];
totalCount: number;
page: number;
limit: number;
totalPages: number;
}
AuditEventQuery
Query parameters for filtering audit events.
interface AuditEventQuery {
page?: number;
limit?: number;
/** Single event type filter */
eventType?: string;
/** Multiple event types (comma-separated string) */
eventTypes?: string;
/** Exact user ID filter (admin only) */
userId?: string;
/** Search users by ID, username, or email (partial match) */
userSearch?: string;
resourceType?: string;
status?: string;
/** Filter by source service (e.g., "api", "id", "backend") */
sourceService?: string;
/** Filter by start date (ISO 8601 format) */
startDate?: string;
/** Filter by end date (ISO 8601 format) */
endDate?: string;
/** Sort field (event_type, user_id, status, created_at, date) */
sortField?: string;
/** Sort direction (asc or desc) */
sortDirection?: string;
/** Filter to show only reported events (admin only) */
isReported?: boolean;
}
AuditEventReport
Report submitted for suspicious activity.
interface AuditEventReport {
id: string;
auditEventId: string;
userId: string;
reason: string;
description?: string;
status: "pending" | "reviewed" | "resolved" | "dismissed";
reviewedBy?: string;
reviewedAt?: string;
resolutionNotes?: string;
createdAt: string;
updatedAt: string;
/** Reviewer info (username, avatar) when the report has been reviewed */
reviewer?: {
id: string;
username?: string;
avatarUrl?: string;
};
}
ReportAuditEventInput
Input for reporting an audit event.
interface ReportAuditEventInput {
auditEventId: string;
reason: "not_me" | "suspicious" | "unknown_device" | "unknown_location" | "other";
description?: string;
}
ReportAuditEventResponse
Response from reporting an audit event.
interface ReportAuditEventResponse {
success: boolean;
report?: AuditEventReport;
error?: string;
}
AuditReportPage (Admin)
Paginated audit reports response for admins.
interface AuditReportPage {
reports: AuditEventReport[];
totalCount: number;
page: number;
limit: number;
totalPages: number;
}
UpdateAuditReportInput (Admin)
Input for updating an audit report status.
interface UpdateAuditReportInput {
reportId: string;
status: "reviewed" | "resolved" | "dismissed";
resolutionNotes?: string;
}
UpdateAuditReportResponse (Admin)
Response from updating an audit report.
interface UpdateAuditReportResponse {
success: boolean;
report?: AuditEventReport;
error?: string;
}
Audit Event Constants & Utilities
The library provides constants and helper functions for working with audit events.
AuditEventTypes
Type-safe constants for all audit event types:
import { AuditEventTypes } from "@elcto/api";
AuditEventTypes.LOGIN // "login"
AuditEventTypes.LOGIN_FAILED // "login_failed"
AuditEventTypes.LOGOUT // "logout"
AuditEventTypes.TWO_FA_ENABLED // "2fa_enabled"
AuditEventTypes.PASSWORD_CHANGED // "password_changed"
// ... and more
AuditEventLabels
Human-readable labels for event types:
import { AuditEventLabels, getAuditEventLabel } from "@elcto/api";
// Direct lookup
AuditEventLabels["login"] // "Signed in"
// Helper function (with fallback)
getAuditEventLabel("login") // "Signed in"
getAuditEventLabel("unknown_type") // "unknown_type" (fallback)
Event Categories
Categorize events for filtering and display:
import {
AuditEventCategories,
getAuditEventCategory,
type AuditEventCategory,
} from "@elcto/api";
// Categories: "auth" | "security" | "account" | "oauth" | "link" | "data"
// | "bot" | "integration" | "storage" | "admin" | "modules" | "other"
getAuditEventCategory("login") // "auth"
getAuditEventCategory("user_updated") // "account"
getAuditEventCategory("session_created") // "account"
getAuditEventCategory("consent_granted") // "oauth"
getAuditEventCategory("user_banned") // "admin"
Event Icons
Icon names for rendering audit event icons:
import {
AuditEventIcons,
getAuditEventIconName,
type AuditIconName,
} from "@elcto/api";
// Icon names: "LogIn" | "LogOut" | "Shield" | "Key" | "User" | ...
getAuditEventIconName("login") // "LogIn"
getAuditEventIconName("2fa_enabled") // "Shield"
getAuditEventIconName("password_changed") // "Lock"
Use the AuditIcon component from @elcto/ui to render these icons:
import { AuditIcon } from "@elcto/ui";
<AuditIcon eventType="login" className="w-4 h-4" />
Event Colors
Get colors for event categories and failure states:
import {
AuditCategoryColors,
AuditFailureColor,
getAuditEventColor,
} from "@elcto/api";
// Tailwind class strings (bg + text + border) keyed by category
AuditCategoryColors.auth // "bg-blue-500/10 text-blue-500 border-blue-500/20"
AuditCategoryColors.security // "bg-amber-500/10 text-amber-500 border-amber-500/20"
AuditCategoryColors.account // "bg-purple-500/10 text-purple-500 border-purple-500/20"
AuditCategoryColors.oauth // "bg-green-500/10 text-green-500 border-green-500/20"
// Failure color
AuditFailureColor // "bg-[var(--error-bg)] text-[var(--error)] border-[var(--error)]/20"
// Get color for a specific event — signature: (eventType, status)
// Failures always return AuditFailureColor; otherwise the category color is used.
getAuditEventColor("login", "success") // auth category color (blue)
getAuditEventColor("login", "failure") // AuditFailureColor
Filter Options
Pre-built filter options for activity log dropdowns:
import { AuditFilterOptions, getAuditFilterEventTypes } from "@elcto/api";
// Use in a select/dropdown
<select>
{AuditFilterOptions.map(option => (
<option key={option.value} value={option.value}>
{option.label}
</option>
))}
</select>
// Get event types for a filter category
getAuditFilterEventTypes("auth")
// Returns: ["login", "login_failed", "logout"]
getAuditFilterEventTypes("security")
// Returns: ["2fa_enabled", "2fa_disabled", "2fa_verified", ...]
Common Types
PaginationParams
Pagination parameters for list requests.
interface PaginationParams {
page?: number;
limit?: number;
offset?: number;
}
PaginatedResponse
Paginated response wrapper.
interface PaginatedResponse<T> {
items: T[];
total: number;
page: number;
limit: number;
hasMore: boolean;
}
ApiConfig
Legacy descriptor type (kept for backwards compatibility). Not the config you pass to
transports — use ApiClientConfig for that.
interface ApiConfig {
apiUrl: string;
wsUrl: string;
hasSystemKey: boolean;
}
Hook Types
UseWebSocketOptions
Options for the useWebSocket hook.
interface UseWebSocketOptions extends WebSocketConfig {
immediate?: boolean;
}
UseWebSocketReturn
Return value from useWebSocket hook.
interface UseWebSocketReturn {
isConnected: boolean;
lastMessage: unknown;
send: (data: unknown) => void;
connect: () => void;
disconnect: () => void;
}
Role Constants
The library exports role ID constants for type-safe role checks:
import {
ROLE_SUPER_ADMIN, // "role_super_admin"
ROLE_ADMIN, // "role_admin"
ROLE_MODERATOR, // "role_moderator"
ROLE_DEVELOPER, // "role_developer"
ROLE_USER, // "role_user"
PRIVILEGED_ROLE_IDS, // Array of admin/mod/dev role IDs
} from "@/lib/api";
Helper Functions
import {
hasPrivilegedRole, // Check if user has admin/mod/dev role
hasRole, // Check if user has specific role
hasAnyRole, // Check if user has any of specified roles
hasAllRoles, // Check if user has all specified roles
} from "@/lib/api";
// Usage
const { roleIds, isSuperAdmin } = usePermissions();
if (isSuperAdmin || hasPrivilegedRole(roleIds)) {
// User can access admin features
}
if (hasRole(roleIds, ROLE_DEVELOPER)) {
// User has developer role
}
Importing Types
All types can be imported from @/lib/api:
import type {
// Config
ApiClientConfig,
// REST
ApiResponse,
ApiRequestOptions,
// GraphQL
GraphQLResponse,
GraphQLRequestOptions,
// WebSocket
WebSocketConfig,
WebSocketClient,
ServerMessage,
UserStatusMessage,
PermissionMessage,
OAuthConsentRevokedMessage,
// User
UserProfile,
UserPermissions,
PlatformAccount,
ActiveSession,
ActiveSessionsResponse,
RevokeSessionResponse,
RevokeAllSessionsResponse,
// Audit
AuditEvent,
AuditEventPage,
AuditEventQuery,
AuditEventReport,
ReportAuditEventInput,
ReportAuditEventResponse,
AuditReportPage,
UpdateAuditReportInput,
UpdateAuditReportResponse,
// Common
PaginationParams,
PaginatedResponse,
ApiConfig,
// Hooks
UseWebSocketOptions,
UseWebSocketReturn,
} from "@/lib/api";
// Role constants and helpers (not types)
import {
ROLE_SUPER_ADMIN,
ROLE_ADMIN,
ROLE_MODERATOR,
ROLE_DEVELOPER,
ROLE_USER,
PRIVILEGED_ROLE_IDS,
hasPrivilegedRole,
hasRole,
hasAnyRole,
hasAllRoles,
} from "@/lib/api";