/**
* {{domainNamePascal}} Service
*
* Service layer for interacting with Lokalise {{domainNamePascal}} API.
* Handles all API communication and data transformation.
*/
import type {
PaginatedResult,
// TODO: Import domain-specific SDK types here
// Check /node_modules/@lokalise/node-api/dist/main.d.ts for:
// - {{domainNamePascal}} (the main entity type)
// - {{domainNamePascal}}CreateData (for create operations)
// - {{domainNamePascal}}UpdateData (for update operations)
// Example: import type { Project, ProjectCreateData } from "@lokalise/node-api";
} from "@lokalise/node-api";
import { getLokaliseApi } from "../../shared/utils/lokalise-api.util.js";
import {
createApiError,
createUnexpectedError,
} from "../../shared/utils/error.util.js";
import { Logger } from "../../shared/utils/logger.util.js";
import type {
{{#if:list}}
List{{domainNamePascal}}ToolArgsType,
{{/if:list}}
{{#if:get}}
Get{{domainNamePascal}}ToolArgsType,
{{/if:get}}
{{#if:create}}
Add{{domainNamePascal}}ToolArgsType,
{{/if:create}}
{{#if:update}}
Update{{domainNamePascal}}ToolArgsType,
{{/if:update}}
{{#if:delete}}
Remove{{domainNamePascal}}ToolArgsType,
{{/if:delete}}
} from "./{{domainName}}.types.js";
const logger = Logger.forContext("{{domainName}}.service.ts");
// ============================================================================
// Service Implementation
// ============================================================================
/**
* {{domainNamePascal}} service for Lokalise API operations
*/
export const {{domainName}}Service = {
{{#if:list}}
/**
* List {{domainName}} for a project
*/
async list(
args: List{{domainNamePascal}}ToolArgsType,
): Promise<PaginatedResult<{{domainNamePascal}}>> {
const methodLogger = logger.forMethod("list");
methodLogger.info("Listing {{domainName}}", {
projectId: args.projectId,
page: args.page,
limit: args.limit,
});
try {
const api = getLokaliseApi();
// TODO: Replace with actual SDK method
// Example: const result = await api.{{domainName}}().list({
const result = await api.{{domainName}}().list({
project_id: args.projectId,
page: args.page,
limit: args.limit,
});
methodLogger.info("Listed {{domainName}} successfully", {
projectId: args.projectId,
count: result.items.length,
totalResults: result.totalResults,
});
return result;
} catch (error) {
methodLogger.error("Failed to list {{domainName}}", { error, args });
throw createUnexpectedError(
`Failed to list {{domainName}} for project ${args.projectId}`,
error,
);
}
},
{{/if:list}}
{{#if:get}}
/**
* Get a specific {{domainName}}
*/
async get(args: Get{{domainNamePascal}}ToolArgsType): Promise<{{domainNamePascal}}> {
const methodLogger = logger.forMethod("get");
methodLogger.info("Getting {{domainName}}", {
projectId: args.projectId,
{{domainName}}Id: args.{{domainName}}Id,
});
try {
const api = getLokaliseApi();
// TODO: Replace with actual SDK method
// Example: const result = await api.{{domainName}}().get(args.{{domainName}}Id, {
const result = await api.{{domainName}}().get(args.{{domainName}}Id, {
project_id: args.projectId,
});
methodLogger.info("Retrieved {{domainName}} successfully", {
projectId: args.projectId,
{{domainName}}Id: args.{{domainName}}Id,
});
return result;
} catch (error) {
methodLogger.error("Failed to get {{domainName}}", { error, args });
throw createUnexpectedError(
`Failed to get {{domainName}} ${args.{{domainName}}Id} from project ${args.projectId}`,
error,
);
}
},
{{/if:get}}
{{#if:create}}
/**
* Add {{domainName}} to a project
*/
async create(args: Add{{domainNamePascal}}ToolArgsType): Promise<{{domainNamePascal}}[]> {
const methodLogger = logger.forMethod("create");
methodLogger.info("Adding {{domainName}}", {
projectId: args.projectId,
count: args.{{domainName}}.length,
});
try {
const api = getLokaliseApi();
// Map our schema to SDK types
// TODO: Map the data structure to match SDK requirements
const {{domainName}}Data = args.{{domainName}}.map(
(item) => ({
// Map fields here
}),
);
// TODO: Replace with actual SDK method
// Example: const result = await api.{{domainName}}().create({{domainName}}Data, {
const result = await api.{{domainName}}().create({{domainName}}Data, {
project_id: args.projectId,
});
methodLogger.info("Added {{domainName}} successfully", {
projectId: args.projectId,
added: result.length,
});
return result;
} catch (error) {
methodLogger.error("Failed to add {{domainName}}", { error, args });
throw createUnexpectedError(
`Failed to add {{domainName}} to project ${args.projectId}`,
error,
);
}
},
{{/if:create}}
{{#if:update}}
/**
* Update a {{domainName}}
*/
async update(args: Update{{domainNamePascal}}ToolArgsType): Promise<{{domainNamePascal}}> {
const methodLogger = logger.forMethod("update");
methodLogger.info("Updating {{domainName}}", {
projectId: args.projectId,
{{domainName}}Id: args.{{domainName}}Id,
});
try {
const api = getLokaliseApi();
// Build update data
// TODO: Map update fields to SDK structure
const updateData = {
// Map fields here
};
// TODO: Replace with actual SDK method
// Example: const result = await api.{{domainName}}().update(args.{{domainName}}Id, updateData, {
const result = await api
.{{domainName}}()
.update(args.{{domainName}}Id, updateData, { project_id: args.projectId });
methodLogger.info("Updated {{domainName}} successfully", {
projectId: args.projectId,
{{domainName}}Id: args.{{domainName}}Id,
});
return result;
} catch (error) {
methodLogger.error("Failed to update {{domainName}}", { error, args });
throw createUnexpectedError(
`Failed to update {{domainName}} ${args.{{domainName}}Id} in project ${args.projectId}`,
error,
);
}
},
{{/if:update}}
{{#if:delete}}
/**
* Remove a {{domainName}} from a project
*/
async delete(
args: Remove{{domainNamePascal}}ToolArgsType,
): Promise<{ {{domainName}}_deleted: boolean; project_id: string }> {
const methodLogger = logger.forMethod("delete");
methodLogger.info("Removing {{domainName}}", {
projectId: args.projectId,
{{domainName}}Id: args.{{domainName}}Id,
});
try {
const api = getLokaliseApi();
// TODO: Replace with actual SDK method
// Example: const result = await api.{{domainName}}().delete(args.{{domainName}}Id, {
const result = await api.{{domainName}}().delete(args.{{domainName}}Id, {
project_id: args.projectId,
});
methodLogger.info("Removed {{domainName}} successfully", {
projectId: args.projectId,
{{domainName}}Id: args.{{domainName}}Id,
});
return result;
} catch (error) {
methodLogger.error("Failed to remove {{domainName}}", { error, args });
throw createUnexpectedError(
`Failed to remove {{domainName}} ${args.{{domainName}}Id} from project ${args.projectId}`,
error,
);
}
},
{{/if:delete}}
};
/**
* IMPLEMENTATION GUIDE:
*
* 1. Check the Lokalise SDK types in /node_modules/@lokalise/node-api/dist/main.d.ts
* 2. Look for the {{domainName}} interface and related types
* 3. Import the correct types at the top of this file
* 4. Replace api.{{domainName}}() with the actual SDK method if different (e.g., api.contributors())
* 5. Map your Zod schema types to SDK types in create/update methods
* 6. Check /node_modules/@lokalise/node-api/docs/api/{{domainName}}.md for examples
*
* Common SDK patterns:
* - List methods return PaginatedResult<T>
* - Create methods often accept arrays and return arrays
* - Update/delete methods return the modified object or confirmation
* - All methods require { project_id } in options
*/