feat(Makefile): patch base44Client.js for local development
This commit introduces a script to patch the base44Client.js file within the frontend-web directory. This patch is specifically designed to facilitate local development by mocking user roles and authentication, allowing developers to test role-based functionality without needing a full Base44 SDK setup. The Makefile is updated to include a call to this script during the `integrate-export` target, ensuring that the patch is applied automatically when integrating a fresh Base44 export. This change streamlines the local development process and enhances the testing capabilities for role-based features.
This commit is contained in:
123
scripts/patch-base44-client.js
Normal file
123
scripts/patch-base44-client.js
Normal file
@@ -0,0 +1,123 @@
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
|
||||
const projectRoot = path.resolve(__dirname, '..');
|
||||
const clientFilePath = path.join(projectRoot, 'frontend-web', 'src', 'api', 'base44Client.js');
|
||||
|
||||
const originalMock = `// import { createClient } from '@base44/sdk';
|
||||
|
||||
// --- MIGRATION MOCK ---
|
||||
// This mock completely disables the Base44 SDK to allow for local development.
|
||||
export const base44 = {
|
||||
auth: {
|
||||
me: () => Promise.resolve(null),
|
||||
logout: () => {},
|
||||
},
|
||||
entities: {
|
||||
ActivityLog: {
|
||||
filter: () => Promise.resolve([]),
|
||||
},
|
||||
},
|
||||
};`;
|
||||
|
||||
const patchedMock = `// import { createClient } from '@base44/sdk';
|
||||
|
||||
// --- MIGRATION MOCK ---
|
||||
// This mock completely disables the Base44 SDK to allow for local development.
|
||||
// It also simulates user roles for the RoleSwitcher component.
|
||||
|
||||
const MOCK_USER_KEY = 'krow_mock_user_role';
|
||||
|
||||
// Default mock user data
|
||||
const DEFAULT_MOCK_USER = {
|
||||
id: "mock-user-123",
|
||||
email: "dev@example.com",
|
||||
full_name: "Dev User",
|
||||
// 'role' is the Base44 default, 'user_role' is our custom field
|
||||
role: "admin",
|
||||
user_role: "admin", // Default role for testing
|
||||
profile_picture: "https://i.pravatar.cc/150?u=a042581f4e29026024d",
|
||||
};
|
||||
|
||||
// Function to get the current mock user state
|
||||
const getMockUser = () => {
|
||||
try {
|
||||
const storedRole = localStorage.getItem(MOCK_USER_KEY);
|
||||
if (storedRole) {
|
||||
return { ...DEFAULT_MOCK_USER, user_role: storedRole, role: storedRole };
|
||||
}
|
||||
// If no role is stored, set the default and return it
|
||||
localStorage.setItem(MOCK_USER_KEY, DEFAULT_MOCK_USER.user_role);
|
||||
return DEFAULT_MOCK_USER;
|
||||
} catch (e) {
|
||||
// localStorage is not available (e.g., in SSR)
|
||||
return DEFAULT_MOCK_USER;
|
||||
}
|
||||
};
|
||||
|
||||
export const base44 = {
|
||||
auth: {
|
||||
me: () => Promise.resolve(getMockUser()),
|
||||
logout: () => {
|
||||
try {
|
||||
localStorage.removeItem(MOCK_USER_KEY); // Clear role on logout
|
||||
// Optionally, redirect to login page or reload
|
||||
window.location.reload();
|
||||
} catch (e) {
|
||||
// localStorage is not available
|
||||
}
|
||||
return Promise.resolve();
|
||||
},
|
||||
updateMe: (data) => {
|
||||
try {
|
||||
if (data.user_role) {
|
||||
localStorage.setItem(MOCK_USER_KEY, data.user_role);
|
||||
}
|
||||
} catch (e) {
|
||||
// localStorage is not available
|
||||
}
|
||||
// Simulate a successful update
|
||||
return Promise.resolve({ ...getMockUser(), ...data });
|
||||
},
|
||||
},
|
||||
entities: {
|
||||
ActivityLog: {
|
||||
filter: () => Promise.resolve([]),
|
||||
},
|
||||
// Add other entity mocks as needed for the RoleSwitcher to function
|
||||
// For now, the RoleSwitcher only updates the user role, so other entities might not be critical.
|
||||
},
|
||||
integrations: {
|
||||
Core: {
|
||||
SendEmail: () => Promise.resolve({ status: "sent" }),
|
||||
UploadFile: () => Promise.resolve({ file_url: "mock-file-url" }),
|
||||
InvokeLLM: () => Promise.resolve({ result: "mock-ai-response" }),
|
||||
// Add other integration mocks if the RoleSwitcher indirectly calls them
|
||||
}
|
||||
}
|
||||
};`;
|
||||
|
||||
try {
|
||||
let content = fs.readFileSync(clientFilePath, 'utf8');
|
||||
|
||||
if (content.includes('me: () => Promise.resolve(null),')) {
|
||||
content = content.replace(originalMock.trim(), patchedMock.trim());
|
||||
fs.writeFileSync(clientFilePath, content, 'utf8');
|
||||
console.log('✅ Successfully patched frontend-web/src/api/base44Client.js');
|
||||
} else if (content.includes('const MOCK_USER_KEY')) {
|
||||
console.log('ℹ️ base44Client.js is already patched. Skipping.');
|
||||
} else {
|
||||
// Fallback to a simpler, more brittle replacement if the full mock doesn't match
|
||||
const simpleOriginal = 'me: () => Promise.resolve(null),';
|
||||
if (content.includes(simpleOriginal)) {
|
||||
fs.writeFileSync(clientFilePath, patchedMock, 'utf8');
|
||||
console.log('✅ Successfully patched frontend-web/src/api/base44Client.js using fallback.');
|
||||
} else {
|
||||
console.error('❌ Patching failed: Could not find the original mock code in base44Client.js.');
|
||||
process.exit(1);
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('❌ An error occurred during patching:', error);
|
||||
process.exit(1);
|
||||
}
|
||||
Reference in New Issue
Block a user