UNPKG

alnilam-cli

Version:

Git-native AI career coach that converts multi-year ambitions into weekly execution

225 lines (224 loc) 8.24 kB
"use strict"; var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || (function () { var ownKeys = function(o) { ownKeys = Object.getOwnPropertyNames || function (o) { var ar = []; for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k; return ar; }; return ownKeys(o); }; return function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]); __setModuleDefault(result, mod); return result; }; })(); Object.defineProperty(exports, "__esModule", { value: true }); exports.restClient = exports.apiClient = void 0; exports.getAPIClient = getAPIClient; exports.callFunction = callFunction; exports.getDatabase = getDatabase; exports.createGoal = createGoal; exports.listGoals = listGoals; exports.addEvidence = addEvidence; const auth_js_1 = require("./auth.js"); /** * Get the authenticated Supabase client for all API operations * This replaces axios clients and manual auth header management */ function getAPIClient() { return (0, auth_js_1.createAuthenticatedSupabaseClient)(); } /** * Call a Supabase Edge Function with automatic authentication */ async function callFunction(functionName, data) { const client = getAPIClient(); const { data: result, error } = await client.functions.invoke(functionName, { body: data }); if (error) { throw new Error(`Function ${functionName} failed: ${error.message}`); } return result; } /** * Extract data from Edge Function response wrapper * @param result - Raw response from Edge Function * @param dataKey - Key to extract (e.g., 'goal', 'evidence', 'goals') * @returns Extracted data */ function extractResponseData(result, dataKey) { if (!result) return null; // If result has the specific data key, return that if (result[dataKey] !== undefined) { return result[dataKey]; } // If result has success: true, it's likely a wrapper if (result.success === true) { return result[dataKey] || result; } // Otherwise return the result as-is return result; } /** * Direct database operations using Supabase client */ function getDatabase() { return getAPIClient(); } // Goal API functions async function createGoal(goal) { const result = await callFunction('create_goal', goal); return extractResponseData(result, 'goal'); } async function listGoals(params) { const client = getAPIClient(); // Get current auth session to pass as header const { data: { session } } = await client.auth.getSession(); if (!session) { throw new Error('Not authenticated'); } // Get config to access supabaseUrl const { getConfig } = await Promise.resolve().then(() => __importStar(require('./config.js'))); const config = getConfig(); // Build query string from params const queryParams = new URLSearchParams(); if (params?.horizon) queryParams.append('horizon', params.horizon); if (params?.status) queryParams.append('status', params.status); if (params?.limit) queryParams.append('limit', params.limit.toString()); if (params?.offset) queryParams.append('offset', params.offset.toString()); // Make direct HTTP GET request to the Edge Function const url = `${config.supabaseUrl}/functions/v1/list_goals?${queryParams.toString()}`; const response = await fetch(url, { method: 'GET', headers: { 'Authorization': `Bearer ${session.access_token}`, 'Content-Type': 'application/json' } }); if (!response.ok) { const errorText = await response.text().catch(() => 'Unknown error'); throw new Error(`Function list_goals failed: HTTP ${response.status} ${response.statusText} - ${errorText}`); } const result = await response.json(); // Extract goals array from response wrapper return extractResponseData(result, 'goals') || []; } // Evidence API functions async function addEvidence(evidence) { const result = await callFunction('add_evidence', evidence); return extractResponseData(result, 'evidence'); } // Legacy exports for backward compatibility during transition exports.apiClient = { post: async (path, data) => { // Extract function name from path (e.g., '/functions/v1/create_goal' -> 'create_goal') const functionName = path.split('/').pop(); if (!functionName) { throw new Error('Invalid function path'); } return { data: await callFunction(functionName, data) }; }, get: async (path, params) => { // For GET requests, we'll use direct database queries instead of Edge Functions const functionName = path.split('/').pop(); if (!functionName) { throw new Error('Invalid function path'); } return { data: await callFunction(functionName, params) }; }, patch: async (path, data) => { const functionName = path.split('/').pop(); if (!functionName) { throw new Error('Invalid function path'); } return { data: await callFunction(functionName, data) }; } }; exports.restClient = { ...getDatabase(), get: async (path, params) => { // For direct database queries const client = getDatabase(); const tableName = path.split('/').pop(); if (!tableName) { throw new Error('Invalid table path'); } const { data, error } = await client.from(tableName).select('*'); if (error) { throw error; } return { data }; }, patch: async (path, data) => { // For database updates - handle PostgREST query format const client = getDatabase(); // Parse path like "/nudges?id=eq.abc123" or "/nudges/abc123" const pathParts = path.split('?'); const tablePart = pathParts[0]; // "/nudges" const queryPart = pathParts[1]; // "id=eq.abc123" const tableName = tablePart.split('/').pop(); // "nudges" if (!tableName) { throw new Error('Invalid path for patch operation - no table name'); } let query = client.from(tableName).update(data); if (queryPart) { // Parse PostgREST query format: "id=eq.abc123" const queryParams = queryPart.split('&'); for (const param of queryParams) { const [field, condition] = param.split('='); if (condition && condition.startsWith('eq.')) { const value = condition.substring(3); // Remove "eq." prefix query = query.eq(field, value); } } } else { // Fallback: try to extract ID from path like "/table/id" const pathSegments = tablePart.split('/'); const id = pathSegments[pathSegments.length - 1]; if (id && id !== tableName) { query = query.eq('id', id); } else { throw new Error('Invalid path for patch operation - no ID specified'); } } const { data: result, error } = await query.select(); if (error) { throw error; } return { data: result }; } };