import fetch from "node-fetch";
import {
VerblazeApiResponse,
TranslateValuesParams,
AddLanguageParams,
RemoveLanguageParams,
AddScreenParams,
RemoveScreenParams,
DeleteValueParams,
ChangeBaseLanguageParams,
ListLanguagesParams,
ListScreensParams,
GetScreenValuesParams,
TranslationResponse,
Language,
TranslationValue,
ListLanguagesResponse,
ListScreensResponse,
GetScreenValuesResponse,
} from "../types/index.js";
export class VerblazeApiService {
private baseUrl: string;
private apiKey: string;
constructor() {
this.baseUrl = process.env.VERBLAZE_API_URL || "https://api.verblaze.com";
this.apiKey = process.env.VERBLAZE_API_KEY || "";
if (!this.apiKey) {
throw new Error("VERBLAZE_API_KEY environment variable is required");
}
}
private async makeRequest<T>(
endpoint: string,
method: string = "POST",
body?: any
): Promise<VerblazeApiResponse<T>> {
try {
const response = await fetch(`${this.baseUrl}/api/mcp${endpoint}`, {
method,
headers: {
"Content-Type": "application/json",
"X-API-Key": this.apiKey,
},
body: body ? JSON.stringify(body) : undefined,
});
if (!response.ok) {
const errorText = await response.text();
throw new Error(
`API request failed (${response.status}): ${errorText}`
);
}
const data = (await response.json()) as VerblazeApiResponse<T>;
return data;
} catch (error) {
throw new Error(
`Failed to make request to ${endpoint}: ${
error instanceof Error ? error.message : "Unknown error"
}`
);
}
}
async translateValues(
params: Omit<TranslateValuesParams, "apiKey" | "projectId">
): Promise<TranslationResponse> {
const response = await this.makeRequest<TranslationResponse>(
"/translate-values",
"POST",
params
);
// Backend returns the data directly in the response, not nested under 'data'
return response as any;
}
async addLanguage(
params: Omit<AddLanguageParams, "apiKey" | "projectId">
): Promise<Language> {
const response = await this.makeRequest<Language>(
"/add-language",
"POST",
params
);
// Backend returns the data directly in the response, not nested under 'data'
return response as any;
}
async removeLanguage(
params: Omit<RemoveLanguageParams, "apiKey" | "projectId">
): Promise<void> {
const response = await this.makeRequest<void>(
"/remove-language",
"POST",
params
);
// Backend returns the data directly in the response, not nested under 'data'
return response as any;
}
async addScreen(
params: Omit<AddScreenParams, "apiKey" | "projectId">
): Promise<{ fileKey: string; fileTitle?: string }> {
const response = await this.makeRequest<{
fileKey: string;
fileTitle?: string;
}>("/add-screen", "POST", params);
// Backend returns the data directly in the response, not nested under 'data'
return response as any;
}
async removeScreen(
params: Omit<RemoveScreenParams, "apiKey" | "projectId">
): Promise<{ fileKey: string; deletedCount: number }> {
const response = await this.makeRequest<{
fileKey: string;
deletedCount: number;
}>("/remove-screen", "POST", params);
// Backend returns the data directly in the response, not nested under 'data'
return response as any;
}
async deleteValue(
params: Omit<DeleteValueParams, "apiKey" | "projectId">
): Promise<{
fileKey: string;
valueKey: string;
deletedCount: number;
}> {
const response = await this.makeRequest<{
fileKey: string;
valueKey: string;
deletedCount: number;
}>("/delete-value", "POST", params);
// Backend returns the data directly in the response, not nested under 'data'
return response as any;
}
async changeBaseLanguage(
params: Omit<ChangeBaseLanguageParams, "apiKey" | "projectId">
): Promise<{ newBaseLanguage: Language }> {
const response = await this.makeRequest<{ newBaseLanguage: Language }>(
"/change-base-language",
"POST",
params
);
// Backend returns the data directly in the response, not nested under 'data'
return response as any;
}
// New read-only methods
async listLanguages(): Promise<ListLanguagesResponse> {
const response = await this.makeRequest<ListLanguagesResponse>(
"/list-languages",
"POST"
);
// Backend returns the data directly in the response, not nested under 'data'
return response as any;
}
async listScreens(): Promise<ListScreensResponse> {
const response = await this.makeRequest<ListScreensResponse>(
"/list-screens",
"POST"
);
// Backend returns the data directly in the response, not nested under 'data'
return response as any;
}
async getScreenValues(
params: Omit<GetScreenValuesParams, "apiKey" | "projectId">
): Promise<GetScreenValuesResponse> {
const response = await this.makeRequest<GetScreenValuesResponse>(
"/get-screen-values",
"POST",
params
);
// Backend returns the data directly in the response, not nested under 'data'
return response as any;
}
}