@smartsamurai/krapi-sdk
Version:
KRAPI TypeScript SDK - Easy-to-use client SDK for connecting to self-hosted KRAPI servers (like Appwrite SDK)
150 lines (138 loc) • 4.99 kB
text/typescript
/**
* Admin Adapter
*
* Unifies AdminHttpClient and AdminService behind a common interface.
*/
import { AdminService, AdminUser as ServiceAdminUser } from "../../admin-service";
import { AdminHttpClient } from "../../http-clients/admin-http-client";
import { AdminUser } from "../../types";
import { createAdapterInitError } from "./error-handler";
type Mode = "client" | "server";
export class AdminAdapter {
private mode: Mode;
private httpClient: AdminHttpClient | undefined;
private service: AdminService | undefined;
constructor(mode: Mode, httpClient?: AdminHttpClient, service?: AdminService) {
this.mode = mode;
this.httpClient = httpClient;
this.service = service;
}
async getAllUsers(options?: {
limit?: number;
offset?: number;
search?: string;
role?: string;
status?: string;
project_id?: string;
}): Promise<AdminUser[]> {
if (this.mode === "client") {
if (!this.httpClient) {
throw createAdapterInitError("HTTP client", this.mode);
}
const response = await this.httpClient.getAllUsers(options);
const data = response.data;
if (data && "data" in data) {
return (data.data as AdminUser[]) || [];
}
return (data as unknown as AdminUser[]) || [];
} else {
if (!this.service) {
throw createAdapterInitError("Admin service", this.mode);
}
const users = await this.service.getUsers(options);
return (users as unknown as AdminUser[]) || [];
}
}
async getUser(userId: string): Promise<AdminUser> {
if (this.mode === "client") {
if (!this.httpClient) {
throw createAdapterInitError("HTTP client", this.mode);
}
const response = await this.httpClient.getUser(userId);
return (response.data as unknown as AdminUser) || ({} as AdminUser);
} else {
if (!this.service) {
throw createAdapterInitError("Admin service", this.mode);
}
const user = await this.service.getUserById(userId);
return (user as unknown as AdminUser) || ({} as AdminUser);
}
}
async createUser(userData: {
username: string;
email: string;
password: string;
first_name?: string;
last_name?: string;
role: "admin" | "user";
project_id?: string;
permissions?: string[];
metadata?: Record<string, unknown>;
}): Promise<AdminUser> {
if (this.mode === "client") {
if (!this.httpClient) {
throw createAdapterInitError("HTTP client", this.mode);
}
const response = await this.httpClient.createUser(userData);
return (response.data as unknown as AdminUser) || ({} as AdminUser);
} else {
if (!this.service) {
throw createAdapterInitError("Admin service", this.mode);
}
// Service expects Omit<AdminUser, "id" | "created_at" | "updated_at">
// But we're passing userData which has password, not password_hash
// The service expects password_hash to be required
const serviceUserData: Omit<ServiceAdminUser, "id" | "created_at" | "updated_at"> = {
username: userData.username,
email: userData.email,
password_hash: userData.password, // Service should hash this, but expects it as-is for now
role: userData.role,
access_level: userData.role === "admin" ? "admin" : "user",
permissions: userData.permissions || [],
active: true,
};
const user = await this.service.createUser(serviceUserData);
return (user as unknown as AdminUser) || ({} as AdminUser);
}
}
async updateUser(userId: string, updates: Partial<{
username: string;
email: string;
first_name: string;
last_name: string;
role: "admin" | "user";
is_active: boolean;
permissions: string[];
metadata: Record<string, unknown>;
}>): Promise<AdminUser> {
if (this.mode === "client") {
if (!this.httpClient) {
throw createAdapterInitError("HTTP client", this.mode);
}
const response = await this.httpClient.updateUser(userId, updates);
return (response.data as unknown as AdminUser) || ({} as AdminUser);
} else {
if (!this.service) {
throw createAdapterInitError("Admin service", this.mode);
}
const user = await this.service.updateUser(userId, updates);
return (user as unknown as AdminUser) || ({} as AdminUser);
}
}
async deleteUser(userId: string): Promise<{ success: boolean }> {
if (this.mode === "client") {
if (!this.httpClient) {
throw createAdapterInitError("HTTP client", this.mode);
}
const response = await this.httpClient.deleteUser(userId);
return response.data || { success: false };
} else {
if (!this.service) {
throw createAdapterInitError("Admin service", this.mode);
}
const success = await this.service.deleteUser(userId);
return { success };
}
}
// Additional admin methods can be added here as needed
}