UNPKG

sfdx-hardis

Version:

Swiss-army-knife Toolbox for Salesforce. Allows you to define a complete CD/CD Pipeline. Orchestrate base commands and assist users with interactive wizards

105 lines 4.68 kB
import fs from "fs-extra"; import path from "path"; import { uxLog } from "../utils/index.js"; import c from "chalk"; import { UtilsAi } from "../aiProvider/utils.js"; import { AiProvider } from "../aiProvider/index.js"; export class DocBuilderRoles { placeholder = "<!-- Roles description -->"; promptKey = "PROMPT_DESCRIBE_ROLES"; static async generateMarkdownFileFromRoles(roleDescriptions, outputFile) { const mdLines = [ '<!-- This file is auto-generated. if you do not want it to be overwritten, set TRUE in the line below -->', '<!-- DO_NOT_OVERWRITE_DOC=FALSE -->', '', '# Organization roles', '', '<div id="jstree-container"></div>', '', ]; const aiDescription = await DocBuilderRoles.getDescriptionWithAI(roleDescriptions); if (aiDescription) { mdLines.push(""); mdLines.push("## AI-Generated Description", ""); mdLines.push(...aiDescription.split("\n")); mdLines.push(""); } await fs.ensureDir(path.dirname(outputFile)); await fs.writeFile(outputFile, mdLines.join("\n") + "\n"); await this.generateJsonTreeFileFromRoles(roleDescriptions); } static async getDescriptionWithAI(roleDescriptions) { const promptKey = "PROMPT_DESCRIBE_ROLES"; const metadataName = "Roles"; const rolesStrings = roleDescriptions.map(role => { return `- **${role.name} (id:${role.apiName} )**: ${role.description || "No description available"} (parentId: ${role.parentRole || "ROOT"}`; }).join("\n"); const aiCache = await UtilsAi.findAiCache(promptKey, [rolesStrings], metadataName); if (aiCache.success) { uxLog(this, c.green(`Using cached AI response for Roles`)); return aiCache.cacheText || ''; } if (AiProvider.isAiAvailable()) { const variables = { ROLES_DESCRIPTION: rolesStrings }; const prompt = AiProvider.buildPrompt(promptKey, variables); const aiResponse = await AiProvider.promptAi(prompt, promptKey); if (aiResponse?.success) { let responseText = aiResponse.promptResponse || "No AI description available"; if (responseText.startsWith("##")) { responseText = responseText.split("\n").slice(1).join("\n"); } await UtilsAi.writeAiCache(promptKey, [rolesStrings], metadataName, responseText); return responseText; } } return ''; } static async generateJsonTreeFileFromRoles(roleDescriptions) { const jsonTree = this.buildHierarchyTree(roleDescriptions); const jsonFile = `./docs/json/root-roles.json`; await fs.ensureDir(path.dirname(jsonFile)); await fs.writeFile(jsonFile, JSON.stringify(jsonTree, null, 2)); uxLog(this, c.green(`Successfully generated Roles JSON into ${jsonFile}`)); } static buildHierarchyTree(roleDescriptions) { // Build a tree structure for roles based on parent-child relationships const roleMap = new Map(); const rootRoles = []; // First pass: create all role nodes for (const role of roleDescriptions) { roleMap.set(role.apiName, { text: role.name, icon: "fa-solid fa-users icon-blue", children: [], roleData: role }); } // Second pass: build parent-child relationships for (const role of roleDescriptions) { const roleNode = roleMap.get(role.apiName); if (role.parentRole && roleMap.has(role.parentRole)) { const parentNode = roleMap.get(role.parentRole); parentNode.children.push(roleNode); } else { // This is a root role (no parent) rootRoles.push(roleNode); } } // Sort children by name for each node const sortChildren = (node) => { if (node.children && node.children.length > 0) { node.children.sort((a, b) => a.text.localeCompare(b.text)); node.children.forEach(sortChildren); // Update text to show count node.text = `${node.roleData.name} (${node.children.length})`; } }; rootRoles.forEach(sortChildren); rootRoles.sort((a, b) => a.roleData.name.localeCompare(b.roleData.name)); return rootRoles; } } //# sourceMappingURL=docBuilderRoles.js.map