UNPKG

@minecraft/creator-tools

Version:

Minecraft Creator Tools command line and libraries.

171 lines (170 loc) 7.23 kB
"use strict"; // Copyright (c) Microsoft Corporation. // Licensed under the MIT License. var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); const Database_1 = __importDefault(require("../minecraft/Database")); const Utilities_1 = __importDefault(require("../core/Utilities")); /** * Utility class for managing info generator topic data from form.json files. * Topic metadata (titles, descriptions, updaters) is stored in form.json files * in the public/data/forms/mctoolsval/ folder, with each generator having its own form file. */ class InfoGeneratorTopicUtilities { static _topicFormsByGeneratorId = {}; static _loadingPromises = {}; /** * Gets topic data for a specific generator and topic ID from form.json files. * Returns undefined if no form file exists for the generator or if the topic is not found. * @param generatorId The ID of the generator (e.g., "CADDONREQ", "MCFUNCTION") * @param topicId The numeric topic ID (typically from an enum like 101, 102, etc.) * @returns The topic data including title and optional updaters, or undefined if not found */ static async getTopicData(generatorId, topicId) { const form = await this.ensureFormLoaded(generatorId); if (!form) { return undefined; } return this.getTopicDataFromForm(form, topicId); } /** * Gets topic data synchronously from already-loaded form data. * Returns undefined if the form hasn't been loaded yet or if the topic is not found. * @param generatorId The ID of the generator * @param topicId The numeric topic ID * @returns The topic data or undefined */ static getTopicDataSync(generatorId, topicId) { const normalizedId = generatorId.toLowerCase(); const form = this._topicFormsByGeneratorId[normalizedId]; if (!form || form === null) { return undefined; } return this.getTopicDataFromForm(form, topicId); } /** * Extracts topic data from a form definition for a given topic ID. * For summary items (topicId 0 or 1), returns the form's root title/description if no specific field is found. */ static getTopicDataFromForm(form, topicId) { if (!form.fields) { // If no fields but we have form-level title, return it for summary items if ((topicId === 0 || topicId === 1) && form.title) { return { title: form.title, description: form.description, }; } return undefined; } const topicIdStr = topicId.toString(); for (const field of form.fields) { if (field.id === topicIdStr) { const result = { title: field.title || Utilities_1.default.humanifyJsName(field.id || ""), }; // Extract description, howToUse, and technicalDescription if present if (field.description) { result.description = field.description; } if (field.howToUse) { result.howToUse = field.howToUse; } if (field.technicalDescription) { result.technicalDescription = field.technicalDescription; } // Extract suggestedLineToken for diagnostic line location hints if (field.suggestedLineToken) { result.suggestedLineToken = field.suggestedLineToken; } // Extract suggestedLineShouldHaveData for data-based line matching if (field.suggestedLineShouldHaveData) { result.suggestedLineShouldHaveData = field.suggestedLineShouldHaveData; } // Extract updaters from field metadata if present if (field.matchedValues && Array.isArray(field.matchedValues)) { const updaters = []; for (const val of field.matchedValues) { if (val && typeof val === "object" && "updaterId" in val) { updaters.push(val); } } if (updaters.length > 0) { result.updaters = updaters; } } return result; } } // For summary items (topicId 0 or 1 - fail/success), return the form's root title if available if ((topicId === 0 || topicId === 1) && form.title) { return { title: form.title, description: form.description, }; } return undefined; } /** * Ensures that the form.json file for a generator is loaded. * @param generatorId The ID of the generator * @returns The form definition or undefined if not found */ static async ensureFormLoaded(generatorId) { const normalizedId = generatorId.toLowerCase(); // Check if already loaded (null means "checked and not found") if (normalizedId in this._topicFormsByGeneratorId) { return this._topicFormsByGeneratorId[normalizedId] ?? undefined; } // Check if currently loading const loadingPromise = this._loadingPromises[normalizedId]; if (loadingPromise) { const result = await loadingPromise; return result ?? undefined; } // Start loading this._loadingPromises[normalizedId] = this.loadForm(normalizedId); const form = await this._loadingPromises[normalizedId]; // Cache result: store null for missing forms to avoid re-fetching this._topicFormsByGeneratorId[normalizedId] = form ?? null; delete this._loadingPromises[normalizedId]; return form ?? undefined; } /** * Loads a form.json file for a generator. */ static async loadForm(generatorId) { try { const form = await Database_1.default.ensureFormLoaded("mctoolsval", generatorId); return form ?? null; } catch { // Form file doesn't exist for this generator - that's OK return null; } } /** * Checks if a form is loaded for a generator. */ static isFormLoaded(generatorId) { return this._topicFormsByGeneratorId[generatorId.toLowerCase()] !== undefined; } /** * Preloads forms for all known generators. * This can be called at startup to ensure all forms are available synchronously later. */ static async preloadAllForms(generatorIds) { const loadPromises = generatorIds.map((id) => this.ensureFormLoaded(id)); await Promise.all(loadPromises); } /** * Clears all cached forms. Useful for testing or hot-reloading. */ static clearCache() { this._topicFormsByGeneratorId = {}; this._loadingPromises = {}; } } exports.default = InfoGeneratorTopicUtilities;