@oxyhq/services
Version:
Reusable OxyHQ module to handle authentication, user management, karma system, device-based session management and more 🚀
388 lines (361 loc) • 10.6 kB
JavaScript
"use strict";
/**
* User Management Methods Mixin
*/
import { buildSearchParams, buildPaginationParams } from '../../utils/apiUtils';
export function OxyServicesUserMixin(Base) {
return class extends Base {
constructor(...args) {
super(...args);
}
/**
* Get profile by username
*/
async getProfileByUsername(username) {
try {
return await this.makeRequest('GET', `/api/profiles/username/${username}`, undefined, {
cache: true,
cacheTTL: 5 * 60 * 1000 // 5 minutes cache for profiles
});
} catch (error) {
throw this.handleError(error);
}
}
/**
* Search user profiles
*/
async searchProfiles(query, pagination) {
try {
const params = {
query,
...pagination
};
const searchParams = buildSearchParams(params);
const paramsObj = Object.fromEntries(searchParams.entries());
const response = await this.makeRequest('GET', '/api/profiles/search', paramsObj, {
cache: true,
cacheTTL: 2 * 60 * 1000 // 2 minutes cache
});
// New API shape: { data: User[], pagination: {...} }
const isSearchProfilesResponse = payload => typeof payload === 'object' && payload !== null && Array.isArray(payload.data);
if (isSearchProfilesResponse(response)) {
const typedResponse = response;
const paginationInfo = typedResponse.pagination ?? {
total: typedResponse.data.length,
limit: pagination?.limit ?? typedResponse.data.length,
offset: pagination?.offset ?? 0,
hasMore: typedResponse.data.length === (pagination?.limit ?? typedResponse.data.length) && (pagination?.limit ?? typedResponse.data.length) > 0
};
return {
data: typedResponse.data,
pagination: paginationInfo
};
}
// Legacy API shape: returns raw User[]
if (Array.isArray(response)) {
const fallbackLimit = pagination?.limit ?? response.length;
const fallbackPagination = {
total: response.length,
limit: fallbackLimit,
offset: pagination?.offset ?? 0,
hasMore: fallbackLimit > 0 && response.length === fallbackLimit
};
return {
data: response,
pagination: fallbackPagination
};
}
// If response is unexpected, throw an error
throw new Error('Unexpected search response format');
} catch (error) {
throw this.handleError(error);
}
}
/**
* Get profile recommendations
*/
async getProfileRecommendations() {
return this.withAuthRetry(async () => {
return await this.makeRequest('GET', '/api/profiles/recommendations', undefined, {
cache: true
});
}, 'getProfileRecommendations');
}
/**
* Get user by ID
*/
async getUserById(userId) {
try {
return await this.makeRequest('GET', `/api/users/${userId}`, undefined, {
cache: true,
cacheTTL: 5 * 60 * 1000 // 5 minutes cache
});
} catch (error) {
throw this.handleError(error);
}
}
/**
* Get current user
*/
async getCurrentUser() {
return this.withAuthRetry(async () => {
return await this.makeRequest('GET', '/api/users/me', undefined, {
cache: true,
cacheTTL: 1 * 60 * 1000 // 1 minute cache for current user
});
}, 'getCurrentUser');
}
/**
* Update user profile
*/
async updateProfile(updates) {
try {
return await this.makeRequest('PUT', '/api/users/me', updates, {
cache: false
});
} catch (error) {
throw this.handleError(error);
}
}
/**
* Get privacy settings for a user
* @param userId - The user ID (defaults to current user)
*/
async getPrivacySettings(userId) {
try {
const id = userId || (await this.getCurrentUser()).id;
return await this.makeRequest('GET', `/api/privacy/${id}/privacy`, undefined, {
cache: true,
cacheTTL: 2 * 60 * 1000 // 2 minutes cache
});
} catch (error) {
throw this.handleError(error);
}
}
/**
* Update privacy settings
* @param settings - Partial privacy settings object
* @param userId - The user ID (defaults to current user)
*/
async updatePrivacySettings(settings, userId) {
try {
const id = userId || (await this.getCurrentUser()).id;
return await this.makeRequest('PATCH', `/api/privacy/${id}/privacy`, settings, {
cache: false
});
} catch (error) {
throw this.handleError(error);
}
}
/**
* Request account verification
*/
async requestAccountVerification(reason, evidence) {
try {
return await this.makeRequest('POST', '/api/users/verify/request', {
reason,
evidence
}, {
cache: false
});
} catch (error) {
throw this.handleError(error);
}
}
/**
* Download account data export
*/
async downloadAccountData(format = 'json') {
try {
// Use httpService for blob responses (it handles blob responses automatically)
const result = await this.getClient().request({
method: 'GET',
url: `/api/users/me/data`,
params: {
format
},
cache: false
});
return result;
} catch (error) {
throw this.handleError(error);
}
}
/**
* Delete account permanently
* @param password - User password for confirmation
* @param confirmText - Confirmation text (usually username)
*/
async deleteAccount(password, confirmText) {
try {
return await this.makeRequest('DELETE', '/api/users/me', {
password,
confirmText
}, {
cache: false
});
} catch (error) {
throw this.handleError(error);
}
}
/**
* Update user by ID (admin function)
*/
async updateUser(userId, updates) {
try {
return await this.makeRequest('PUT', `/api/users/${userId}`, updates, {
cache: false
});
} catch (error) {
throw this.handleError(error);
}
}
/**
* Follow a user
*/
async followUser(userId) {
try {
return await this.makeRequest('POST', `/api/users/${userId}/follow`, undefined, {
cache: false
});
} catch (error) {
throw this.handleError(error);
}
}
/**
* Unfollow a user
*/
async unfollowUser(userId) {
try {
return await this.makeRequest('DELETE', `/api/users/${userId}/follow`, undefined, {
cache: false
});
} catch (error) {
throw this.handleError(error);
}
}
/**
* Get follow status
*/
async getFollowStatus(userId) {
try {
return await this.makeRequest('GET', `/api/users/${userId}/follow-status`, undefined, {
cache: true,
cacheTTL: 1 * 60 * 1000 // 1 minute cache
});
} catch (error) {
throw this.handleError(error);
}
}
/**
* Get user followers
*/
async getUserFollowers(userId, pagination) {
try {
const params = buildPaginationParams(pagination || {});
const response = await this.makeRequest('GET', `/api/users/${userId}/followers`, params, {
cache: true,
cacheTTL: 2 * 60 * 1000 // 2 minutes cache
});
return {
followers: response.data || [],
total: response.pagination.total,
hasMore: response.pagination.hasMore
};
} catch (error) {
throw this.handleError(error);
}
}
/**
* Get user following
*/
async getUserFollowing(userId, pagination) {
try {
const params = buildPaginationParams(pagination || {});
const response = await this.makeRequest('GET', `/api/users/${userId}/following`, params, {
cache: true,
cacheTTL: 2 * 60 * 1000 // 2 minutes cache
});
return {
following: response.data || [],
total: response.pagination.total,
hasMore: response.pagination.hasMore
};
} catch (error) {
throw this.handleError(error);
}
}
/**
* Get notifications
*/
async getNotifications() {
return this.withAuthRetry(async () => {
return await this.makeRequest('GET', '/api/notifications', undefined, {
cache: false // Don't cache notifications - always get fresh data
});
}, 'getNotifications');
}
/**
* Get unread notification count
*/
async getUnreadCount() {
try {
const res = await this.makeRequest('GET', '/api/notifications/unread-count', undefined, {
cache: false // Don't cache unread count - always get fresh data
});
return res.count;
} catch (error) {
throw this.handleError(error);
}
}
/**
* Create notification
*/
async createNotification(data) {
try {
return await this.makeRequest('POST', '/api/notifications', data, {
cache: false
});
} catch (error) {
throw this.handleError(error);
}
}
/**
* Mark notification as read
*/
async markNotificationAsRead(notificationId) {
try {
await this.makeRequest('PUT', `/api/notifications/${notificationId}/read`, undefined, {
cache: false
});
} catch (error) {
throw this.handleError(error);
}
}
/**
* Mark all notifications as read
*/
async markAllNotificationsAsRead() {
try {
await this.makeRequest('PUT', '/api/notifications/read-all', undefined, {
cache: false
});
} catch (error) {
throw this.handleError(error);
}
}
/**
* Delete notification
*/
async deleteNotification(notificationId) {
try {
await this.makeRequest('DELETE', `/api/notifications/${notificationId}`, undefined, {
cache: false
});
} catch (error) {
throw this.handleError(error);
}
}
};
}
//# sourceMappingURL=OxyServices.user.js.map