const DEFAULT_BASE_URL = "http://localhost:3000"; function normalizeBaseUrl(value) { const normalized = String(value || DEFAULT_BASE_URL).trim().replace(/\/+$/, ""); const parsed = new URL(normalized); if (!/^https?:$/.test(parsed.protocol)) { throw new Error("YEDIR_BASE_URL must use http or https"); } return parsed.toString().replace(/\/+$/, ""); } function readConfig(overrides = {}) { const baseUrl = normalizeBaseUrl( overrides.baseUrl || process.env.YEDIR_BASE_URL || DEFAULT_BASE_URL ); const accessToken = String( overrides.accessToken || process.env.YEDIR_ACCESS_TOKEN || "" ).trim(); if (!accessToken) { throw new Error("YEDIR_ACCESS_TOKEN is required"); } return { baseUrl, accessToken }; } export class YedirApiError extends Error { constructor(message, status, payload) { super(message); this.name = "YedirApiError"; this.status = status; this.payload = payload; } } export async function yedirRequest(path, options = {}, overrides = {}) { const { baseUrl, accessToken } = readConfig(overrides); const response = await fetch(`${baseUrl}${path}`, { ...options, headers: { Accept: "application/json", Authorization: `Bearer ${accessToken}`, ...(options.body ? { "Content-Type": "application/json" } : {}), ...(options.headers || {}), }, }); const payload = await response.json().catch(() => null); if (!response.ok) { throw new YedirApiError( String(payload?.error || `Yedir API request failed (${response.status})`), response.status, payload ); } return payload; } export function getCurrentUser(overrides) { return yedirRequest("/api/openapi/v1/me", {}, overrides); } export function listCanvases( { workspaceType = "canvas", limit = 24 } = {}, overrides = {} ) { const params = new URLSearchParams({ workspaceType, limit: String(limit), }); return yedirRequest(`/api/openapi/v1/canvases?${params}`, {}, overrides); } export function getCanvas(canvasId, overrides) { return yedirRequest( `/api/openapi/v1/canvases/${encodeURIComponent(canvasId)}`, {}, overrides ); } export function applyCanvasOperation(canvasId, operationPlan, overrides) { return yedirRequest( `/api/openapi/v1/canvases/${encodeURIComponent(canvasId)}/operations`, { method: "POST", body: JSON.stringify({ operationPlan }), }, overrides ); }