@makolabs/ripple
Version:
Simple Svelte 5 powered component library ✨
209 lines (208 loc) • 7.1 kB
JavaScript
/**
* Mock User Management Functions
*
* Mock implementation of user management functions for testing and development.
* These are regular async functions (NOT remote functions) that match the UserManagementAdapter interface.
* They store data in memory and work in both SvelteKit and non-SvelteKit contexts (like Storybook).
*
* Note: These are NOT actual remote functions because remote functions require a SvelteKit server context
* which doesn't exist in Storybook/tests. They're regular async functions that match the adapter interface.
*
* To set initial data, use the resetState function:
* ```ts
* import { resetState } from '@makolabs/ripple/funcs/mock-user-management';
* await resetState({ initialUsers: [...], simulateDelay: false });
* ```
*/
// Internal module-level state
let mockUsers = [];
let simulateDelay = false;
let delayMs = 300;
/**
* Reset mock adapter state
*/
export async function resetState(options = {}) {
mockUsers = options.initialUsers || [];
simulateDelay = options.simulateDelay ?? false;
delayMs = options.delayMs ?? 300;
}
async function delay() {
if (simulateDelay) {
await new Promise((resolve) => setTimeout(resolve, delayMs));
}
}
/**
* Get users with pagination and sorting
* Matches UserManagementAdapter.getUsers signature
*/
export async function getUsers(options) {
await delay();
let filteredUsers = [...mockUsers];
// Apply search query if provided
if (options.query) {
const query = options.query.toLowerCase();
filteredUsers = filteredUsers.filter((user) => user.first_name?.toLowerCase().includes(query) ||
user.last_name?.toLowerCase().includes(query) ||
user.username?.toLowerCase().includes(query) ||
user.email_addresses?.[0]?.email_address?.toLowerCase().includes(query));
}
// Apply sorting
if (options.sortBy) {
filteredUsers.sort((a, b) => {
let aValue = '';
let bValue = '';
switch (options.sortBy) {
case 'first_name':
aValue = a.first_name || '';
bValue = b.first_name || '';
break;
case 'last_name':
aValue = a.last_name || '';
bValue = b.last_name || '';
break;
case 'email_address':
aValue = a.email_addresses?.[0]?.email_address || '';
bValue = b.email_addresses?.[0]?.email_address || '';
break;
case 'created_at':
aValue = a.created_at || 0;
bValue = b.created_at || 0;
break;
case 'last_sign_in_at':
aValue = a.last_sign_in_at || 0;
bValue = b.last_sign_in_at || 0;
break;
default:
return 0;
}
if (typeof aValue === 'string' && typeof bValue === 'string') {
return options.sortOrder === 'desc'
? bValue.localeCompare(aValue)
: aValue.localeCompare(bValue);
}
else if (typeof aValue === 'number' && typeof bValue === 'number') {
return options.sortOrder === 'desc' ? bValue - aValue : aValue - bValue;
}
return 0;
});
}
// Apply pagination
const start = (options.page - 1) * options.pageSize;
const end = start + options.pageSize;
const paginatedUsers = filteredUsers.slice(start, end);
return {
users: paginatedUsers,
totalUsers: filteredUsers.length
};
}
/**
* Create a new user
* Matches UserManagementAdapter.createUser signature
*/
export async function createUser(userData) {
await delay();
const newUser = {
id: `user_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`,
first_name: userData.first_name || '',
last_name: userData.last_name || '',
username: userData.username,
email_addresses: userData.email_addresses || [{ email_address: '' }],
phone_numbers: userData.phone_numbers || [],
role: userData.role,
permissions: userData.permissions || [],
created_at: Date.now(),
...userData
};
mockUsers.push(newUser);
return newUser;
}
/**
* Update an existing user
* Matches UserManagementAdapter.updateUser signature
*/
export async function updateUser(options) {
await delay();
const { userId, userData } = options;
const userIndex = mockUsers.findIndex((u) => u.id === userId);
if (userIndex === -1) {
throw new Error(`User with ID ${userId} not found`);
}
const updatedUser = {
...mockUsers[userIndex],
...userData,
id: userId
};
mockUsers[userIndex] = updatedUser;
return updatedUser;
}
/**
* Delete a single user
* Matches UserManagementAdapter.deleteUser signature
*/
export async function deleteUser(userId) {
await delay();
const userIndex = mockUsers.findIndex((u) => u.id === userId);
if (userIndex === -1) {
throw new Error(`User with ID ${userId} not found`);
}
mockUsers.splice(userIndex, 1);
}
/**
* Delete multiple users
* Matches UserManagementAdapter.deleteUsers signature
*/
export async function deleteUsers(userIds) {
await delay();
userIds.forEach((userId) => {
const userIndex = mockUsers.findIndex((u) => u.id === userId);
if (userIndex !== -1) {
mockUsers.splice(userIndex, 1);
}
});
}
/**
* Get permissions for a specific user
* Matches UserManagementAdapter.getUserPermissions signature
*/
export async function getUserPermissions(userId) {
await delay();
const user = mockUsers.find((u) => u.id === userId);
return user?.permissions || [];
}
/**
* Update permissions for a specific user
* Matches UserManagementAdapter.updateUserPermissions signature
*/
export async function updateUserPermissions(options) {
await delay();
const { userId, permissions } = options;
const user = mockUsers.find((u) => u.id === userId);
if (!user) {
throw new Error(`User with ID ${userId} not found`);
}
user.permissions = permissions;
}
/**
* Generate API key (mock implementation)
* Matches UserManagementAdapter.generateApiKey signature
*/
export async function generateApiKey(options) {
await delay();
const { userId } = options;
const user = mockUsers.find((u) => u.id === userId);
if (!user) {
throw new Error(`User with ID ${userId} not found`);
}
const apiKey = `mock_api_key_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
if (!user.private_metadata) {
user.private_metadata = {};
}
user.private_metadata.mako_api_key = apiKey;
return {
success: true,
apiKey,
message: options.revokeOld
? 'New API key generated and old key revoked successfully'
: 'API key generated successfully'
};
}