important configuration for dataconnect and firebase
This commit is contained in:
22
frontend-web/src/api/client.js
Normal file
22
frontend-web/src/api/client.js
Normal file
@@ -0,0 +1,22 @@
|
||||
import axios from "axios";
|
||||
import { auth } from "../firebase";
|
||||
|
||||
const apiClient = axios.create({
|
||||
baseURL: import.meta.env.VITE_API_BASE_URL, // You will need to add this to your .env file
|
||||
});
|
||||
|
||||
apiClient.interceptors.request.use(
|
||||
async (config) => {
|
||||
const user = auth.currentUser;
|
||||
if (user) {
|
||||
const token = await user.getIdToken();
|
||||
config.headers.Authorization = `Bearer ${token}`;
|
||||
}
|
||||
return config;
|
||||
},
|
||||
(error) => {
|
||||
return Promise.reject(error);
|
||||
}
|
||||
);
|
||||
|
||||
export default apiClient;
|
||||
466
frontend-web/src/api/krowSDK.js
Normal file
466
frontend-web/src/api/krowSDK.js
Normal file
@@ -0,0 +1,466 @@
|
||||
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;
|
||||
},
|
||||
};
|
||||
|
||||
const dataconnectEntityConfig = {
|
||||
User: {
|
||||
list: 'listUsers',
|
||||
get: 'getUserById',
|
||||
create: 'createUser',
|
||||
update: 'updateUser',
|
||||
delete: 'deleteUser',
|
||||
filter: 'filterUsers',
|
||||
},
|
||||
Event: {
|
||||
list: 'listEvents',
|
||||
create: 'createEvent',
|
||||
get: 'getEventById',
|
||||
update: 'updateEvent',
|
||||
delete: 'deleteEvent',
|
||||
filter: 'filterEvents',
|
||||
},
|
||||
|
||||
Staff: {
|
||||
list: 'listStaff',
|
||||
create: 'createStaff',
|
||||
get: 'getStaffById',
|
||||
update: 'updateStaff',
|
||||
delete: 'deleteStaff',
|
||||
filter: 'filterStaff',
|
||||
},
|
||||
|
||||
Vendor: {
|
||||
list: 'listVendor',
|
||||
get: 'getVendorById',
|
||||
create: 'createVendor',
|
||||
update: 'updateVendor',
|
||||
delete: 'deleteVendor',
|
||||
filter: 'filterVendors',
|
||||
},
|
||||
|
||||
VendorRate: {
|
||||
list: 'listVendorRate',
|
||||
get: 'getVendorRateById',
|
||||
create: 'createVendorRate',
|
||||
update: 'updateVendorRate',
|
||||
delete: 'deleteVendorRate',
|
||||
filter: 'filterVendorRates',
|
||||
},
|
||||
|
||||
VendorDefaultSetting:{
|
||||
list: 'listVendorDefaultSettings',
|
||||
get: 'getVendorDefaultSettingById',
|
||||
create: 'createVendorDefaultSetting',
|
||||
update: 'updateVendorDefaultSetting',
|
||||
delete: 'deleteVendorDefaultSetting',
|
||||
filter: 'filterVendorDefaultSettings',
|
||||
},
|
||||
|
||||
Invoice:{
|
||||
list: 'listInvoice',
|
||||
get: 'getInvoiceById',
|
||||
create: 'createInvoice',
|
||||
update: 'updateInvoice',
|
||||
delete: 'deleteInvoice',
|
||||
filter: 'filterInvoices',
|
||||
|
||||
},
|
||||
|
||||
Business:{
|
||||
list: 'listBusiness',
|
||||
get: 'getBusinessById',
|
||||
create: 'createBusiness',
|
||||
update: 'updateBusiness',
|
||||
delete: 'deleteBusiness',
|
||||
filter: 'filterBusiness',
|
||||
},
|
||||
|
||||
Certification:{
|
||||
list: 'listCertification',
|
||||
get: 'getCertificationById',
|
||||
create: 'createCertification',
|
||||
update: 'updateCertification',
|
||||
delete: 'deleteCertification',
|
||||
filter: 'filterCertification',
|
||||
},
|
||||
|
||||
Team:{
|
||||
list: 'listTeam',
|
||||
get: 'getTeamById',
|
||||
create: 'createTeam',
|
||||
update: 'updateTeam',
|
||||
delete: 'deleteTeam',
|
||||
filter: 'filterTeam',
|
||||
},
|
||||
|
||||
TeamMember: {
|
||||
list: 'listTeamMember',
|
||||
get: 'getTeamMemberById',
|
||||
create: 'createTeamMember',
|
||||
update: 'updateTeamMember',
|
||||
delete: 'deleteTeamMember',
|
||||
filter: 'filterTeamMember',
|
||||
},
|
||||
|
||||
TeamHub: {
|
||||
list: 'listTeamHub',
|
||||
get: 'getTeamHubById',
|
||||
create: 'createTeamHub',
|
||||
update: 'updateTeamHub',
|
||||
delete: 'deleteTeamHub',
|
||||
filter: 'filterTeamHub',
|
||||
},
|
||||
|
||||
TeamMemberInvite: {
|
||||
list: 'listTeamMemberInvite',
|
||||
get: 'getTeamMemberInviteById',
|
||||
create: 'createTeamMemberInvite',
|
||||
update: 'updateTeamMemberInvite',
|
||||
delete: 'deleteTeamMemberInvite',
|
||||
filter: 'filterTeamMemberInvite',
|
||||
},
|
||||
|
||||
Conversation:{
|
||||
list: 'listConversation',
|
||||
get: 'getConversationById',
|
||||
create: 'createConversation',
|
||||
update: 'updateConversation',
|
||||
delete: 'deleteConversation',
|
||||
filter: 'filterConversation',
|
||||
},
|
||||
|
||||
Message:{
|
||||
list: 'listMessage',
|
||||
get: 'getMessageById',
|
||||
create: 'createMessage',
|
||||
update: 'updateMessage',
|
||||
delete: 'deleteMessage',
|
||||
filter: 'filterMessage',
|
||||
},
|
||||
|
||||
ActivityLog:{
|
||||
list: 'listActivityLog',
|
||||
get: 'getActivityLogById',
|
||||
create: 'createActivityLog',
|
||||
update: 'updateActivityLog',
|
||||
delete: 'deleteActivityLog',
|
||||
filter: 'filterActivityLog',
|
||||
},
|
||||
|
||||
Enterprise:{
|
||||
list: 'listEnterprise',
|
||||
get: 'getEnterpriseById',
|
||||
create: 'createEnterprise',
|
||||
update: 'updateEnterprise',
|
||||
delete: 'deleteEnterprise',
|
||||
filter: 'filterEnterprise',
|
||||
},
|
||||
|
||||
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,
|
||||
};
|
||||
Reference in New Issue
Block a user