@minecraft/creator-tools
Version:
Minecraft Creator Tools command line and libraries.
850 lines (848 loc) • 44.8 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.ExportMode = exports.MarkdownTop = void 0;
const Utilities_1 = require("../core/Utilities");
const StorageUtilities_1 = require("../storage/StorageUtilities");
const DataFormUtilities_1 = require("../dataform/DataFormUtilities");
const IField_1 = require("../dataform/IField");
const EntityTypeDefinition_1 = require("../minecraft/EntityTypeDefinition");
const Database_1 = require("../minecraft/Database");
const ICondition_1 = require("../dataform/ICondition");
exports.MarkdownTop = `---
author: mammerla
ms.author: mikeam
title: "{0}"
description: "{1}"
ms.service: minecraft-bedrock-edition
ms.date: 02/11/2025
---
`;
var ExportMode;
(function (ExportMode) {
ExportMode[ExportMode["other"] = 0] = "other";
ExportMode[ExportMode["triggers"] = 1] = "triggers";
ExportMode[ExportMode["blockComponents"] = 2] = "blockComponents";
ExportMode[ExportMode["itemComponents"] = 3] = "itemComponents";
ExportMode[ExportMode["entityComponents"] = 4] = "entityComponents";
ExportMode[ExportMode["AIGoals"] = 5] = "AIGoals";
ExportMode[ExportMode["visuals"] = 6] = "visuals";
ExportMode[ExportMode["fogs"] = 7] = "fogs";
ExportMode[ExportMode["websockets"] = 8] = "websockets";
ExportMode[ExportMode["filters"] = 9] = "filters";
ExportMode[ExportMode["MCToolsVal"] = 10] = "MCToolsVal";
ExportMode[ExportMode["eventResponses"] = 11] = "eventResponses";
ExportMode[ExportMode["clientBiomes"] = 12] = "clientBiomes";
ExportMode[ExportMode["biomes"] = 13] = "biomes";
ExportMode[ExportMode["features"] = 14] = "features";
ExportMode[ExportMode["featureCore"] = 15] = "featureCore";
ExportMode[ExportMode["deferredRendering"] = 16] = "deferredRendering";
})(ExportMode = exports.ExportMode || (exports.ExportMode = {}));
class FormMarkdownDocumentationGenerator {
async generateMarkdown(formJsonInputFolder, outputFolder) {
const formsByPath = {};
await this.loadFormJsonFromFolder(formsByPath, formJsonInputFolder, outputFolder);
this.exportMarkdownCatalogDocs(formsByPath, outputFolder, ExportMode.features, "/FeaturesReference/Examples/Features/", "/features/minecraft_", "Feature", "Feature Type");
this.exportMarkdownDocListPage(formsByPath, outputFolder, ExportMode.entityComponents, "/FeaturesReference/Examples/FeatureList.md", "/features/minecraft_", "Features", "Features");
this.exportMarkdownCatalogDocs(formsByPath, outputFolder, ExportMode.featureCore, "/FeaturesReference/Examples/Features/", "/feature/", "Feature", "Feature Type");
this.exportListYml(formsByPath, outputFolder, ExportMode.entityComponents, "/FeaturesReference/Examples/Features/TOC.yml", "/features/minecraft_", "- name: Features List\r\n href: ../FeatureList.md", "minecraft_");
this.exportMarkdownCatalogDocs(formsByPath, outputFolder, ExportMode.AIGoals, "/EntityReference/Examples/EntityGoals/", "/entity/minecraft_behavior", "Entity", "AI Behavior Component");
this.exportMarkdownCatalogDocs(formsByPath, outputFolder, ExportMode.visuals, "/VisualReference/", "/visual/", "Visuals", "Visual Element");
this.exportMarkdownCatalogDocs(formsByPath, outputFolder, ExportMode.fogs, "/FogsReference/", "/fogs/", "Fogs", "Fog Element");
this.exportMarkdownCatalogDocs(formsByPath, outputFolder, ExportMode.websockets, "/WebsocketsReference/", "/websockets/", "Websockets", "Websocket Packet");
this.exportValidatorMarkdownCatalogDocs(formsByPath, outputFolder, ExportMode.MCToolsVal, "/MCToolsValReference/", "/mctoolsval/", "MCTools Validation Rules", "MCTools Validation Rules");
this.exportMarkdownCatalogDocs(formsByPath, outputFolder, ExportMode.triggers, "/EntityReference/Examples/EntityTriggers/", "/entity/minecraft_on", "Entity", "Entity Trigger");
this.exportMarkdownCatalogDocs(formsByPath, outputFolder, ExportMode.filters, "/EntityReference/Examples/Filters/", "/entityfilters/", "Entity Filters", "Entity Filter Element");
this.exportMarkdownCatalogDocs(formsByPath, outputFolder, ExportMode.eventResponses, "/EntityReference/Examples/EventActions/", "/entityevents/", "Entity Actions", "Entity Action Types");
this.exportMarkdownCatalogDocs(formsByPath, outputFolder, ExportMode.blockComponents, "/BlockReference/Examples/BlockComponents/", "/block/minecraft_", "Block Components", "Block Component");
this.exportMarkdownCatalogDocs(formsByPath, outputFolder, ExportMode.itemComponents, "/ItemReference/Examples/ItemComponents/", "/item/minecraft_", "Items", "Item Component");
this.exportMarkdownCatalogDocs(formsByPath, outputFolder, ExportMode.entityComponents, "/EntityReference/Examples/EntityComponents/", "/entity/minecraft_", "Entity", "Entity Component");
this.exportMarkdownCatalogDocs(formsByPath, outputFolder, ExportMode.deferredRendering, "/DeferredRendering/", "/client_deferred_rendering/", "Deferred Rendering", "Deferred Rendering");
this.exportMarkdownCatalogDocs(formsByPath, outputFolder, ExportMode.clientBiomes, "/ClientBiomesReference/Examples/Components/", "/client_biome/", "Client Biome", "Client Biome");
this.exportMarkdownCatalogDocs(formsByPath, outputFolder, ExportMode.biomes, "/BiomesReference/Examples/Components/", "/biome/", "Biome", "Biome");
this.exportMarkdownDocListPage(formsByPath, outputFolder, ExportMode.entityComponents, "/EntityReference/Examples/ComponentList.md", "/entity/minecraft_", "Entity Components", "EntityComponents");
this.exportListYml(formsByPath, outputFolder, ExportMode.entityComponents, "/EntityReference/Examples/EntityComponents/TOC.yml", "/entity/minecraft_", "- name: Components List\r\n href: ../ComponentList.md", "minecraftComponent_");
this.exportMarkdownDocListPage(formsByPath, outputFolder, ExportMode.triggers, "/EntityReference/Examples/TriggerList.md", "/entity/minecraft_on", "Entity Triggers", "EntityTriggers");
this.exportListYml(formsByPath, outputFolder, ExportMode.entityComponents, "/EntityReference/Examples/EntityTriggers/TOC.yml", "/entity/minecraft_on", "- name: Triggers List\r\n href: ../TriggerList.md", "minecraftTrigger_");
this.exportMarkdownDocListPage(formsByPath, outputFolder, ExportMode.AIGoals, "/EntityReference/Examples/AIGoalList.md", "/entity/minecraft_behavior", "Entity Behavior (AI) Components", "EntityGoals");
this.exportListYml(formsByPath, outputFolder, ExportMode.AIGoals, "/EntityReference/Examples/EntityGoals/TOC.yml", "/entity/minecraft_behavior", "- name: AI Component List\r\n href: ../AIGoalList.md");
this.exportMarkdownDocListPage(formsByPath, outputFolder, ExportMode.filters, "/EntityReference/Examples/FilterList.md", "/entityfilters/", "Entity Filter Types", "Filters");
this.exportListYml(formsByPath, outputFolder, ExportMode.filters, "/EntityReference/Examples/Filters/TOC.yml", "/entityfilters/", "- name: Entity Filter List\r\n href: ../FilterList.md");
this.exportMarkdownDocListPage(formsByPath, outputFolder, ExportMode.eventResponses, "/EntityReference/Examples/EventActions.md", "/entityevents/", "Event Actions", "EventActions");
this.exportListYml(formsByPath, outputFolder, ExportMode.eventResponses, "/EntityReference/Examples/EventActions/TOC.yml", "/entityevents/", "- name: Entity Event List\r\n href: ../EventActions.md");
}
getFileNameFromBaseName(baseName, exportMode) {
let fileName = baseName;
if (exportMode === ExportMode.triggers && fileName.startsWith("minecraft_on_")) {
fileName = "minecraftTrigger_" + baseName.substring(10);
}
else if (exportMode === ExportMode.triggers && fileName.startsWith("minecraft_on_")) {
fileName = "minecraftTrigger_" + baseName.substring(10);
}
else if (exportMode === ExportMode.AIGoals && fileName.startsWith("minecraft_behavior")) {
fileName = "minecraftB" + baseName.substring(11);
}
else if (exportMode === ExportMode.entityComponents && fileName.startsWith("minecraft_")) {
fileName = "minecraftComponent_" + baseName.substring(10);
}
else if (exportMode === ExportMode.blockComponents && fileName.startsWith("minecraft_")) {
fileName = "minecraftBlock_" + baseName.substring(10);
}
else if (exportMode === ExportMode.itemComponents && fileName.startsWith("minecraft_")) {
fileName = "minecraft_" + baseName.substring(10);
}
else if (exportMode === ExportMode.clientBiomes && fileName.startsWith("minecraft_")) {
fileName = "minecraftClientBiomes_" + baseName.substring(10);
}
else if (exportMode === ExportMode.biomes && fileName.startsWith("minecraft_")) {
fileName = "minecraftBiomes_" + baseName.substring(10);
}
fileName = fileName.replace("_horse_", "_horse.");
fileName = fileName.replace("_jump_", "_jump.");
if (fileName.indexOf("movement_tracking") < 0) {
fileName = fileName.replace("_movement_", "_movement.");
}
fileName = fileName.replace("_navigation_", "_navigation.");
fileName = fileName.replace("_player_", "_player.");
return fileName;
}
async exportMarkdownAggregatedPage(formsByPath, outputFolder, exportMode, filePath, formsPath, category, categoryExtended) {
const targetFolder = await outputFolder.ensureFolderFromRelativePath(filePath);
if (!targetFolder) {
return;
}
let hasEnsuredFolder = false;
formsByPath = this.getFormsFromFilter(formsByPath, formsPath, exportMode);
for (const formPath in formsByPath) {
const formO = formsByPath[formPath];
if (formO) {
let baseName = StorageUtilities_1.default.getBaseFromName(StorageUtilities_1.default.getLeafName(formPath));
if (baseName.endsWith(".form")) {
baseName = baseName.substring(0, baseName.length - 5);
}
if (!hasEnsuredFolder) {
await targetFolder.ensureExists();
hasEnsuredFolder = true;
}
let fileName = this.getFileNameFromBaseName(baseName, exportMode);
const markdownFile = targetFolder.ensureFile(fileName + ".md");
await this.saveMarkdownDocFromForm(markdownFile, formO, baseName, exportMode, category, categoryExtended);
}
}
}
async exportValidatorMarkdownCatalogDocs(formsByPath, outputFolder, exportMode, subFolderPath, formsPath, categoryPlural, categorySingular) {
const targetFolder = await outputFolder.ensureFolderFromRelativePath(subFolderPath);
if (!targetFolder) {
return;
}
let hasEnsuredFolder = false;
formsByPath = this.getFormsFromFilter(formsByPath, formsPath, exportMode);
for (const formPath in formsByPath) {
const formO = formsByPath[formPath];
if (formO) {
let baseName = StorageUtilities_1.default.getBaseFromName(StorageUtilities_1.default.getLeafName(formPath));
if (baseName.endsWith(".form")) {
baseName = baseName.substring(0, baseName.length - 5);
}
if (!hasEnsuredFolder) {
await targetFolder.ensureExists();
hasEnsuredFolder = true;
}
let fileName = this.getFileNameFromBaseName(baseName, exportMode);
const markdownFile = targetFolder.ensureFile(fileName + ".md");
await this.saveValidatorMarkdownDocFromForm(markdownFile, formO, baseName, exportMode, categoryPlural, categorySingular);
}
}
}
async exportMarkdownCatalogDocs(formsByPath, outputFolder, exportMode, subFolderPath, formsPath, categoryPlural, categorySingular) {
const targetFolder = await outputFolder.ensureFolderFromRelativePath(subFolderPath);
if (!targetFolder) {
return;
}
let hasEnsuredFolder = false;
formsByPath = this.getFormsFromFilter(formsByPath, formsPath, exportMode);
for (const formPath in formsByPath) {
const formO = formsByPath[formPath];
if (formO) {
let baseName = StorageUtilities_1.default.getBaseFromName(StorageUtilities_1.default.getLeafName(formPath));
if (baseName.endsWith(".form")) {
baseName = baseName.substring(0, baseName.length - 5);
}
if (!hasEnsuredFolder) {
await targetFolder.ensureExists();
hasEnsuredFolder = true;
}
let fileName = this.getFileNameFromBaseName(baseName, exportMode);
const markdownFile = targetFolder.ensureFile(fileName + ".md");
await this.saveMarkdownDocFromForm(markdownFile, formO, baseName, exportMode, categoryPlural, categorySingular);
}
}
}
async exportMarkdownDocListPage(formsByPath, outputFolder, exportMode, subFolderPath, formsPath, category, subFolderName) {
const targetFile = await outputFolder.ensureFileFromRelativePath(subFolderPath);
if (!targetFile) {
return;
}
formsByPath = this.getFormsFromFilter(formsByPath, formsPath, exportMode);
const content = [];
content.push(Utilities_1.default.stringFormat(exports.MarkdownTop, category + " Documentation - " + category, "A reference document describing all current " + category));
let internalDepCount = 0;
content.push("| " + category + " | Description |");
content.push("|:-----|:----------|");
for (const formPath in formsByPath) {
const formO = formsByPath[formPath];
if (formO && !formO.isDeprecated && !formO.isInternal) {
let baseName = StorageUtilities_1.default.getBaseFromName(StorageUtilities_1.default.getLeafName(formPath));
if (baseName.endsWith(".form")) {
baseName = baseName.substring(0, baseName.length - 5);
}
let canonName = EntityTypeDefinition_1.default.getComponentFromBaseFileName(baseName);
if (formO.id) {
canonName = formO.id;
}
else if (formO.title) {
canonName = formO.title;
}
content.push("| [" +
canonName +
"](" +
subFolderName +
"/" +
this.getFileNameFromBaseName(baseName, exportMode) +
".md)| " +
(formO.description ? this.sanitizeForTable(this.getFirstSentence(formO.description)) : "") +
" |");
}
else if (formO) {
internalDepCount++;
}
}
if (internalDepCount > 0) {
content.push("");
content.push("## Internal/Deprecated Components");
content.push("These components are either deprecated or internal to Minecraft and not usable in custom content.");
content.push("");
content.push("| " + category + " | Description |");
content.push("|:-----|:----------|");
for (const formPath in formsByPath) {
const formO = formsByPath[formPath];
if (formO && (formO.isDeprecated || formO.isInternal)) {
let baseName = StorageUtilities_1.default.getBaseFromName(StorageUtilities_1.default.getLeafName(formPath));
if (baseName.endsWith(".form")) {
baseName = baseName.substring(0, baseName.length - 5);
}
let canonName = EntityTypeDefinition_1.default.getComponentFromBaseFileName(baseName);
content.push("| [" +
canonName +
"](" +
subFolderName +
"/" +
this.getFileNameFromBaseName(baseName, exportMode) +
".md)| " +
(formO.description ? this.sanitizeForTable(this.getFirstSentence(formO.description)) : "") +
" |");
}
}
}
targetFile.setContent(content.join("\r\n"));
await targetFile.saveContent();
}
async exportListYml(formsByPath, outputFolder, exportMode, subFolderPath, formsPath, header, prefix) {
const targetFile = await outputFolder.ensureFileFromRelativePath(subFolderPath);
if (!targetFile) {
return;
}
const content = [];
if (header) {
content.push(header);
}
formsByPath = this.getFormsFromFilter(formsByPath, formsPath, exportMode);
for (const formPath in formsByPath) {
const formO = formsByPath[formPath];
if (formO && !formO.isDeprecated && !formO.isInternal) {
let baseName = StorageUtilities_1.default.getBaseFromName(StorageUtilities_1.default.getLeafName(formPath));
if (baseName.endsWith(".form")) {
baseName = baseName.substring(0, baseName.length - 5);
}
if (prefix && baseName.startsWith("minecraftComponent_")) {
baseName = prefix + baseName.substring(19);
}
else if (prefix && baseName.startsWith("minecraft_")) {
baseName = prefix + baseName.substring(10);
}
else if (prefix) {
baseName = prefix + baseName;
}
content.push("- name: " + (formO.id ? formO.id : formO.title));
content.push(" href: " + this.getFileNameFromBaseName(baseName, exportMode) + ".md");
}
}
targetFile.setContent(content.join("\r\n"));
await targetFile.saveContent();
}
getFirstSentence(description) {
let endOfSentence = description.indexOf(". ");
if (endOfSentence >= 0) {
description = description.substring(0, endOfSentence + 1);
}
return description;
}
async saveMarkdownDocFromForm(markdownFile, form, baseName, exportMode, category, categoryExtended) {
const content = [];
let canonName = "minecraft:" + EntityTypeDefinition_1.default.getComponentFromBaseFileName(baseName);
if (exportMode === ExportMode.websockets && form.id) {
canonName = form.id;
}
content.push(Utilities_1.default.stringFormat(exports.MarkdownTop, category + " Documentation - " + canonName, "Describes the " + canonName + " " + categoryExtended.toLowerCase()));
content.push("# " + category + " Documentation - " + canonName + "\r\n");
if (form.isDeprecated) {
content.push("> [!IMPORTANT]");
content.push("> This type is now deprecated, and no longer in use in the latest versions of Minecraft.");
content.push("");
}
if (form.isInternal) {
content.push("> [!IMPORTANT]");
content.push("> This type is internal to vanilla Minecraft usage, and is not functional or supported within custom Minecraft content.");
content.push("");
}
await this.appendForm(form, content, 0);
if (form.samples) {
content.push("\r\n## Samples\r\n");
let samplesAdded = 0;
const linesAdded = [];
for (const samplePath in form.samples) {
let sampleArr = form.samples[samplePath];
let addedHeader = false;
if (sampleArr && samplesAdded < 12) {
const sampBaseName = StorageUtilities_1.default.getBaseFromName(StorageUtilities_1.default.getLeafName(samplePath));
let targetPath = samplePath;
if (!Array.isArray(sampleArr)) {
console.log("Malformed sample node at `" + samplePath + "` for file at `" + markdownFile.fullPath + "`");
}
else {
for (const sample of sampleArr) {
let line = "\r\n```json\r\n";
if (baseName.startsWith("minecraft_") &&
(typeof sample.content !== "string" || !sample.content.startsWith("minecraft:"))) {
line += '"' + canonName + '": ';
}
if (typeof sample.content === "object" || Array.isArray(sample.content)) {
line += JSON.stringify(sample.content, undefined, 2) + "\r\n```\r\n";
}
else {
if (typeof sample.content === "string") {
let cont = sample.content.trim();
if (cont.startsWith("{") && cont.endsWith("}")) {
line += cont + "\r\n```\r\n";
}
else {
line += '"' + cont + '"\r\n```\r\n';
}
}
else {
line += sample.content + "\r\n```\r\n";
}
}
if (!linesAdded.includes(line)) {
if (!addedHeader) {
addedHeader = true;
if (targetPath !== "samples" && targetPath !== "sample") {
if (targetPath.startsWith("/vanilla")) {
targetPath = "https://github.com/Mojang/bedrock-samples/tree/preview" + targetPath.substring(8);
}
else if (targetPath.startsWith("/samples")) {
targetPath = "https://github.com/microsoft/minecraft-samples/tree/main" + targetPath.substring(8);
}
content.push("#### [" +
Utilities_1.default.humanifyMinecraftName(sampBaseName.substring(0, 1).toUpperCase() + sampBaseName.substring(1)) +
"](" +
targetPath +
")\r\n");
}
}
if (sampleArr.length > 1) {
content.push("At " + sample.path + ": ");
}
linesAdded.push(line);
content.push(line);
samplesAdded++;
}
}
}
}
}
}
markdownFile.setContent(content.join("\r\n"));
await markdownFile.saveContent();
}
async saveValidatorMarkdownDocFromForm(markdownFile, form, baseName, exportMode, category, categoryExtended) {
const content = [];
let canonName = "minecraft:" + EntityTypeDefinition_1.default.getComponentFromBaseFileName(baseName);
if (exportMode === ExportMode.websockets && form.id) {
canonName = form.id;
}
content.push(Utilities_1.default.stringFormat(exports.MarkdownTop, category + " Documentation - " + canonName, "Describes the " + canonName + " " + categoryExtended.toLowerCase()));
content.push("# " + category + " Documentation - " + canonName + "\r\n");
if (form.isDeprecated) {
content.push("> [!IMPORTANT]");
content.push("> This type is now deprecated, and no longer in use in the latest versions of Minecraft.");
content.push("");
}
await this.appendValidatorForm(form, content, 0);
markdownFile.setContent(content.join("\r\n"));
await markdownFile.saveContent();
}
sanitizeDescription(description) {
description = description.trim();
if (description.length > 10 && !description.endsWith(".") && !description.endsWith(":")) {
description += ".";
}
return description;
}
getFileNameFromJsonKey(key) {
key = key.toLowerCase();
key = key.replace(/ /gi, "_");
key = key.replace(/::/gi, "_");
key = key.replace(/:/gi, "_");
return key;
}
async appendForm(form, content, depth, altTitle) {
if (form.description) {
content.push(this.sanitizeDescription(form.description) + "\r\n");
}
if (form.note) {
content.push("> [!Note]");
content.push("> " + this.sanitizeDescription(form.note) + "\r\n");
}
if (form.note2) {
content.push("> [!Note]");
content.push("> " + this.sanitizeDescription(form.note2) + "\r\n");
}
if (form.note3) {
content.push("> [!Note]");
content.push("> " + this.sanitizeDescription(form.note3) + "\r\n");
}
if (form.requires) {
let descStr = "";
const entityComponents = [];
if (!Array.isArray(form.requires)) {
console.log("Malformed requires node at `" + JSON.stringify(form.requires) + "`");
}
else {
for (const dep of form.requires) {
if (dep.type === "tame_owner") {
content.push("> [!Note]");
content.push("> Requires a player to be set as the tame owner via taming (or the `tame` command, or the tame API on EntityTameableComponent) in order to work properly.");
}
else if (dep.type === "targeting_entity_component") {
content.push("> [!Note]");
content.push("> Requires a target in order to work properly. Entities can generate targets via one of the following behaviors:");
content.push("> ");
content.push("> * [minecraft:behavior.nearest_attackable_target](../EntityGoals/minecraftBehavior_nearest_attackable_target.md)");
content.push("> * [minecraft:behavior.hurt_by_target](../EntityGoals/minecraftBehavior_hurt_by_target.md)");
}
else if (dep.type === "entity_component" ||
dep.type === "item_component" ||
dep.type === "block_component") {
if (dep.description) {
if (descStr.length > 0) {
descStr += " ";
}
descStr += dep.description;
}
entityComponents.push(dep.id);
}
}
}
if (entityComponents.length > 0) {
content.push("> [!Note]");
if (entityComponents.length === 1) {
content.push("> Requires the following component in order to work properly:");
}
else {
content.push("> Requires the following components in order to work properly:");
}
content.push("> ");
for (const entityComponent of entityComponents) {
content.push("> * [" +
Utilities_1.default.humanifyMinecraftName(entityComponent) +
" (" +
entityComponent +
")](../EntityComponents/minecraftComponent_" +
this.getFileNameFromJsonKey(entityComponent.substring(10)) +
".md)");
}
if (descStr.length >= 0) {
content.push("> " + descStr);
}
}
}
if (form.restrictions) {
const entityTypes = [];
let descStr = "";
for (const restriction of form.restrictions) {
if (restriction.type === "entity_type") {
entityTypes.push(restriction.id);
if (restriction.description) {
if (descStr.length > 0) {
descStr += " ";
}
descStr += restriction.description;
}
}
}
if (entityTypes.length > 0) {
content.push("> [!Note]");
if (entityTypes.length === 1) {
content.push("> Can only be used on the following type of entity:");
}
else {
content.push("> Can only be used on the following types of entity:");
}
content.push("> ");
for (const entityType of entityTypes) {
content.push("> * " + Utilities_1.default.humanifyMinecraftName(entityType) + " (" + entityType + ")");
}
if (descStr.length >= 0) {
content.push("> " + descStr);
}
}
}
const scalarField = DataFormUtilities_1.default.getScalarField(form);
if (scalarField) {
content.push("## Alternate Simple Representations\r\n");
for (const scalarFieldInst of DataFormUtilities_1.default.getFieldAndAlternates(scalarField)) {
content.push("This item can also be represented as a `" +
DataFormUtilities_1.default.getFieldTypeDescription(scalarFieldInst.dataType) +
"`.");
}
content.push("");
}
let title = undefined;
if (form.title) {
if (form.title === form.id) {
title = Utilities_1.default.humanifyMinecraftName(form.id);
}
else {
title = form.title;
}
}
else if (form.id) {
title = Utilities_1.default.humanifyMinecraftName(form.id);
}
else if (altTitle) {
title = altTitle;
}
else {
title = "Item";
}
if (form.fields && form.fields.length > 0) {
const subContent = [];
if (depth > 0) {
content.push("\r\n#### " + title + " Properties\r\n");
}
else {
content.push("\r\n## " + title + " Properties\r\n");
}
content.push("|Name |Default Value |Type |Description |Example Values |");
content.push("|:----------|:-------------|:----|:-----------|:------------- |");
form.fields.sort((a, b) => {
return a.id.localeCompare(b.id);
});
let fullFieldList = [];
for (const field of form.fields) {
fullFieldList.push(field);
if (field.alternates) {
let i = 0;
for (const altField of field.alternates) {
i++;
if (!altField.id || altField.id === field.id) {
altField.id = field.id + " (Alternate " + i + ")";
}
fullFieldList.push(altField);
}
}
}
for (const field of fullFieldList) {
let fieldRow = "| " + field.id + " | ";
if (field.defaultValue !== undefined) {
fieldRow += this.getValueAsString(field.defaultValue);
}
else {
fieldRow += "*not set*";
}
const fieldName = Utilities_1.default.humanifyMinecraftName(field.id);
const fieldLink = "(#" + this.getMarkdownBookmark(fieldName) + "-" + (field.choices ? "choices" : "item-type") + ")";
let subForm = field.subForm;
if (!subForm && field.subFormId) {
subForm = await Database_1.default.ensureFormLoadedByPath(field.subFormId);
}
if (subForm && subForm.fields && subForm.fields.length > 0) {
if (field.dataType === IField_1.FieldDataType.objectArray) {
fieldRow += " | Array of [" + fieldName + "]" + fieldLink + " items | ";
}
else if (field.dataType === IField_1.FieldDataType.keyedObjectCollection) {
fieldRow += " | Key/item pairs of [" + fieldName + "]" + fieldLink + " items | ";
}
else {
fieldRow += " | [" + fieldName + "]" + fieldLink + " item | ";
}
}
else if (field.choices) {
fieldRow += " | [" + fieldName + "]" + fieldLink + " choices | ";
subContent.push("\r\n### " + fieldName + " choices\r\n");
subContent.push("|Value |Title |Description |");
subContent.push("|:-----------|:-----|:-----------|");
for (const choice of field.choices) {
let choiceRow = "";
choiceRow += "| " + choice.id;
choiceRow +=
" | " + (choice.title ? this.sanitizeForTable(choice.title) : Utilities_1.default.humanifyMinecraftName(choice.id));
choiceRow += " | " + (choice.description ? this.sanitizeForTable(choice.description) : "") + "|";
subContent.push(choiceRow);
}
}
else if (field.dataType === IField_1.FieldDataType.minecraftEventTrigger) {
fieldRow +=
" | [" +
DataFormUtilities_1.default.getFieldTypeDescription(field.dataType) +
"](../Definitions/NestedTables/triggers.md) | ";
}
else {
let fieldTypes = "";
fieldTypes = DataFormUtilities_1.default.getFieldTypeDescription(field.dataType);
fieldRow += " | " + fieldTypes + " | ";
}
if (field.description) {
let descrip = field.description;
descrip += " " + this.addAdditionalNotes(field);
descrip = descrip.trim();
fieldRow += this.sanitizeForTable(descrip);
if (field.note) {
fieldRow += " " + this.sanitizeForTable(field.note);
}
if (field.note2) {
fieldRow += " " + this.sanitizeForTable(field.note2);
}
if (field.note3) {
fieldRow += " " + this.sanitizeForTable(field.note3);
}
}
fieldRow += " | ";
if (subForm && subForm.fields.length > 0) {
subContent.push("\r\n## " + fieldName + " item type");
await this.appendForm(subForm, subContent, depth + 1, fieldName);
}
if (field.samples) {
let samplesAdded = 0;
const samplesUsed = [];
let addedKey = false;
for (const samplePath in field.samples) {
let sampleArr = field.samples[samplePath];
if (sampleArr && samplesAdded < 3) {
const sampleSet = {};
for (const sample of sampleArr) {
const sampleVal = JSON.stringify(sample.content);
if (!samplesUsed.includes(sampleVal)) {
samplesUsed.push(sampleVal);
const baseName = StorageUtilities_1.default.getBaseFromName(StorageUtilities_1.default.getLeafName(samplePath));
samplesAdded++;
const key = baseName.substring(0, 1).toUpperCase() + baseName.substring(1);
if (!sampleSet[key]) {
sampleSet[key] = "`" + sampleVal + "`";
}
else {
sampleSet[key] = sampleSet[key] + ", `" + sampleVal + "`";
}
}
}
for (const key in sampleSet) {
if (addedKey) {
fieldRow += ", ";
}
fieldRow += Utilities_1.default.humanifyMinecraftName(key) + ": " + this.sanitizeForTable(sampleSet[key]);
addedKey = true;
}
}
}
}
fieldRow += " | ";
content.push(fieldRow);
}
content.push(...subContent);
}
}
addAdditionalNotes(field) {
let descrip = "";
if (field.minLength) {
descrip += "Value must have at least " + field.minLength + " items. ";
}
if (field.maxLength) {
descrip += "Value must have at most " + field.maxLength + " items. ";
}
if (field.validity) {
for (const cond of field.validity) {
if (cond.comparison === ICondition_1.ComparisonType.matchesPattern) {
descrip += 'Value must be match patern "' + cond.value + '". ';
}
else if (cond.comparison) {
descrip += "Value must be " + cond.comparison + " " + cond.value + ". ";
}
}
}
return descrip;
}
async appendValidatorForm(form, content, depth, altTitle) {
if (form.description) {
content.push(this.sanitizeDescription(form.description) + "\r\n");
}
if (form.note) {
content.push("> [!Note]");
content.push("> " + this.sanitizeDescription(form.note) + "\r\n");
}
if (form.note2) {
content.push("> [!Note]");
content.push("> " + this.sanitizeDescription(form.note2) + "\r\n");
}
if (form.note3) {
content.push("> [!Note]");
content.push("> " + this.sanitizeDescription(form.note3) + "\r\n");
}
let title = undefined;
if (form.title) {
if (form.title === form.id) {
title = Utilities_1.default.humanifyMinecraftName(form.id);
}
else {
title = form.title;
}
}
else if (form.id) {
title = Utilities_1.default.humanifyMinecraftName(form.id);
}
else if (altTitle) {
title = altTitle;
}
else {
title = "Item";
}
if (form.fields && form.fields.length > 0) {
const subContent = [];
if (depth > 0) {
content.push("\r\n#### " + title + " Properties\r\n");
}
else {
content.push("\r\n## " + title + " Properties\r\n");
}
content.push("|Name |Description |");
content.push("|:----------|:-------------|");
form.fields.sort((a, b) => {
return a.id.localeCompare(b.id);
});
let fullFieldList = [];
for (const field of form.fields) {
fullFieldList.push(field);
if (field.alternates) {
let i = 0;
for (const altField of field.alternates) {
i++;
if (!altField.id || altField.id === field.id) {
altField.id = field.id + " (Alternate " + i + ")";
}
fullFieldList.push(altField);
}
}
}
for (const field of fullFieldList) {
let fieldRow = "| " + field.id + " | ";
if (field.description) {
fieldRow += this.sanitizeForTable(field.description);
if (field.note) {
fieldRow += " " + this.sanitizeForTable(field.note);
}
if (field.note2) {
fieldRow += " " + this.sanitizeForTable(field.note2);
}
if (field.note3) {
fieldRow += " " + this.sanitizeForTable(field.note3);
}
}
fieldRow += " | ";
content.push(fieldRow);
}
content.push(...subContent);
}
}
getValueAsString(value) {
if (Array.isArray(value)) {
let result = "[";
let index = 0;
for (const subVal of value) {
if (index > 0) {
result += ", ";
}
result += subVal.toString();
index++;
}
return result + "]";
}
return value.toString();
}
sanitizeForTable(value) {
value = value.replace(/\\r/gi, " ");
value = value.replace(/\\t/gi, " ");
value = value.replace(/\\n/gi, "<br>");
value = value.replace(/\\"/gi, '"');
value = value.replace(/\r/gi, " ");
value = value.replace(/\n/gi, "<br>");
value = value.replace(/ /gi, " ");
value = value.replace(/ /gi, " ");
value = value.trim();
return value;
}
getMarkdownBookmark(id) {
return id.toLowerCase().replace(/ /gi, "-");
}
getFormsFromFilter(formsByPath, formsPath, mode) {
const filteredList = {};
for (const formPath in formsByPath) {
let includeFile = true;
if (formPath.indexOf("index") >= 0 ||
formPath.indexOf("overview") >= 0 ||
formPath.indexOf("describes") >= 0 ||
formPath.indexOf("versioned") >= 0) {
includeFile = false;
}
if (includeFile &&
formPath.toLowerCase().startsWith(formsPath) &&
formsByPath[formPath] &&
(formsPath.indexOf("behavior") >= 0 || formPath.indexOf("behavior") < 0) &&
(formsPath.indexOf("_on") >= 0 || formPath.indexOf("minecraft_on") < 0)) {
filteredList[formPath] = formsByPath[formPath];
}
}
return filteredList;
}
async loadFormJsonFromFolder(formsByPath, inputFolder, outputFolder) {
await inputFolder.load();
const fileList = { files: [], folders: [] };
for (const folderName in inputFolder.folders) {
const folder = inputFolder.folders[folderName];
if (folder) {
await this.loadFormJsonFromFolder(formsByPath, folder, outputFolder.ensureFolder(folderName));
fileList.folders.push(folderName);
}
}
for (const fileName in inputFolder.files) {
const file = inputFolder.files[fileName];
if (file) {
await file.loadContent();
const jsonO = StorageUtilities_1.default.getJsonObject(file);
if (jsonO) {
formsByPath[file.storageRelativePath] = jsonO;
}
}
}
}
}
exports.default = FormMarkdownDocumentationGenerator;
//# sourceMappingURL=../maps/docgen/FormMarkdownDocumentationGenerator.js.map