Files
Krow-workspace/internal-api-harness/src/api/krowSDK.js
2025-11-24 17:15:08 -05:00

416 lines
10 KiB
JavaScript

import apiClient from './client';
import { auth, dataConnect } from '../firebase';
import { signOut } from 'firebase/auth';
import * as dcSdk from '@dataconnect/generated'; // listEvents, createEvent, etc.
// --- Auth Module ---
const authModule = {
/**
* Fetches the currently authenticated user's profile from the backend.
* @returns {Promise<object>} The user profile.
*/
me: async () => {
const { data } = await apiClient.get('/auth/me');
return data;
},
/**
* Logs the user out.
* @param {string} [redirectUrl] - Optional URL to redirect to after logout.
*/
logout: async (redirectUrl) => {
await signOut(auth);
if (redirectUrl) {
window.location.href = redirectUrl;
}
},
/**
* Checks if a user is currently authenticated.
* @returns {boolean} True if a user is authenticated.
*/
isAuthenticated: () => {
return !!auth.currentUser;
},
};
// --- Core Integrations Module ---
const coreIntegrationsModule = {
/**
* Sends an email.
* @param {object} params - { to, subject, body }
* @returns {Promise<object>} API response.
*/
SendEmail: async (params) => {
const { data } = await apiClient.post('/sendEmail', params);
return data;
},
/**
* Invokes a large language model.
* @param {object} params - { prompt, response_json_schema, file_urls }
* @returns {Promise<object>} API response.
*/
InvokeLLM: async (params) => {
const { data } = await apiClient.post('/invokeLLM', params);
return data;
},
/**
* Uploads a public file.
* @param {File} file - The file to upload.
* @returns {Promise<object>} API response with file_url.
*/
UploadFile: async ({ file }) => {
const formData = new FormData();
formData.append('file', file);
const { data } = await apiClient.post('/uploadFile', formData, {
headers: { 'Content-Type': 'multipart/form-data' },
});
return data;
},
/**
* Uploads a private file.
* @param {File} file - The file to upload.
* @returns {Promise<object>} API response with file_uri.
*/
UploadPrivateFile: async ({ file }) => {
const formData = new FormData();
formData.append('file', file);
const { data } = await apiClient.post('/uploadPrivateFile', formData, {
headers: { 'Content-Type': 'multipart/form-data' },
});
return data;
},
/**
* Creates a temporary signed URL for a private file.
* @param {object} params - { file_uri, expires_in }
* @returns {Promise<object>} API response with signed_url.
*/
CreateFileSignedUrl: async (params) => {
const { data } = await apiClient.post('/createSignedUrl', params);
return data;
},
};
// --- Entities Module ---
// Based on docs/07-reference-base44-api-export.md
/*const entityNames = [
"User", "Event", "Staff", "Vendor", "VendorRate", "Invoice", "Business",
"Certification", "Team", "Conversation", "Message", "ActivityLog",
"Enterprise", "Sector", "Partner", "Order", "Shift"
];
const entitiesModule = {};
entityNames.forEach(entityName => {
// This factory creates a standard set of CRUD-like methods for each entity.
// It assumes a consistent RESTful endpoint structure: /entities/{EntityName}/{method}
entitiesModule[entityName] = {
get: async (params) => {
const { data } = await apiClient.get(`/entities/${entityName}/get`, { params });
return data;
},
create: async (params) => {
const { data } = await apiClient.post(`/entities/${entityName}/create`, params);
return data;
},
update: async (params) => {
const { data } = await apiClient.post(`/entities/${entityName}/update`, params);
return data;
},
delete: async (params) => {
const { data } = await apiClient.post(`/entities/${entityName}/delete`, params);
return data;
},
filter: async (params) => {
const { data } = await apiClient.post(`/entities/${entityName}/filter`, params);
return data;
},
list: async () => {
// Assuming a 'filter' with no params can act as 'list'
const { data } = await apiClient.post(`/entities/${entityName}/filter`, {});
return data;
}
};
});*/
const dataconnectEntityConfig = {
Event: {
list: 'listEvents',
create: 'createEvent',
// get: 'getEvent',
// update: 'updateEvent',
// delete: 'deleteEvent',
// filter: 'filterEvents',
},
Staff: {
list: 'listStaff',
create: 'createStaff',
},
Vendor: {
list: 'listVendor',
get: 'getVendorById',
create: 'createVendor',
update: 'updateVendor',
delete: 'deleteVendor',
filter: 'filterVendors',
},
VendorRate: {
},
Invoice:{
},
Business:{
},
Certification:{
},
Team:{
},
Conversation:{
},
Message:{
},
ActivityLog:{
},
Enterprise:{
},
Sector:{
},
Partner:{
},
Order:{
},
Shift:{
}
};
// Helper for methods not implemented
const notImplemented = (entityName, method) => async () => {
throw new Error(`${entityName}.${method} is not implemented yet for Data Connect`);
};
// --- Entities Module ( Data Connect, without REST Base44) ---
const entitiesModule = {};
Object.entries(dataconnectEntityConfig).forEach(([entityName, ops]) => {
entitiesModule[entityName] = {
get: notImplemented(entityName, 'get'),
update: notImplemented(entityName, 'update'),
delete: notImplemented(entityName, 'delete'),
filter: notImplemented(entityName, 'filter'),
list: notImplemented(entityName, 'list'),
create: notImplemented(entityName, 'create'),
// list
...(ops.list && {
list: async (params) => {
const fn = dcSdk[ops.list];
if (typeof fn !== 'function') {
throw new Error(
`Data Connect operation "${ops.list}" not found for entity "${entityName}".`
);
}
return fn(dataConnect);
},
}),
// create
...(ops.create && {
create: async (params) => {
const fn = dcSdk[ops.create];
if (typeof fn !== 'function') {
throw new Error(
`Data Connect operation "${ops.create}" not found for entity "${entityName}".`
);
}
const { data } = params ?? {};
if (!data) {
throw new Error(
`${entityName}.create expects a payload like { data: { ...fields } }`
);
}
return fn(dataConnect, data);
},
}),
//get
...(ops.get && {
get: async (params) => {
const fn = dcSdk[ops.get];
if (typeof fn !== 'function') {
throw new Error(
`Data Connect operation "${ops.get}" not found for entity "${entityName}".`
);
}
if (!params || typeof params !== 'object') {
throw new Error(`${entityName}.get expects an object of variables (e.g. { id })`);
}
return fn(dataConnect, params);
},
}),
//update
...(ops.update && {
update: async (params) => {
const fn = dcSdk[ops.update];
if (typeof fn !== 'function') {
throw new Error(
`Data Connect operation "${ops.update}" not found for entity "${entityName}".`
);
}
if (!params || typeof params !== 'object') {
throw new Error(
`${entityName}.update expects an object of variables matching the GraphQL mutation`
);
}
const { id, data } = params;
if (!id) {
throw new Error(`${entityName}.update requires an "id" field`);
}
if (!data || typeof data !== 'object') {
throw new Error(
`${entityName}.update requires a "data" object with the fields to update`
);
}
const vars = { id, ...data };
return fn(dataConnect, vars);
},
}),
// delete
...(ops.delete && {
delete: async (params) => {
const fn = dcSdk[ops.delete];
if (typeof fn !== 'function') {
throw new Error(
`Data Connect operation "${ops.delete}" not found for entity "${entityName}".`
);
}
if (!params || typeof params !== 'object') {
throw new Error(
`${entityName}.delete expects an object like { id }`
);
}
const { id } = params;
if (!id) {
throw new Error(`${entityName}.delete requires an "id" field`);
}
// Data Connect solo espera { id } como variables
return fn(dataConnect, { id });
},
}),
// filter
...(ops.filter && {
filter: async (params) => {
const fn = dcSdk[ops.filter];
if (typeof fn !== 'function') {
throw new Error(
`Data Connect operation "${ops.filter}" not found for entity "${entityName}".`
);
}
if (!params) {
if (ops.list) {//if no params, call to list()
const listFn = dcSdk[ops.list];
if (typeof listFn !== 'function') {
throw new Error(
`Data Connect operation "${ops.list}" not found for entity "${entityName}".`
);
}
return listFn(dataConnect);
}
throw new Error(`${entityName}.filter expects params or a list operation`);
}
const rawFilters = params.filters ?? params;
const variables = {};
for (const [key, value] of Object.entries(rawFilters)) {//cleaning undefined/null/'' values
if (value !== undefined && value !== null && value !== '') {
variables[key] = value;
}
}
// if no valid filters, call to list()
if (Object.keys(variables).length === 0) {
if (ops.list) {
const listFn = dcSdk[ops.list];
if (typeof listFn !== 'function') {
throw new Error(
`Data Connect operation "${ops.list}" not found for entity "${entityName}".`
);
}
return listFn(dataConnect);
}
throw new Error(`${entityName}.filter received no valid filters and no list operation`);
}
return fn(dataConnect, variables);
},
}),
};
});
// --- Main SDK Export ---
export const krowSDK = {
auth: authModule,
integrations: {
Core: coreIntegrationsModule,
},
entities: entitiesModule,
};