UNPKG

@cparra/apexdocs

Version:

Library with CLI capabilities to generate documentation for Salesforce Apex classes.

1,522 lines (1,436 loc) 178 kB
'use strict'; var _function = require('fp-ts/function'); var TE = require('fp-ts/TaskEither'); var E = require('fp-ts/Either'); var yaml = require('js-yaml'); var path = require('path'); var T = require('fp-ts/Task'); var A = require('fp-ts/lib/Array'); var apexReflection = require('@cparra/apex-reflection'); var O = require('fp-ts/Option'); var fastXmlParser = require('fast-xml-parser'); var Handlebars = require('handlebars'); var boolean = require('fp-ts/boolean'); var A$1 = require('fp-ts/Array'); var fs = require('fs'); var TE$1 = require('fp-ts/lib/TaskEither'); var minimatch = require('minimatch'); var sourceDeployRetrieve = require('@salesforce/source-deploy-retrieve'); var chalk = require('chalk'); function _interopNamespaceDefault(e) { var n = Object.create(null); if (e) { Object.keys(e).forEach(function (k) { if (k !== 'default') { var d = Object.getOwnPropertyDescriptor(e, k); Object.defineProperty(n, k, d.get ? d : { enumerable: true, get: function () { return e[k]; } }); } }); } n.default = e; return Object.freeze(n); } var TE__namespace = /*#__PURE__*/_interopNamespaceDefault(TE); var E__namespace = /*#__PURE__*/_interopNamespaceDefault(E); var yaml__namespace = /*#__PURE__*/_interopNamespaceDefault(yaml); var path__namespace = /*#__PURE__*/_interopNamespaceDefault(path); var T__namespace = /*#__PURE__*/_interopNamespaceDefault(T); var A__namespace = /*#__PURE__*/_interopNamespaceDefault(A); var O__namespace = /*#__PURE__*/_interopNamespaceDefault(O); var A__namespace$1 = /*#__PURE__*/_interopNamespaceDefault(A$1); var fs__namespace = /*#__PURE__*/_interopNamespaceDefault(fs); var TE__namespace$1 = /*#__PURE__*/_interopNamespaceDefault(TE$1); function apply(fn, ...front) { return (...tailArgs) => fn(...front, ...tailArgs); } function defaultGetEmailByReference(email) { return { __type: "link", title: email, url: `mailto:${email}` }; } function replaceInlineReferences(text, linkReplacer, emailReplacer = defaultGetEmailByReference) { const inlineLinks = apply(replaceInlineLinks, linkReplacer); const inlineEmails = apply(replaceInlineEmails, emailReplacer); return _function.pipe(inlineCode$1([text]), inlineLinks, inlineEmails); } function inlineCode$1(renderableContents) { return renderableContents.flatMap((renderableContent) => inlineCodeContent(renderableContent)); } function inlineCodeContent(renderableContent) { if (typeof renderableContent !== "string") { return [renderableContent]; } function inlineCodeLink(text2) { return { __type: "inline-code", content: text2 }; } const text = renderableContent; const codeFormatRegEx = "`([^`]*)`"; const matches = match(codeFormatRegEx, text); return createRenderableContents(matches, text, inlineCodeLink); } function replaceInlineLinks(getLinkByTypeName, renderableContents) { return renderableContents.flatMap((renderableContent) => inlineLinkContent(renderableContent, getLinkByTypeName)); } function inlineLinkContent(renderableContent, getLinkByTypeName) { if (typeof renderableContent !== "string") { return [renderableContent]; } const text = renderableContent; const linkFormatRegEx = "{@link (.*?)}|<<([^>]+)>>"; const matches = match(linkFormatRegEx, text); return createRenderableContents(matches, text, getLinkByTypeName); } function replaceInlineEmails(getLinkByTypeName, renderableContents) { return renderableContents.flatMap((renderableContent) => inlineEmailContent(renderableContent, getLinkByTypeName)); } function inlineEmailContent(renderableContent, getLinkByTypeName) { if (typeof renderableContent !== "string") { return [renderableContent]; } const text = renderableContent; const linkFormatRegEx = "{@email (.*?)}"; const matches = match(linkFormatRegEx, text); return createRenderableContents(matches, text, getLinkByTypeName); } function match(regex, text) { const expression = new RegExp(regex, "gi"); let match2; const matches = []; do { match2 = expression.exec(text); if (match2) { matches.push(match2); } } while (match2); return matches; } function createRenderableContents(matches, text, linker) { if (matches.length === 0) { return [text]; } const result = []; let lastIndex = 0; for (const match2 of matches) { const index = match2.index; const length = match2[0].length; const capturedGroup = match2.slice(1).find((group) => group); if (!capturedGroup) { continue; } result.push(text.slice(lastIndex, index)); result.push(linker(capturedGroup)); lastIndex = index + length; } if (lastIndex < text.length) { result.push(text.slice(lastIndex)); } return result; } function isEmptyLine(content) { return Object.keys(content).includes("__type") && content.__type === "empty-line"; } function isCodeBlock(content) { return Object.keys(content).includes("__type") && content.__type === "code-block"; } function isInlineCode(content) { return Object.keys(content).includes("__type") && content.__type === "inline-code"; } var __defProp$o = Object.defineProperty; var __defProps$o = Object.defineProperties; var __getOwnPropDescs$o = Object.getOwnPropertyDescriptors; var __getOwnPropSymbols$o = Object.getOwnPropertySymbols; var __hasOwnProp$o = Object.prototype.hasOwnProperty; var __propIsEnum$o = Object.prototype.propertyIsEnumerable; var __defNormalProp$o = (obj, key, value) => key in obj ? __defProp$o(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value; var __spreadValues$o = (a, b) => { for (var prop in b || (b = {})) if (__hasOwnProp$o.call(b, prop)) __defNormalProp$o(a, prop, b[prop]); if (__getOwnPropSymbols$o) for (var prop of __getOwnPropSymbols$o(b)) { if (__propIsEnum$o.call(b, prop)) __defNormalProp$o(a, prop, b[prop]); } return a; }; var __spreadProps$o = (a, b) => __defProps$o(a, __getOwnPropDescs$o(b)); function adaptDescribable(describable, linkGenerator) { return { description: describableToRenderableContent(describable, linkGenerator) }; } function describableToRenderableContent(describable, linkGenerator) { if (!describable) { return; } let content = []; for (let i = 0; i < describable.length; i++) { const line = describable[i]; const codeBlockMatch = line.match(/^```([a-zA-Z]*)$/); if (codeBlockMatch) { const language = codeBlockMatch[1] || "apex"; const codeBlockLines = []; i++; while (i < describable.length) { const currentLine = describable[i]; if (currentLine.trim() === "```") { break; } codeBlockLines.push(currentLine); i++; } content = [ ...content, { __type: "code-block", language, content: codeBlockLines }, { __type: "empty-line" } ]; continue; } content = [ ...content, ...replaceInlineReferences(line, linkGenerator), { __type: "empty-line" } ]; } return content.filter((line, index, lines) => !(isEmptyLine(line) && index === lines.length - 1)); } function adaptDocumentable(documentable, linkGenerator, subHeadingLevel) { var _a, _b, _c; function extractCustomTags(type) { var _a2, _b2; const baseTags = ["description", "group", "author", "date", "see", "example", "throws", "exception"]; return (_b2 = (_a2 = type.docComment) == null ? void 0 : _a2.annotations.filter((currentAnnotation) => !baseTags.includes(currentAnnotation.name.toLowerCase())).map((currentAnnotation) => __spreadProps$o(__spreadValues$o({}, adaptDescribable(currentAnnotation.bodyLines, linkGenerator)), { name: currentAnnotation.name }))) != null ? _b2 : []; } function extractAnnotationBody(type, annotationName) { var _a2, _b2; return (_b2 = (_a2 = type.docComment) == null ? void 0 : _a2.annotations.find( (currentAnnotation) => currentAnnotation.name.toLowerCase() === annotationName )) == null ? void 0 : _b2.body; } function extractSeeAnnotations(type) { var _a2, _b2; return (_b2 = (_a2 = type.docComment) == null ? void 0 : _a2.annotations.filter((currentAnnotation) => currentAnnotation.name.toLowerCase() === "see").map((currentAnnotation) => currentAnnotation.body)) != null ? _b2 : []; } return __spreadProps$o(__spreadValues$o({}, adaptDescribable((_a = documentable.docComment) == null ? void 0 : _a.descriptionLines, linkGenerator)), { annotations: documentable.annotations.map((annotation) => annotation.type.toUpperCase()), customTags: extractCustomTags(documentable), example: { headingLevel: subHeadingLevel, heading: "Example", value: describableToRenderableContent((_c = (_b = documentable.docComment) == null ? void 0 : _b.exampleAnnotation) == null ? void 0 : _c.bodyLines, linkGenerator) }, group: extractAnnotationBody(documentable, "group"), author: extractAnnotationBody(documentable, "author"), date: extractAnnotationBody(documentable, "date"), sees: extractSeeAnnotations(documentable).map(linkGenerator) }); } var __defProp$n = Object.defineProperty; var __defProps$n = Object.defineProperties; var __getOwnPropDescs$n = Object.getOwnPropertyDescriptors; var __getOwnPropSymbols$n = Object.getOwnPropertySymbols; var __hasOwnProp$n = Object.prototype.hasOwnProperty; var __propIsEnum$n = Object.prototype.propertyIsEnumerable; var __defNormalProp$n = (obj, key, value) => key in obj ? __defProp$n(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value; var __spreadValues$n = (a, b) => { for (var prop in b || (b = {})) if (__hasOwnProp$n.call(b, prop)) __defNormalProp$n(a, prop, b[prop]); if (__getOwnPropSymbols$n) for (var prop of __getOwnPropSymbols$n(b)) { if (__propIsEnum$n.call(b, prop)) __defNormalProp$n(a, prop, b[prop]); } return a; }; var __spreadProps$n = (a, b) => __defProps$n(a, __getOwnPropDescs$n(b)); function adaptMethod(method, linkGenerator, baseHeadingLevel) { var _a, _b, _c; function buildTitle(method2) { const { name, parameters } = method2; const parametersString = parameters.map((param) => param.name).join(", "); return `${name}(${parametersString})`; } function buildSignature(method2) { const { access_modifier, typeReference, name, memberModifiers } = method2; const parameters = method2.parameters.map((param) => `${param.typeReference.rawDeclaration} ${param.name}`).join(", "); const members = memberModifiers.length > 0 ? `${memberModifiers.join(" ")} ` : ""; return { __type: "code-block", language: "apex", content: [`${access_modifier} ${members}${typeReference.rawDeclaration} ${name}(${parameters})`] }; } return { headingLevel: baseHeadingLevel, doc: adaptDocumentable(method, linkGenerator, baseHeadingLevel + 1), heading: buildTitle(method), signature: { headingLevel: baseHeadingLevel + 1, heading: "Signature", value: buildSignature(method) }, returnType: { headingLevel: baseHeadingLevel + 1, heading: "Return Type", value: __spreadProps$n(__spreadValues$n({}, adaptDescribable((_b = (_a = method.docComment) == null ? void 0 : _a.returnAnnotation) == null ? void 0 : _b.bodyLines, linkGenerator)), { type: linkGenerator(method.typeReference.rawDeclaration) }) }, throws: { headingLevel: baseHeadingLevel + 1, heading: "Throws", value: (_c = method.docComment) == null ? void 0 : _c.throwsAnnotations.map((thrown) => mapThrows(thrown, linkGenerator)) }, parameters: { headingLevel: baseHeadingLevel + 1, heading: "Parameters", value: method.parameters.map((param) => mapParameters(method, param, linkGenerator)) }, inherited: method.inherited }; } function adaptConstructor(typeName, constructor, linkGenerator, baseHeadingLevel) { var _a; function buildTitle(name, constructor2) { const { parameters } = constructor2; const parametersString = parameters.map((param) => param.name).join(", "); return `${name}(${parametersString})`; } function buildSignature(name, constructor2) { const { access_modifier } = constructor2; const parameters = constructor2.parameters.map((param) => `${param.typeReference.rawDeclaration} ${param.name}`).join(", "); return { __type: "code-block", language: "apex", content: [`${access_modifier} ${name}(${parameters})`] }; } return { doc: adaptDocumentable(constructor, linkGenerator, baseHeadingLevel + 1), headingLevel: baseHeadingLevel, heading: buildTitle(typeName, constructor), signature: { headingLevel: baseHeadingLevel + 1, heading: "Signature", value: buildSignature(typeName, constructor) }, parameters: { headingLevel: baseHeadingLevel + 1, heading: "Parameters", value: constructor.parameters.map((param) => mapParameters(constructor, param, linkGenerator)) }, throws: { headingLevel: baseHeadingLevel + 1, heading: "Throws", value: (_a = constructor.docComment) == null ? void 0 : _a.throwsAnnotations.map((thrown) => mapThrows(thrown, linkGenerator)) } }; } function mapParameters(documentable, param, linkGenerator) { var _a; const paramAnnotation = (_a = documentable.docComment) == null ? void 0 : _a.paramAnnotations.find( (pa) => pa.paramName.toLowerCase() === param.name.toLowerCase() ); return __spreadProps$n(__spreadValues$n({}, adaptDescribable(paramAnnotation == null ? void 0 : paramAnnotation.bodyLines, linkGenerator)), { name: param.name, type: linkGenerator(param.typeReference.rawDeclaration) }); } function mapThrows(thrown, linkGenerator) { return __spreadProps$n(__spreadValues$n({}, adaptDescribable(thrown.bodyLines, linkGenerator)), { type: linkGenerator(thrown.exceptionName) }); } function adaptFieldOrProperty(field, linkGenerator, baseHeadingLevel) { function buildSignature() { const { access_modifier, name } = field; const memberModifiers = field.memberModifiers.join(" "); const codeContents = `${access_modifier} ${memberModifiers} ${name}`.replace(/ {2}/g, " "); return { __type: "code-block", language: "apex", content: [codeContents] }; } return { headingLevel: baseHeadingLevel, doc: adaptDocumentable(field, linkGenerator, baseHeadingLevel + 1), heading: field.name, type: { headingLevel: baseHeadingLevel + 1, heading: "Type", value: linkGenerator(field.typeReference.rawDeclaration) }, inherited: field.inherited, accessModifier: field.access_modifier, signature: { headingLevel: baseHeadingLevel + 1, heading: "Signature", value: buildSignature() } }; } function skip() { return { _tag: "Skip" }; } function isSkip(value) { return Object.prototype.hasOwnProperty.call(value, "_tag") && value._tag === "Skip"; } function isObjectType(type) { return type.type_name === "customobject"; } function isApexType(type) { return !isObjectType(type) && !isTriggerType(type); } function isTriggerType(type) { return type.type_name === "trigger"; } function isInSource(source) { return "filePath" in source; } function getTypeGroup(type, config) { function getGroup(type2, config2) { var _a, _b; const groupAnnotation = (_a = type2.docComment) == null ? void 0 : _a.annotations.find( (annotation) => annotation.name.toLowerCase() === "group" ); return (_b = groupAnnotation == null ? void 0 : groupAnnotation.body) != null ? _b : config2.defaultGroupName; } switch (type.type_name) { case "customobject": return config.customObjectsGroupName; case "trigger": return config.triggersGroupName; default: return getGroup(type, config); } } function passThroughHook(value) { return value; } function toFrontmatterString(frontmatter) { if (typeof frontmatter === "string") { return frontmatter; } if (!frontmatter) { return ""; } const yamlString = yaml.dump(frontmatter); return `--- ${yamlString}--- `; } var __defProp$m = Object.defineProperty; var __defProps$m = Object.defineProperties; var __getOwnPropDescs$m = Object.getOwnPropertyDescriptors; var __getOwnPropSymbols$m = Object.getOwnPropertySymbols; var __hasOwnProp$m = Object.prototype.hasOwnProperty; var __propIsEnum$m = Object.prototype.propertyIsEnumerable; var __defNormalProp$m = (obj, key, value) => key in obj ? __defProp$m(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value; var __spreadValues$m = (a, b) => { for (var prop in b || (b = {})) if (__hasOwnProp$m.call(b, prop)) __defNormalProp$m(a, prop, b[prop]); if (__getOwnPropSymbols$m) for (var prop of __getOwnPropSymbols$m(b)) { if (__propIsEnum$m.call(b, prop)) __defNormalProp$m(a, prop, b[prop]); } return a; }; var __spreadProps$m = (a, b) => __defProps$m(a, __getOwnPropDescs$m(b)); function typeToRenderable$1(parsedFile, linkGenerator, config) { function getRenderable() { const { type } = parsedFile; switch (type.type_name) { case "enum": return enumTypeToEnumSource(type, linkGenerator); case "interface": return interfaceTypeToInterfaceSource(type, linkGenerator); case "class": return classTypeToClassSource(type, linkGenerator); case "trigger": return triggerMetadataToRenderable(type, linkGenerator); case "customobject": return objectMetadataToRenderable(type, config); } } return __spreadProps$m(__spreadValues$m({}, getRenderable()), { filePath: isInSource(parsedFile.source) ? parsedFile.source.filePath : void 0, namespace: config.namespace }); } function baseTypeAdapter(type, linkGenerator, baseHeadingLevel) { function getHeading(type2) { const suffixMap = { class: "Class", interface: "Interface", enum: "Enum" }; return `${type2.name} ${suffixMap[type2.type_name]}`; } return { headingLevel: baseHeadingLevel, heading: getHeading(type), doc: adaptDocumentable(type, linkGenerator, baseHeadingLevel + 1), name: type.name, meta: { accessModifier: type.access_modifier } }; } function enumTypeToEnumSource(enumType, linkGenerator, baseHeadingLevel = 1) { return __spreadProps$m(__spreadValues$m({ type: "enum" }, baseTypeAdapter(enumType, linkGenerator, baseHeadingLevel)), { values: { headingLevel: baseHeadingLevel + 1, heading: "Values", value: enumType.values.map((value) => { var _a; return __spreadProps$m(__spreadValues$m({}, adaptDescribable((_a = value.docComment) == null ? void 0 : _a.descriptionLines, linkGenerator)), { value: value.name }); }) } }); } function interfaceTypeToInterfaceSource(interfaceType, linkGenerator, baseHeadingLevel = 1) { return __spreadProps$m(__spreadValues$m({ type: "interface" }, baseTypeAdapter(interfaceType, linkGenerator, baseHeadingLevel)), { extends: interfaceType.extended_interfaces.map(linkGenerator), methods: { headingLevel: baseHeadingLevel + 1, heading: "Methods", value: interfaceType.methods.map((method) => adaptMethod(method, linkGenerator, baseHeadingLevel + 2)) } }); } function classTypeToClassSource(classType, linkGenerator, baseHeadingLevel = 1) { return __spreadProps$m(__spreadValues$m({ type: "class" }, baseTypeAdapter(classType, linkGenerator, baseHeadingLevel)), { classModifier: classType.classModifier, sharingModifier: classType.sharingModifier, implements: classType.implemented_interfaces.map(linkGenerator), extends: classType.inheritanceChain.map(linkGenerator), methods: adaptMembers("Methods", classType.methods, adaptMethod, linkGenerator, baseHeadingLevel + 1), constructors: adaptMembers( "Constructors", classType.constructors, (constructor, linkGenerator2, baseHeadingLevel2) => adaptConstructor(classType.name, constructor, linkGenerator2, baseHeadingLevel2), linkGenerator, baseHeadingLevel + 1 ), fields: adaptMembers( "Fields", classType.fields, adaptFieldOrProperty, linkGenerator, baseHeadingLevel + 1 ), properties: adaptMembers( "Properties", classType.properties, adaptFieldOrProperty, linkGenerator, baseHeadingLevel + 1 ), innerClasses: { headingLevel: baseHeadingLevel + 1, heading: "Classes", value: classType.classes.map( (innerClass) => classTypeToClassSource(__spreadProps$m(__spreadValues$m({}, innerClass), { inheritanceChain: [] }), linkGenerator, baseHeadingLevel + 2) ) }, innerEnums: { headingLevel: baseHeadingLevel + 1, heading: "Enums", value: classType.enums.map((innerEnum) => enumTypeToEnumSource(innerEnum, linkGenerator, baseHeadingLevel + 2)) }, innerInterfaces: { headingLevel: baseHeadingLevel + 1, heading: "Interfaces", value: classType.interfaces.map( (innerInterface) => interfaceTypeToInterfaceSource(innerInterface, linkGenerator, baseHeadingLevel + 2) ) } }); } function adaptMembers(heading, members, adapter, linkFromTypeNameGenerator, headingLevel) { return { headingLevel, heading, isGrouped: hasGroup(members), value: hasGroup(members) ? toGroupedMembers(members, adapter, linkFromTypeNameGenerator, headingLevel + 1) : toFlat(members, adapter, linkFromTypeNameGenerator, headingLevel + 1) }; } function hasGroup(members) { return members.some((member) => member.group); } function toFlat(members, adapter, linkGenerator, baseHeadingLevel) { return members.map((member) => adapter(member, linkGenerator, baseHeadingLevel)); } function toGroupedMembers(members, adapter, linkGenerator, baseHeadingLevel) { const groupedMembers = groupByGroupName(members); return Object.entries(groupedMembers).map( ([groupName, members2]) => singleGroup(baseHeadingLevel, groupName, adapter, members2, linkGenerator) ); } function groupByGroupName(members) { return members.reduce( (acc, member) => { var _a, _b; const groupName = (_a = member.group) != null ? _a : "Other"; acc[groupName] = (_b = acc[groupName]) != null ? _b : []; acc[groupName].push(member); return acc; }, {} ); } function singleGroup(headingLevel, groupName, adapter, members, linkGenerator) { return { headingLevel, heading: groupName, groupDescription: members[0].groupDescription, // All fields in the group have the same description value: toFlat(members, adapter, linkGenerator, headingLevel + 1) }; } function triggerMetadataToRenderable(triggerMetadata, linkGenerator, baseHeadingLevel = 1) { function formatEvent(event) { switch (event) { case "beforeinsert": return "Before Insert"; case "beforeupdate": return "Before Update"; case "beforedelete": return "Before Delete"; case "afterinsert": return "After Insert"; case "afterupdate": return "After Update"; case "afterdelete": return "After Delete"; case "afterundelete": return "After Undelete"; default: return event; } } return { doc: adaptDocumentable( { docComment: triggerMetadata.docComment, annotations: [] }, linkGenerator, baseHeadingLevel + 1 ), name: triggerMetadata.name, type: "trigger", headingLevel: 1, heading: triggerMetadata.name + " Trigger", objectName: triggerMetadata.object_name, events: triggerMetadata.events.map(formatEvent) }; } function objectMetadataToRenderable(objectMetadata, config) { var _a; function toRenderablePublishBehavior(publishBehavior) { switch (publishBehavior) { case "PublishImmediately": return "Publish Immediately"; case "PublishAfterCommit": return "Publish After Commit"; default: return null; } } return { type: "customobject", headingLevel: 1, apiName: getApiName(objectMetadata.name, config), heading: (_a = objectMetadata.label) != null ? _a : objectMetadata.name, name: objectMetadata.name, doc: { description: objectMetadata.description ? [objectMetadata.description] : [], group: getTypeGroup(objectMetadata, config) }, hasFields: objectMetadata.fields.length > 0, fields: { headingLevel: 2, heading: "Fields", value: objectMetadata.fields.map((field) => fieldMetadataToRenderable(field, config, 3)) }, hasRecords: objectMetadata.metadataRecords.length > 0, metadataRecords: { headingLevel: 2, heading: "Records", value: objectMetadata.metadataRecords.map((metadata) => customMetadataToRenderable(metadata, 3)) }, publishBehavior: toRenderablePublishBehavior(objectMetadata.publishBehavior) }; } function fieldMetadataToRenderable(field, config, headingLevel) { var _a; return { type: "field", headingLevel, heading: (_a = field.label) != null ? _a : field.name, description: field.description ? [field.description] : [], apiName: getApiName(field.name, config), fieldType: field.type, required: field.required, pickListValues: field.pickListValues ? { headingLevel: headingLevel + 1, heading: "Possible values are", value: field.pickListValues } : void 0 }; } function customMetadataToRenderable(metadata, headingLevel) { var _a, _b; return { type: "metadata", headingLevel, heading: (_a = metadata.label) != null ? _a : metadata.name, apiName: metadata.apiName, label: (_b = metadata.label) != null ? _b : metadata.name, protected: metadata.protected }; } function getApiName(currentName, config) { if (config.namespace) { const name = currentName.replace(/__c$/, ""); if (name.includes("__")) { return name; } return `${config.namespace}__${currentName}`; } return currentName; } const generateLink = (strategy) => { switch (strategy) { case "relative": return generateRelativeLink; case "no-link": return generateNoLink; case "none": return returnReferenceAsIs; } }; const generateRelativeLink = (references, from, referenceName) => { function getRelativePath(fromPath, toPath) { return path.relative(path.parse(path.join("/", fromPath)).dir, path.join("/", toPath)); } const referenceTo = references[referenceName]; if (!referenceTo) { return referenceName; } if (referenceTo && from === "__base__") { return { __type: "link", title: referenceTo.displayName, url: getRelativePath("", referenceTo.referencePath) }; } const referenceFrom = references[from]; if (!referenceFrom) { return referenceTo.displayName; } return { __type: "link", title: referenceTo.displayName, url: getRelativePath(referenceFrom.referencePath, referenceTo.referencePath) }; }; const generateNoLink = (references, _from, referenceName) => { const referenceTo = references[referenceName]; return referenceTo ? referenceTo.displayName : referenceName; }; const returnReferenceAsIs = (references, _from, referenceName) => { const referenceTo = references[referenceName]; if (!referenceTo) { return referenceName; } return { __type: "link", title: referenceTo.displayName, url: referenceTo.referencePath }; }; function parsedFilesToRenderableBundle(config, parsedFiles, references) { const referenceFinder = apply(generateLink(config.linkingStrategy), references); function toReferenceGuide(parsedFiles2) { return parsedFiles2.reduce( addToReferenceGuide(apply(referenceFinder, "__base__"), config, references), {} ); } function toRenderables(parsedFiles2) { return parsedFiles2.reduce((acc, parsedFile) => { const renderable = typeToRenderable$1(parsedFile, apply(referenceFinder, parsedFile.source.name), config); acc.push(renderable); return acc; }, []); } return { referencesByGroup: toReferenceGuide(parsedFiles), renderables: toRenderables(parsedFiles) }; } function addToReferenceGuide(findLinkFromHome, config, references) { return (acc, parsedFile) => { const group = getTypeGroup(parsedFile.type, config); if (!acc[group]) { acc[group] = []; } acc[group].push({ reference: references[parsedFile.source.name], title: findLinkFromHome(parsedFile.source.name), description: getRenderableDescription(parsedFile.type, findLinkFromHome) }); return acc; }; } function getRenderableDescription(type, findLinkFromHome) { var _a, _b; switch (type.type_name) { case "customobject": return type.description ? [type.description] : null; default: return (_b = adaptDescribable((_a = type.docComment) == null ? void 0 : _a.descriptionLines, findLinkFromHome).description) != null ? _b : null; } } class ReflectionError { constructor(file, message) { this.file = file; this.message = message; } } class ReflectionErrors { constructor(errors) { this.errors = errors; this._tag = "ReflectionErrors"; } } class HookError { constructor(error) { this.error = error; this._tag = "HookError"; } } function parseApexMetadata(input) { return _function.pipe(input, parse, E__namespace.map(toMap)); } function parse(input) { return E__namespace.tryCatch(() => new fastXmlParser.XMLParser().parse(input), E__namespace.toError); } function toMap(metadata) { const map = /* @__PURE__ */ new Map(); map.set("apiVersion", String(metadata.ApexClass.apiVersion)); if (metadata.ApexClass.status) { map.set("status", String(metadata.ApexClass.status)); } return map; } var __defProp$l = Object.defineProperty; var __defProps$l = Object.defineProperties; var __getOwnPropDescs$l = Object.getOwnPropertyDescriptors; var __getOwnPropSymbols$l = Object.getOwnPropertySymbols; var __hasOwnProp$l = Object.prototype.hasOwnProperty; var __propIsEnum$l = Object.prototype.propertyIsEnumerable; var __defNormalProp$l = (obj, key, value) => key in obj ? __defProp$l(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value; var __spreadValues$l = (a, b) => { for (var prop in b || (b = {})) if (__hasOwnProp$l.call(b, prop)) __defNormalProp$l(a, prop, b[prop]); if (__getOwnPropSymbols$l) for (var prop of __getOwnPropSymbols$l(b)) { if (__propIsEnum$l.call(b, prop)) __defNormalProp$l(a, prop, b[prop]); } return a; }; var __spreadProps$l = (a, b) => __defProps$l(a, __getOwnPropDescs$l(b)); var __async$5 = (__this, __arguments, generator) => { return new Promise((resolve, reject) => { var fulfilled = (value) => { try { step(generator.next(value)); } catch (e) { reject(e); } }; var rejected = (value) => { try { step(generator.throw(value)); } catch (e) { reject(e); } }; var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected); step((generator = generator.apply(__this, __arguments)).next()); }); }; function reflectAsync$1(rawSource) { return __async$5(this, null, function* () { return new Promise((resolve, reject) => { const result = apexReflection.reflect(rawSource); if (result.typeMirror) { return resolve(result.typeMirror); } else if (result.error) { return reject(result.error); } else { return reject(new Error("Unknown error")); } }); }); } function reflectApexSource(apexBundles) { const semiGroupReflectionError = { concat: (x, y) => new ReflectionErrors([...x.errors, ...y.errors]) }; const Ap = TE__namespace.getApplicativeTaskValidation(T__namespace.ApplyPar, semiGroupReflectionError); return _function.pipe(apexBundles, A__namespace.traverse(Ap)(reflectBundle$1)); } function reflectBundle$1(apexBundle) { const convertToParsedFile = apply(toParsedFile$4, apexBundle.filePath); const withMetadata = apply(addMetadata, apexBundle.metadataContent); return _function.pipe(apexBundle, reflectAsTask$1, TE__namespace.map(convertToParsedFile), TE__namespace.flatMap(withMetadata)); } function reflectAsTask$1(apexBundle) { return TE__namespace.tryCatch( () => reflectAsync$1(apexBundle.content), (error) => new ReflectionErrors([new ReflectionError(apexBundle.filePath, error.message)]) ); } function toParsedFile$4(filePath, typeMirror) { return { source: { filePath, name: typeMirror.name, type: typeMirror.type_name }, type: typeMirror }; } function addMetadata(rawMetadataContent, parsedFile) { return TE__namespace.fromEither( _function.pipe( parsedFile.type, (type) => addFileMetadataToTypeAnnotation(type, rawMetadataContent), E__namespace.map((type) => __spreadProps$l(__spreadValues$l({}, parsedFile), { type })), E__namespace.mapLeft( (error) => errorToReflectionErrors(error, isInSource(parsedFile.source) ? parsedFile.source.filePath : "") ) ) ); } function errorToReflectionErrors(error, filePath) { return new ReflectionErrors([new ReflectionError(filePath, error.message)]); } function addFileMetadataToTypeAnnotation(type, metadata) { const concatAnnotationToType = apply(concatAnnotations, type); return _function.pipe( O__namespace.fromNullable(metadata), O__namespace.map(concatAnnotationToType), O__namespace.getOrElse(() => E__namespace.right(type)) ); } function concatAnnotations(type, metadataInput) { return _function.pipe( metadataInput, parseApexMetadata, E__namespace.map((metadataMap) => __spreadProps$l(__spreadValues$l({}, type), { annotations: [...type.annotations, ...mapToAnnotations(metadataMap)] })) ); } function mapToAnnotations(metadata) { return Array.from(metadata.entries()).map(([key, value]) => { const declaration = `${key}: ${value}`; return { name: declaration, type: declaration, rawDeclaration: declaration }; }); } function createInheritanceChain(repository, classMirror) { return _function.pipe( O__namespace.fromNullable(classMirror.extended_class), O__namespace.match( () => [], (extendedClassName) => inheritanceChainFromParentClassName(repository, extendedClassName) ) ); } function inheritanceChainFromParentClassName(repository, className) { return _function.pipe( O__namespace.fromNullable(repository.find((type) => type.name.toLowerCase() === className.toLowerCase())), O__namespace.match( () => [className], (extendedClass) => [className, ...createInheritanceChain(repository, extendedClass)] ) ); } const parsedFilesToTypes = (parsedFiles) => parsedFiles.map((parsedFile) => parsedFile.type); var __defProp$k = Object.defineProperty; var __defProps$k = Object.defineProperties; var __getOwnPropDescs$k = Object.getOwnPropertyDescriptors; var __getOwnPropSymbols$k = Object.getOwnPropertySymbols; var __hasOwnProp$k = Object.prototype.hasOwnProperty; var __propIsEnum$k = Object.prototype.propertyIsEnumerable; var __defNormalProp$k = (obj, key, value) => key in obj ? __defProp$k(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value; var __spreadValues$k = (a, b) => { for (var prop in b || (b = {})) if (__hasOwnProp$k.call(b, prop)) __defNormalProp$k(a, prop, b[prop]); if (__getOwnPropSymbols$k) for (var prop of __getOwnPropSymbols$k(b)) { if (__propIsEnum$k.call(b, prop)) __defNormalProp$k(a, prop, b[prop]); } return a; }; var __spreadProps$k = (a, b) => __defProps$k(a, __getOwnPropDescs$k(b)); const addInheritanceChainToTypes = (parsedFiles) => parsedFiles.map((parsedFile) => __spreadProps$k(__spreadValues$k({}, parsedFile), { type: addInheritanceChain(parsedFile.type, parsedFilesToTypes(parsedFiles)) })); function addInheritanceChain(current, repository) { if (current.type_name === "enum" || current.type_name === "interface") { return current; } else { const inheritanceChain = createInheritanceChain(repository, current); return __spreadProps$k(__spreadValues$k({}, current), { inheritanceChain }); } } var __defProp$j = Object.defineProperty; var __defProps$j = Object.defineProperties; var __getOwnPropDescs$j = Object.getOwnPropertyDescriptors; var __getOwnPropSymbols$j = Object.getOwnPropertySymbols; var __hasOwnProp$j = Object.prototype.hasOwnProperty; var __propIsEnum$j = Object.prototype.propertyIsEnumerable; var __defNormalProp$j = (obj, key, value) => key in obj ? __defProp$j(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value; var __spreadValues$j = (a, b) => { for (var prop in b || (b = {})) if (__hasOwnProp$j.call(b, prop)) __defNormalProp$j(a, prop, b[prop]); if (__getOwnPropSymbols$j) for (var prop of __getOwnPropSymbols$j(b)) { if (__propIsEnum$j.call(b, prop)) __defNormalProp$j(a, prop, b[prop]); } return a; }; var __spreadProps$j = (a, b) => __defProps$j(a, __getOwnPropDescs$j(b)); const addInheritedMembersToTypes = (parsedFiles) => parsedFiles.map((parsedFile) => addInheritedMembers(parsedFilesToTypes(parsedFiles), parsedFile)); function addInheritedMembers(repository, parsedFile) { function addInheritedMembersToType(repository2, current) { if (current.type_name === "enum") { return current; } else if (current.type_name === "interface") { return addInheritedInterfaceMethods(current, repository2); } else { return addInheritedClassMembers(current, repository2); } } return __spreadProps$j(__spreadValues$j({}, parsedFile), { type: addInheritedMembersToType(repository, parsedFile.type) }); } function addInheritedInterfaceMethods(interfaceMirror, repository) { function methodAlreadyExists(memberName, members) { return members.some((member) => member.name.toLowerCase() === memberName.toLowerCase()); } function parentExtractor(interfaceMirror2) { return interfaceMirror2.extended_interfaces; } const parents = getParents(parentExtractor, interfaceMirror, repository); return __spreadProps$j(__spreadValues$j({}, interfaceMirror), { methods: parents.reduce( (acc, currentValue) => [ ...acc, ...currentValue.methods.filter((method) => !methodAlreadyExists(method.name, acc)).map((method) => __spreadProps$j(__spreadValues$j({}, method), { inherited: true })) ], interfaceMirror.methods ) }); } function addInheritedClassMembers(classMirror, repository) { function memberAlreadyExists(memberName, members) { return members.some((member) => member.name.toLowerCase() === memberName.toLowerCase()); } function parentExtractor(classMirror2) { return classMirror2.extended_class ? [classMirror2.extended_class] : []; } function filterMember(members, existing) { return members.filter((member) => member.access_modifier.toLowerCase() !== "private").filter((member) => !memberAlreadyExists(member.name, existing)).map((member) => __spreadProps$j(__spreadValues$j({}, member), { inherited: true })); } const parents = getParents(parentExtractor, classMirror, repository); return __spreadProps$j(__spreadValues$j({}, classMirror), { fields: parents.reduce( (acc, currentValue) => [...acc, ...filterMember(currentValue.fields, acc)], classMirror.fields ), properties: parents.reduce( (acc, currentValue) => [...acc, ...filterMember(currentValue.properties, acc)], classMirror.properties ), methods: parents.reduce( (acc, currentValue) => [...acc, ...filterMember(currentValue.methods, acc)], classMirror.methods ) }); } function getParents(extendedNamesExtractor, current, repository) { return _function.pipe( extendedNamesExtractor(current), (interfaces) => interfaces.map((interfaceName) => repository.find((type) => type.name === interfaceName)), (interfaces = []) => interfaces.filter((type) => type !== void 0), (interfaces) => interfaces.reduce( (acc, current2) => [...acc, ...getParents(extendedNamesExtractor, current2, repository)], interfaces ) ); } const typeDocPartial = ` {{#> documentablePartialTemplate}} {{#if doc.group}} **Group** {{doc.group}} {{/if}} {{#if doc.author}} **Author** {{doc.author}} {{/if}} {{#if doc.date}} **Date** {{doc.date}} {{/if}} {{#each doc.sees}} **See** {{link this}} {{/each}} {{#if namespace}} ## Namespace {{namespace}} {{/if}} {{/documentablePartialTemplate}} `.trim(); const documentablePartialTemplate = ` {{#each doc.annotations}} \`{{this}}\` {{/each}} {{{renderContent doc.description}}} {{#each doc.customTags}} **{{splitAndCapitalize name}}** {{{renderContent description}}} {{/each}} {{> @partial-block}} {{#if doc.mermaid.value}} {{ heading doc.mermaid.headingLevel doc.mermaid.heading }} {{code doc.mermaid.value}} {{/if}} {{#if doc.example.value}} {{ heading doc.example.headingLevel doc.example.heading }} {{{renderContent doc.example.value}}} {{/if}} `.trim(); const methodsPartialTemplate = ` {{ heading headingLevel heading }} {{#each value}} {{{ heading headingLevel (inlineCode heading) }}} {{#if inherited}} *Inherited* {{/if}} {{#> documentablePartialTemplate}} {{ heading signature.headingLevel signature.heading }} {{ code signature.value }} {{#if parameters.value}} {{ heading parameters.headingLevel parameters.heading }} | Name | Type | Description | |------|------|-------------| {{#each parameters.value}} | {{name}} | {{link type}} | {{{renderContent description}}} | {{/each}} {{/if}} {{ heading returnType.headingLevel returnType.heading }} **{{link returnType.value.type}}** {{#if returnType.value.description}} {{returnType.value.description}} {{/if}} {{#if throws.value}} {{ heading throws.headingLevel throws.heading }} {{#each throws.value}} {{link this.type}}: {{this.description}} {{/each}} {{/if}} {{/documentablePartialTemplate}} {{#unless @last}}---{{/unless}} {{/each}} `.trim(); const groupedMembersPartialTemplate = ` {{ heading headingLevel heading }} {{#each value}} {{> (lookup .. "subTemplate") this}} {{/each}} `.trim(); const constructorsPartialTemplate = ` {{ heading headingLevel heading }} {{#each value}} {{{ heading headingLevel (inlineCode heading) }}} {{#> documentablePartialTemplate}} {{ heading signature.headingLevel signature.heading }} {{ code signature.value }} {{#if parameters.value}} {{ heading parameters.headingLevel parameters.heading }} | Name | Type | Description | |------|------|-------------| {{#each parameters.value}} | {{name}} | {{link type}} | {{description}} | {{/each}} {{/if}} {{#if throws.value}} {{ heading throws.headingLevel throws.heading }} {{#each throws.value}} {{link this.type}}: {{this.description}} {{/each}} {{/if}} {{/documentablePartialTemplate}} {{#unless @last}}---{{/unless}} {{/each}} `.trim(); const fieldsPartialTemplate = ` {{ heading headingLevel heading }} {{#each value}} {{{ heading headingLevel (inlineCode heading) }}} {{#if inherited}} *Inherited* {{/if}} {{#> documentablePartialTemplate }} {{ heading signature.headingLevel signature.heading }} {{ code signature.value }} {{ heading type.headingLevel type.heading }} {{link type.value}} {{/documentablePartialTemplate}} {{#unless @last}}---{{/unless}} {{/each}} `.trim(); const classMarkdownTemplate = ` {{ heading headingLevel heading }} {{#if classModifier}} \`{{classModifier}}\` {{/if}} {{> typeDocumentation}} {{#if extends.length}} **Inheritance** {{#each extends}}{{link this}}{{#unless @last}} < {{/unless}}{{/each}} {{/if}} {{#if implements}} **Implements** {{#each implements}} {{link this}}{{#unless @last}}, {{/unless}} {{/each}} {{/if}} {{#if fields.value}} {{#if fields.isGrouped}} {{> groupedMembersPartialTemplate fields subTemplate="fieldsPartialTemplate"}} {{else}} {{> fieldsPartialTemplate fields}} {{/if}} {{/if}} {{#if properties.value}} {{#if properties.isGrouped}} {{> groupedMembersPartialTemplate properties subTemplate="fieldsPartialTemplate"}} {{else}} {{> fieldsPartialTemplate properties}} {{/if}} {{/if}} {{#if constructors.value}} {{#if constructors.isGrouped}} {{> groupedMembersPartialTemplate constructors subTemplate="constructorsPartialTemplate"}} {{else}} {{> constructorsPartialTemplate constructors}} {{/if}} {{/if}} {{#if methods.value}} {{#if methods.isGrouped}} {{> groupedMembersPartialTemplate methods subTemplate="methodsPartialTemplate"}} {{else}} {{> methodsPartialTemplate methods}} {{/if}} {{/if}} {{#if innerClasses.value}} {{ heading innerClasses.headingLevel innerClasses.heading }} {{#each innerClasses.value}} {{> classTemplate this}} {{/each}} {{/if}} {{#if innerEnums.value}} {{ heading innerEnums.headingLevel innerEnums.heading }} {{#each innerEnums.value}} {{> enumTemplate this}} {{/each}} {{/if}} {{#if innerInterfaces.value}} {{ heading innerInterfaces.headingLevel innerInterfaces.heading }} {{#each innerInterfaces.value}} {{> interfaceTemplate this}} {{/each}} {{/if}} `.trim(); const enumMarkdownTemplate = ` {{ heading headingLevel heading }} {{> typeDocumentation }} {{ heading values.headingLevel values.heading }} | Value | Description | |-------|-------------| {{#each values.value}} | {{value}} | {{description}} | {{/each}} `.trim(); const interfaceMarkdownTemplate = ` {{ heading headingLevel heading }} {{> typeDocumentation }} {{#if extends}} **Extends** {{#each extends}} {{link this}}{{#unless @last}}, {{/unless}} {{/each}} {{/if}} {{#if methods}} {{> methodsPartialTemplate methods}} {{/if}} `.trim(); class Template { constructor() { Handlebars.registerPartial("typeDocumentation", typeDocPartial); Handlebars.registerPartial("documentablePartialTemplate", documentablePartialTemplate); Handlebars.registerPartial("methodsPartialTemplate", methodsPartialTemplate); Handlebars.registerPartial("constructorsPartialTemplate", constructorsPartialTemplate); Handlebars.registerPartial("groupedMembersPartialTemplate", groupedMembersPartialTemplate); Handlebars.registerPartial("fieldsPartialTemplate", fieldsPartialTemplate); Handlebars.registerPartial("classTemplate", classMarkdownTemplate); Handlebars.registerPartial("enumTemplate", enumMarkdownTemplate); Handlebars.registerPartial("interfaceTemplate", interfaceMarkdownTemplate); Handlebars.registerHelper("link", link); Handlebars.registerHelper("code", convertCodeBlock); Handlebars.registerHelper("renderContent", resolveRenderableContent); Handlebars.registerHelper("heading", heading); Handlebars.registerHelper("inlineCode", inlineCode); Handlebars.registerHelper("splitAndCapitalize", splitAndCapitalize); } static getInstance() { if (!Template.instance) { Template.instance = new Template(); } return Template.instance; } compile(request) { const compiled = Handlebars.compile(request.template); return compiled(request.source).trim().replace(/\n{3,}/g, "\n\n"); } } const splitAndCapitalize = (text) => { const words = text.split(/[-_]+/); const capitalizedWords = []; for (const word of words) { capitalizedWords.push(word.charAt(0).toUpperCase() + word.slice(1)); } return capitalizedWords.join(" "); }; const heading = (level, text) => { return `${"#".repeat(level)} ${text}`; }; const inlineCode = (text) => { return new Handlebars.SafeString(`\`${text}\``); }; const convertCodeBlock = (codeBlock) => { return new Handlebars.SafeString( ` \`\`\`${codeBlock.language} ${codeBlock.content.join("\n")} \`\`\` `.trim() ); }; const resolveRenderableContent = (description) => { if (!description) { return ""; } function reduceDescription(acc, curr) { if (isEmptyLine(curr)) { return acc + "\n"; } if (isCodeBlock(curr)) { return acc + convertCodeBlock(curr) + "\n"; } if (isInlineCode(curr)) { return acc + inlineCode(curr.content).toString() + " "; } else { return acc + Handlebars.escapeExpression(link(curr)).trim() + " "; } } return description.reduce(reduceDescription, "").trim(); }; const link = (source) => { if (typeof source === "string") { return source; } else { return `[${source.title}](${source.url})`; } }; var __defProp$i = Object.defineProperty; var __defProps$i = Object.defineProperties; var __getOwnPropDescs$i = Object.getOwnPropertyDescriptors; var __getOwnPropSymbols$i = Object.getOwnPropertySymbols; var __hasOwnProp$i = Object.prototype.hasOwnProperty; var __propIsEnum$i = Object.prototype.propertyIsEnumerable; var __defNormalProp$i = (obj, key, value) => key in obj ? __defProp$i(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value; var __spreadValues$i = (a, b) => { for (var prop in b || (b = {})) if (__hasOwnProp$i.call(b, prop)) __defNormalProp$i(a, prop, b[prop]); if (__getOwnPropSymbols$i) for (var prop of __getOwnPropSymbols$i(b)) { if (__propIsEnum$i.call(b, prop)) __defNormalProp$i(a, prop, b[prop]); } return a; }; var __spreadProps$i = (a, b) => __defProps$i(a, __getOwnPropDescs$i(b)); const commonDefaults = { targetDir: "./docs/" }; const markdownAndChangelogDefaults = __spreadProps$i(__spreadValues$i({}, commonDefaults), { scope: ["global"], customObjectVisibility: ["public"], exclude: [] }); const markdownDefaults = __spreadProps$i(__spreadValues$i({}, markdownAndChangelogDe