[TSM.ID].[11031972] xcu-client v0.2.0 — API key auth, leaveRoom, billing types
JUMPA App CI / build (push) Has started running
JUMPA App CI / build (push) Has started running
This commit is contained in:
+58
-9
@@ -1,7 +1,16 @@
|
||||
// [TSM.ID].[11031972] — XCU Client Library for JUMPA.ID
|
||||
// Connects to api.xcomu.id Rust engine
|
||||
// [TSM.ID].[11031972] — XCU Client Library for JUMPA.ID v0.2.0
|
||||
// Connects to api.xcomu.id Rust engine (PostgreSQL-backed)
|
||||
|
||||
const XCU_API_URL = process.env.NEXT_PUBLIC_XCU_API_URL || 'https://api.xcomu.id';
|
||||
const XCU_API_KEY = process.env.XCU_API_KEY || process.env.NEXT_PUBLIC_XCU_API_KEY || 'xcu_live_jumpa_2026';
|
||||
|
||||
function headers(extra?: Record<string, string>): Record<string, string> {
|
||||
return {
|
||||
'Content-Type': 'application/json',
|
||||
'X-XCU-API-Key': XCU_API_KEY,
|
||||
...extra,
|
||||
};
|
||||
}
|
||||
|
||||
export interface Room {
|
||||
id: string;
|
||||
@@ -23,6 +32,7 @@ export interface Participant {
|
||||
role: string;
|
||||
transport: string;
|
||||
joined_at: string;
|
||||
is_active: boolean;
|
||||
}
|
||||
|
||||
export interface TokenResponse {
|
||||
@@ -43,34 +53,65 @@ export interface HealthResponse {
|
||||
uptime_secs: number;
|
||||
timestamp: string;
|
||||
watermark: string;
|
||||
db_connected: boolean;
|
||||
}
|
||||
|
||||
export interface BillingResponse {
|
||||
client_id: string;
|
||||
total_rooms: number;
|
||||
total_participants: number;
|
||||
active_rooms: number;
|
||||
video_minutes: number;
|
||||
period: string;
|
||||
}
|
||||
|
||||
export interface AuthResponse {
|
||||
valid: boolean;
|
||||
tenant_id: string | null;
|
||||
tenant_name: string | null;
|
||||
plan: string | null;
|
||||
}
|
||||
|
||||
export const xcuClient = {
|
||||
async health(): Promise<HealthResponse> {
|
||||
const res = await fetch(`${XCU_API_URL}/health`);
|
||||
const res = await fetch(`${XCU_API_URL}/health`, { headers: headers() });
|
||||
return res.json();
|
||||
},
|
||||
|
||||
async validateAuth(): Promise<AuthResponse> {
|
||||
const res = await fetch(`${XCU_API_URL}/v1/auth/validate`, {
|
||||
method: 'POST',
|
||||
headers: headers(),
|
||||
body: JSON.stringify({ api_key: XCU_API_KEY }),
|
||||
});
|
||||
return res.json();
|
||||
},
|
||||
|
||||
async createRoom(displayName: string, maxParticipants = 100): Promise<Room> {
|
||||
const res = await fetch(`${XCU_API_URL}/v1/rooms`, {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
headers: headers(),
|
||||
body: JSON.stringify({
|
||||
display_name: displayName,
|
||||
max_participants: maxParticipants,
|
||||
codec_preference: 'h265',
|
||||
}),
|
||||
});
|
||||
if (!res.ok) {
|
||||
const err = await res.text();
|
||||
throw new Error(`Create room failed: ${err}`);
|
||||
}
|
||||
return res.json();
|
||||
},
|
||||
|
||||
async listRooms(): Promise<Room[]> {
|
||||
const res = await fetch(`${XCU_API_URL}/v1/rooms`);
|
||||
const res = await fetch(`${XCU_API_URL}/v1/rooms`, { headers: headers() });
|
||||
if (!res.ok) return [];
|
||||
return res.json();
|
||||
},
|
||||
|
||||
async getRoom(code: string): Promise<Room> {
|
||||
const res = await fetch(`${XCU_API_URL}/v1/rooms/${code}`);
|
||||
const res = await fetch(`${XCU_API_URL}/v1/rooms/${code}`, { headers: headers() });
|
||||
if (!res.ok) throw new Error(`Room ${code} not found`);
|
||||
return res.json();
|
||||
},
|
||||
@@ -78,7 +119,7 @@ export const xcuClient = {
|
||||
async joinRoom(code: string, userId: string, displayName: string, role = 'participant'): Promise<TokenResponse> {
|
||||
const res = await fetch(`${XCU_API_URL}/v1/rooms/${code}/join`, {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
headers: headers(),
|
||||
body: JSON.stringify({
|
||||
external_user_id: userId,
|
||||
display_name: displayName,
|
||||
@@ -89,8 +130,16 @@ export const xcuClient = {
|
||||
return res.json();
|
||||
},
|
||||
|
||||
async getBilling() {
|
||||
const res = await fetch(`${XCU_API_URL}/v1/billing`);
|
||||
async leaveRoom(code: string): Promise<{ success: boolean }> {
|
||||
const res = await fetch(`${XCU_API_URL}/v1/rooms/${code}/leave`, {
|
||||
method: 'POST',
|
||||
headers: headers(),
|
||||
});
|
||||
return res.json();
|
||||
},
|
||||
|
||||
async getBilling(): Promise<BillingResponse> {
|
||||
const res = await fetch(`${XCU_API_URL}/v1/billing`, { headers: headers() });
|
||||
return res.json();
|
||||
},
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user