UNPKG

webpods

Version:

Append-only log service with OAuth authentication

190 lines 5.83 kB
/** * Stream operations domain logic */ import { isValidStreamId, isSystemStream } from "../utils.js"; import { createLogger } from "../logger.js"; const logger = createLogger("webpods:domain:streams"); /** * Map database row to domain type */ function mapStreamFromDb(row) { return { id: row.id, pod_id: row.pod_id, stream_id: row.stream_id, creator_id: row.creator_id, access_permission: row.access_permission, metadata: undefined, created_at: row.created_at, updated_at: row.created_at, }; } /** * Get or create a stream */ export async function getOrCreateStream(db, podId, streamId, userId, accessPermission) { // Validate stream ID if (!isValidStreamId(streamId)) { return { success: false, error: { code: "INVALID_STREAM_ID", message: "Invalid stream ID", }, }; } const actualStreamId = streamId; try { // Try to find existing stream let stream = await db.oneOrNone(`SELECT * FROM stream WHERE pod_id = $(podId) AND stream_id = $(streamId)`, { podId, streamId: actualStreamId }); if (stream) { return { success: true, data: { stream: mapStreamFromDb(stream), created: false }, }; } // Create new stream stream = await db.one(`INSERT INTO stream (id, pod_id, stream_id, creator_id, access_permission, created_at) VALUES (gen_random_uuid(), $(podId), $(streamId), $(userId), $(accessPermission), NOW()) RETURNING *`, { podId, streamId: actualStreamId, userId, accessPermission: accessPermission || "public", }); logger.info("Stream created", { podId, streamId: actualStreamId, userId }); return { success: true, data: { stream: mapStreamFromDb(stream), created: true }, }; } catch (error) { logger.error("Failed to get/create stream", { error, podId, streamId }); return { success: false, error: { code: "DATABASE_ERROR", message: "Failed to get/create stream", }, }; } } /** * Get stream by pod and stream ID */ export async function getStream(db, podId, streamId) { try { const stream = await db.oneOrNone(`SELECT * FROM stream WHERE pod_id = $(podId) AND stream_id = $(streamId)`, { podId, streamId }); if (!stream) { return { success: false, error: { code: "STREAM_NOT_FOUND", message: "Stream not found", }, }; } return { success: true, data: mapStreamFromDb(stream) }; } catch (error) { logger.error("Failed to get stream", { error, podId, streamId }); return { success: false, error: { code: "DATABASE_ERROR", message: "Failed to get stream", }, }; } } /** * Delete a stream */ export async function deleteStream(db, podId, streamId, userId) { // Prevent deletion of system streams if (isSystemStream(streamId)) { return { success: false, error: { code: "FORBIDDEN", message: "System streams cannot be deleted", }, }; } try { const stream = await db.oneOrNone(`SELECT * FROM stream WHERE pod_id = $(podId) AND stream_id = $(streamId)`, { podId, streamId }); if (!stream) { return { success: false, error: { code: "STREAM_NOT_FOUND", message: "Stream not found", }, }; } // Only creator can delete stream if (stream.creator_id !== userId) { return { success: false, error: { code: "FORBIDDEN", message: "Only stream creator can delete stream", }, }; } // Delete stream (cascades to records) await db.none(`DELETE FROM stream WHERE id = $(streamId)`, { streamId: stream.id, }); logger.info("Stream deleted", { podId, streamId, userId }); return { success: true, data: undefined }; } catch (error) { logger.error("Failed to delete stream", { error, podId, streamId }); return { success: false, error: { code: "DATABASE_ERROR", message: "Failed to delete stream", }, }; } } /** * Update stream permissions */ export async function updateStreamPermissions(db, streamId, accessPermission) { try { const stream = await db.oneOrNone(`UPDATE stream SET access_permission = COALESCE($(accessPermission), access_permission) WHERE id = $(streamId) RETURNING *`, { streamId, accessPermission }); if (!stream) { return { success: false, error: { code: "STREAM_NOT_FOUND", message: "Stream not found", }, }; } return { success: true, data: mapStreamFromDb(stream) }; } catch (error) { logger.error("Failed to update stream permissions", { error, streamId }); return { success: false, error: { code: "DATABASE_ERROR", message: "Failed to update stream permissions", }, }; } } //# sourceMappingURL=streams.js.map