Skip to main content

TypeScript Types

Complete TypeScript type reference for the Lumio Developer SDK and Developer REST API.

Core extension types

Extension

Represents a published extension in the Lumio store.

interface Extension {
id: string; // "ext_01j9k2m3n4p5q6r7s8t9u0v1w2"
slug: string; // "my-scoreboard"
name: string;
description: string;
shortDescription: string;
authorId: string;
visibility: "private" | "unlisted" | "public";
status: "draft" | "in_review" | "approved" | "rejected" | "suspended";
pricing: PricingConfig;
currentVersionId: string | null;
installCount: number;
rating: number | null;
ratingCount: number;
createdAt: string; // ISO 8601
updatedAt: string;
}

ExtensionVersion

A specific published version of an extension.

interface ExtensionVersion {
id: string;
extensionId: string;
version: string; // semver, e.g. "1.2.0"
changelog: string;
status: "pending" | "approved" | "rejected";
targets: ExtensionTarget[];
hasServer: boolean;
bundleSizeBytes: number;
submittedAt: string;
approvedAt: string | null;
}

type ExtensionTarget = "layer" | "editor" | "interactive";

ExtensionInstall

A record of an extension installed in a user's Lumio account.

interface ExtensionInstall {
id: string; // installId
extensionId: string;
extensionVersionId: string;
accountId: string;
overlayId: string | null; // null if not yet placed on an overlay
config: Record<string, unknown>;
installedAt: string;
updatedAt: string;
}

PricingConfig

type PricingConfig =
| { type: "free" }
| { type: "one_time"; amount: number; currency: "EUR" | "USD" | "GBP" }
| {
type: "subscription";
amount: number;
currency: "EUR" | "USD" | "GBP";
interval: "monthly";
};

Config types

LumioConfig

The shape returned by useLumioConfig(). The config field is the raw JSON stored by the editor.

interface UseLumioConfigResult<T = Record<string, unknown>> {
config: T | null;
setConfig: (patch: Partial<T>) => Promise<void>;
loading: boolean;
}

LumioConfigSchema

A field descriptor used in the declarative defineConfig() API.

type LumioConfigField =
| { type: "string"; label: string; default?: string; placeholder?: string }
| { type: "number"; label: string; default?: number; min?: number; max?: number }
| { type: "boolean"; label: string; default?: boolean }
| { type: "select"; label: string; options: Array<{ value: string; label: string }>; default?: string }
| { type: "color"; label: string; default?: string };

Event types

LumioEvent

interface LumioEvent<T = unknown> {
type: LumioEventType;
timestamp: string; // ISO 8601
data: T;
}

type LumioEventType =
// Twitch
| "twitch:follower"
| "twitch:subscribe"
| "twitch:gift_sub"
| "twitch:resub"
| "twitch:cheer"
| "twitch:raid"
| "twitch:reward"
| "twitch:hype_train"
| "twitch:hype_train_end"
| "twitch:poll"
| "twitch:poll_end"
| "twitch:prediction"
| "twitch:prediction_lock"
| "twitch:prediction_end"
| "twitch:goal"
| "twitch:goal_end"
| "twitch:ad_break"
| "twitch:ban"
| "twitch:unban"
| "twitch:stream_online"
| "twitch:stream_offline"
| "twitch:stream_update"
// YouTube
| "youtube:subscribe"
| "youtube:member"
| "youtube:superchat"
| "youtube:supersticker"
| "youtube:gift_membership"
| "youtube:gift_membership_received"
| "youtube:poll"
// Kick
| "kick:follower"
| "kick:subscribe"
| "kick:gift"
| "kick:stream_online"
| "kick:stream_offline"
| "kick:chat"
// Trovo
| "trovo:subscribe"
| "trovo:spell"
| "trovo:chat"
// Spotify
| "spotify:track"
| "spotify:play"
| "spotify:pause"
| "spotify:skip"
| "spotify:volume"
| "spotify:queue_add"
| "spotify:device"
| "spotify:playlist_add"
| "spotify:playlist_remove"
| "spotify:playlist_create"
| "spotify:playlist_edit"
| "spotify:playlist_delete"
// StreamElements
| "streamelements:tip"
// Chat — per-platform
| "twitch:chat"
| "youtube:chat"
// Chat — catch-all (fires for all platforms)
| "chat:message";

Event payload types

interface TwitchFollowerData {
userName: string;
userId: string;
followedAt: string;
}

interface TwitchSubscribeData {
userName: string;
userId: string;
tier: "1000" | "2000" | "3000" | "prime";
months: number;
message: string | null;
}

interface TwitchGiftSubData {
gifterName: string;
gifterUserId: string;
recipientName: string;
recipientUserId: string;
tier: "1000" | "2000" | "3000";
}

interface TwitchResubData {
userName: string;
userId: string;
tier: "1000" | "2000" | "3000" | "prime";
months: number;
message: string | null;
}

interface TwitchCheerData {
userName: string;
userId: string;
bits: number;
message: string;
}

interface TwitchRaidData {
fromBroadcasterName: string;
fromBroadcasterId: string;
viewerCount: number;
}

interface TwitchRewardData {
userName: string;
userId: string;
rewardId: string;
rewardTitle: string;
rewardCost: number;
input: string | null;
status: "unfulfilled" | "fulfilled" | "canceled";
}

interface TwitchBanData {
userName: string;
userId: string;
reason: string | null;
moderatorName: string;
}

interface TwitchUnbanData {
userName: string;
userId: string;
moderatorName: string;
}

interface TwitchStreamOnlineData {
broadcasterName: string;
broadcasterId: string;
startedAt: string;
}

interface TwitchStreamOfflineData {
broadcasterName: string;
broadcasterId: string;
}

interface TwitchStreamUpdateData {
title: string;
categoryName: string;
categoryId: string;
}

interface SpotifyTrackData {
title: string;
artist: string;
album: string;
albumArtUrl: string;
duration: number; // milliseconds
progress: number; // milliseconds
isPlaying: boolean;
}

interface ChatMessageData {
platform: "twitch" | "youtube" | "kick" | "trovo";
userName: string;
userId: string;
message: string;
emotes: Array<{ id: string; name: string; url: string }>;
badges: string[];
color?: string;
}

Server function types

ActionHandler

type ActionHandler<TArgs, TReturn> = (
ctx: ActionContext,
args: TArgs
) => Promise<TReturn>;

interface ActionContext {
db: StorageContext;
fetch: typeof fetch;
secrets: SecretsContext;
realtime: RealtimeContext;
identity: IdentityContext | null;
}

StorageContext

interface StorageContext {
get<T>(scope: "global" | "install" | "user", key: string): Promise<T | null>;
get<T>(scope: "global" | "install" | "user", ...keys: string[]): Promise<T | null>;
set(scope: "global" | "install" | "user", key: string, value: unknown): Promise<void>;
set(scope: "global" | "install" | "user", ...keysAndValue: [...string[], unknown]): Promise<void>;
delete(scope: "global" | "install" | "user", ...keys: string[]): Promise<void>;
list(scope: "global" | "install" | "user", prefix?: string): Promise<string[]>;
}

SecretsContext

interface SecretsContext {
get(key: string): string; // throws if key not set
has(key: string): boolean;
}

RealtimeContext

interface RealtimeContext {
push(event: string, data: unknown): Promise<void>;
}

Theme types

interface LumioTheme {
mode: "light" | "dark";
primaryColor: string; // hex, e.g. "#6366f1"
fontFamily: string;
borderRadius: number; // px
}

Identity types

interface LumioIdentity {
userId: string;
userName: string;
platform: "twitch" | "youtube" | "kick" | "trovo" | null;
platformUserId: string | null;
isAuthenticated: boolean;
}

Validation schema types

import { v } from "@zaflun/lumio-sdk/server";

// Primitive validators
v.string() // string
v.number() // number
v.boolean() // boolean
v.null_() // null

// Compound validators
v.optional(v.string()) // string | undefined
v.nullable(v.string()) // string | null
v.array(v.string()) // string[]
v.object({ key: v.string() }) // { key: string }
v.union([v.string(), v.number()]) // string | number
v.literal("exact") // "exact"