UNPKG

@minecraft/creator-tools

Version:

Minecraft Creator Tools command line and libraries.

189 lines (188 loc) 6.25 kB
"use strict"; // Copyright (c) Microsoft Corporation. // Licensed under the MIT License. Object.defineProperty(exports, "__esModule", { value: true }); exports.ToolCommandRegistry = void 0; const ToolCommandParser_1 = require("./ToolCommandParser"); /** * Central registry for ToolCommands. */ class ToolCommandRegistry { static _instance; commands = new Map(); /** * Get the singleton instance. */ static get instance() { if (!this._instance) { this._instance = new ToolCommandRegistry(); } return this._instance; } /** * Register a ToolCommand. * @param command The command to register */ register(command) { const { name, aliases } = command.metadata; // Register by name (lowercase for case-insensitive lookup) const lowerName = name.toLowerCase(); if (this.commands.has(lowerName)) { throw new Error(`ToolCommand '${name}' is already registered`); } this.commands.set(lowerName, command); // Register aliases if (aliases) { for (const alias of aliases) { const lowerAlias = alias.toLowerCase(); if (this.commands.has(lowerAlias)) { throw new Error(`ToolCommand alias '${alias}' conflicts with existing command`); } this.commands.set(lowerAlias, command); } } } /** * Register multiple commands. */ registerAll(commands) { for (let i = 0; i < commands.length; i++) { const command = commands[i]; if (!command) { throw new Error(`ToolCommand at index ${i} is undefined or null (out of ${commands.length} commands)`); } this.register(command); } } /** * Get a command by name or alias. * @param name Command name or alias (case-insensitive) */ get(name) { return this.commands.get(name.toLowerCase()); } /** * Check if a command exists. */ has(name) { return this.commands.has(name.toLowerCase()); } /** * Get all unique commands (excluding alias duplicates). * Optionally filter by scope. */ getAll(scope) { const seen = new Set(); const result = []; for (const command of this.commands.values()) { if (seen.has(command)) continue; seen.add(command); // Filter by scope if specified if (scope) { const scopes = command.metadata.scopes; // If no scopes defined, command is available everywhere if (scopes && !scopes.includes(scope)) { continue; } } result.push(command); } // Sort by category then name result.sort((a, b) => { const catCmp = a.metadata.category.localeCompare(b.metadata.category); if (catCmp !== 0) return catCmp; return a.metadata.name.localeCompare(b.metadata.name); }); return result; } /** * Get all command names (for autocomplete). */ getCommandNames(scope) { return this.getAll(scope).map((c) => c.metadata.name); } /** * Execute a command from a command string. * @param commandText Full command text (e.g., "/create template myproject --traits mob") * @param context Execution context * @returns Command result, or undefined if command not found */ async execute(commandText, context) { const parsed = ToolCommandParser_1.ToolCommandParser.parse(commandText); if (!parsed) { return undefined; } return this.executeCommand(parsed.commandName, parsed.args, parsed.flags, context); } /** * Execute a command with pre-parsed arguments. */ async executeCommand(name, args, flags, context) { const command = this.get(name); if (!command) { return undefined; } // Check scope restrictions const scopes = command.metadata.scopes; if (scopes && !scopes.includes(context.scope)) { return { success: false, error: { code: "SCOPE_RESTRICTED", message: `Command '${name}' is not available in ${context.scope} context`, }, }; } // Check project requirement if (command.metadata.requiresProject && !context.project) { return { success: false, error: { code: "PROJECT_REQUIRED", message: `Command '${name}' requires an active project`, }, }; } // Check Minecraft requirement if (command.metadata.requiresMinecraft && !context.minecraft) { return { success: false, error: { code: "MINECRAFT_REQUIRED", message: `Command '${name}' requires an active Minecraft server connection`, }, }; } try { return await command.execute(context, args, flags); } catch (error) { const message = error instanceof Error ? error.message : String(error); return { success: false, error: { code: "EXECUTION_ERROR", message: `Error executing '${name}': ${message}`, }, }; } } /** * Get autocomplete suggestions for a partial command. * @param text The partial command text being typed * @param cursorPos The cursor position in the text * @param context Execution context */ async getCompletions(text, cursorPos, context) { return ToolCommandParser_1.ToolCommandParser.getCompletions(text, cursorPos, this, context); } /** * Clear all registered commands (for testing). */ clear() { this.commands.clear(); } } exports.ToolCommandRegistry = ToolCommandRegistry;