lokalise-mcp
Version:
The Lokalise MCP Server brings Lokalise's localization power to Claude and AI assistants—manage projects, keys, and translations by chat.
206 lines (205 loc) • 8.27 kB
JavaScript
import { handleCliError } from "../../shared/utils/error.util.js";
import { Logger } from "../../shared/utils/logger.util.js";
import projectsController from "./projects.controller.js";
const logger = Logger.forContext("cli/projects.cli.ts");
/**
* Register Projects CLI commands
* @param program The Commander program instance
*/
function register(program) {
const methodLogger = logger.forMethod("register");
methodLogger.debug("Registering Projects CLI commands...");
// List Projects Command
program
.command("list-projects")
.description("Lists all Lokalise projects accessible with your API token. Shows project names, IDs, completion rates, and key statistics.")
.option("-l, --limit <number>", "Number of projects to return (1-500, default: 100)", (value) => {
const parsed = Number.parseInt(value, 10);
if (Number.isNaN(parsed) || parsed < 1 || parsed > 500) {
throw new Error("Limit must be a number between 1 and 500");
}
return parsed;
})
.option("-p, --page <number>", "Page number for pagination (default: 1)", (value) => {
const parsed = Number.parseInt(value, 10);
if (Number.isNaN(parsed) || parsed < 1) {
throw new Error("Page must be a number greater than 0");
}
return parsed;
})
.option("--include-stats", "Include detailed project statistics (keys count, languages, etc.)")
.action(async (options) => {
const actionLogger = logger.forMethod("action:list-projects");
try {
actionLogger.debug("CLI list-projects called", {
limit: options.limit,
page: options.page,
includeStats: options.includeStats,
});
// Create a single args object to pass to the controller
const args = {
limit: options.limit,
page: options.page,
includeStats: options.includeStats || false,
};
const result = await projectsController.listProjects(args);
console.log(result.content);
}
catch (error) {
handleCliError(error);
}
});
// Get Project Details Command
program
.command("get-project-details")
.description("Gets detailed information about a specific Lokalise project including languages, keys, and completion status.")
.argument("<projectId>", "Project ID to get details for")
.option("--include-languages", "Include detailed language information and completion rates")
.option("--include-keys-summary", "Include summary of keys (total, translated, missing)")
.action(async (projectId, options) => {
const actionLogger = logger.forMethod("action:get-project-details");
try {
actionLogger.debug("CLI get-project-details called", {
projectId,
options,
});
// Create a single args object to pass to the controller
const args = {
projectId,
includeLanguages: options.includeLanguages || false,
includeKeysSummary: options.includeKeysSummary || false,
};
const result = await projectsController.getProjectDetails(args);
console.log(result.content);
}
catch (error) {
handleCliError(error);
}
});
// Create Project Command
program
.command("create-project")
.description("Creates a new Lokalise project with specified settings")
.argument("<name>", "Name of the project to create")
.option("-d, --description <text>", "Optional description for the project")
.option("-l, --base-lang <iso>", "Base language ISO code (default: 'en')", "en")
.action(async (name, options) => {
const actionLogger = logger.forMethod("action:create-project");
try {
actionLogger.debug("CLI create-project called", {
name,
options,
});
const args = {
name,
description: options.description,
base_lang_iso: options.baseLang,
};
const result = await projectsController.createProject(args);
console.log(result.content);
}
catch (error) {
handleCliError(error);
}
});
// Update Project Command
program
.command("update-project")
.description("Updates an existing Lokalise project")
.argument("<projectId>", "Project ID to update")
.option("-n, --name <text>", "New project name")
.option("-d, --description <text>", "New project description")
.action(async (projectId, options) => {
const actionLogger = logger.forMethod("action:update-project");
try {
actionLogger.debug("CLI update-project called", {
projectId,
options,
});
const projectData = {};
if (options.name) {
projectData.name = options.name;
}
if (options.description) {
projectData.description = options.description;
}
if (Object.keys(projectData).length === 0) {
throw new Error("At least one field must be provided to update (name or description)");
}
const args = {
projectId,
projectData,
};
const result = await projectsController.updateProject(args);
console.log(result.content);
}
catch (error) {
handleCliError(error);
}
});
// Delete Project Command
program
.command("delete-project")
.description("Permanently deletes a Lokalise project (WARNING: This action cannot be undone!)")
.argument("<projectId>", "Project ID to delete")
.option("--confirm", "Confirm that you want to permanently delete this project")
.action(async (projectId, options) => {
const actionLogger = logger.forMethod("action:delete-project");
try {
actionLogger.debug("CLI delete-project called", {
projectId,
options,
});
if (!options.confirm) {
throw new Error("Project deletion requires confirmation. Use --confirm flag to proceed. WARNING: This action cannot be undone!");
}
const args = {
projectId,
};
const result = await projectsController.deleteProject(args);
console.log(result.content);
}
catch (error) {
handleCliError(error);
}
});
// Empty Project Command
program
.command("empty-project")
.description("Empties a Lokalise project (removes all keys and translations but keeps the project)")
.argument("<projectId>", "Project ID to empty")
.option("--confirm", "Confirm that you want to empty this project (remove all keys and translations)")
.action(async (projectId, options) => {
const actionLogger = logger.forMethod("action:empty-project");
try {
actionLogger.debug("CLI empty-project called", {
projectId,
options,
});
if (!options.confirm) {
throw new Error("Project emptying requires confirmation. Use --confirm flag to proceed. This will remove all keys and translations!");
}
const args = {
projectId,
};
const result = await projectsController.emptyProject(args);
console.log(result.content);
}
catch (error) {
handleCliError(error);
}
});
methodLogger.debug("Projects CLI commands registered successfully");
}
const projectsCli = {
register,
getMeta() {
return {
name: "projects",
description: "Projects management CLI commands",
version: "1.0.0",
cliCommandsCount: 6,
};
},
};
export default projectsCli;