@cparra/apexdocs
Version:
Library with CLI capabilities to generate documentation for Salesforce Apex classes.
1,432 lines (1,388 loc) • 197 kB
JavaScript
'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);
}
const defaultTranslations = {
changelog: {
title: "Changelog",
newClasses: {
heading: "New Classes",
description: "These classes are new."
},
newInterfaces: {
heading: "New Interfaces",
description: "These interfaces are new."
},
newEnums: {
heading: "New Enums",
description: "These enums are new."
},
newCustomObjects: {
heading: "New Custom Objects",
description: "These custom objects are new."
},
newTriggers: {
heading: "New Triggers",
description: "These triggers are new."
},
removedTypes: {
heading: "Removed Types",
description: "These types have been removed."
},
removedCustomObjects: {
heading: "Removed Custom Objects",
description: "These custom objects have been removed."
},
removedTriggers: {
heading: "Removed Triggers",
description: "These triggers have been removed."
},
newOrModifiedMembers: {
heading: "New or Modified Members in Existing Types",
description: "These members have been added or modified."
},
newOrRemovedCustomFields: {
heading: "New or Removed Fields to Custom Objects or Standard Objects",
description: "These custom fields have been added or removed."
},
newOrRemovedCustomMetadataTypeRecords: {
heading: "New or Removed Custom Metadata Type Records",
description: "These custom metadata type records have been added or removed."
},
memberModifications: {
newEnumValue: "New Enum Value",
removedEnumValue: "Removed Enum Value",
newMethod: "New Method",
removedMethod: "Removed Method",
newProperty: "New Property",
removedProperty: "Removed Property",
newField: "New Field",
removedField: "Removed Field",
newType: "New Type",
removedType: "Removed Type",
newCustomMetadataRecord: "New Custom Metadata Record",
removedCustomMetadataRecord: "Removed Custom Metadata Record",
newTrigger: "New Trigger",
removedTrigger: "Removed Trigger"
}
},
markdown: {
sections: {
methods: "Methods",
properties: "Properties",
fields: "Fields",
constructors: "Constructors",
values: "Values",
classes: "Classes",
enums: "Enums",
interfaces: "Interfaces",
namespace: "Namespace",
records: "Records",
publishBehavior: "Publish Behavior"
},
details: {
type: "Type",
signature: "Signature",
group: "Group",
author: "Author",
date: "Date",
see: "See",
possibleValues: "Possible values are",
parameters: "Parameters",
throws: "Throws",
returnType: "Return Type",
apiName: "API Name",
required: "Required",
inlineHelpText: "Inline Help Text",
complianceGroup: "Compliance Group",
securityClassification: "Security Classification",
protected: "Protected"
},
typeSuffixes: {
class: "Class",
interface: "Interface",
enum: "Enum",
trigger: "Trigger"
},
triggerEvents: {
beforeInsert: "Before Insert",
beforeUpdate: "Before Update",
beforeDelete: "Before Delete",
afterInsert: "After Insert",
afterUpdate: "After Update",
afterDelete: "After Delete",
afterUndelete: "After Undelete"
},
publishBehaviors: {
publishImmediately: "Publish Immediately",
publishAfterCommit: "Publish After Commit"
},
inheritance: {
inheritance: "Inheritance",
implements: "Implements"
}
}
};
var __defProp$q = Object.defineProperty;
var __getOwnPropSymbols$q = Object.getOwnPropertySymbols;
var __hasOwnProp$q = Object.prototype.hasOwnProperty;
var __propIsEnum$q = Object.prototype.propertyIsEnumerable;
var __defNormalProp$q = (obj, key, value) => key in obj ? __defProp$q(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
var __spreadValues$q = (a, b) => {
for (var prop in b || (b = {}))
if (__hasOwnProp$q.call(b, prop))
__defNormalProp$q(a, prop, b[prop]);
if (__getOwnPropSymbols$q)
for (var prop of __getOwnPropSymbols$q(b)) {
if (__propIsEnum$q.call(b, prop))
__defNormalProp$q(a, prop, b[prop]);
}
return a;
};
function mergeTranslations(userTranslations) {
if (!userTranslations) {
return defaultTranslations;
}
return JSON.parse(
JSON.stringify(Object.assign({}, defaultTranslations, deepMerge(defaultTranslations, userTranslations)))
);
}
function isObjectWithStringKeys(value) {
return value !== null && typeof value === "object" && !Array.isArray(value);
}
function deepMerge(target, source) {
const result = __spreadValues$q({}, target);
for (const key in source) {
if (Object.prototype.hasOwnProperty.call(source, key)) {
const sourceValue = source[key];
const targetValue = result[key];
if (isObjectWithStringKeys(sourceValue) && isObjectWithStringKeys(targetValue)) {
result[key] = deepMerge(targetValue, sourceValue);
} else if (sourceValue !== void 0) {
result[key] = sourceValue;
}
}
}
return result;
}
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$p = Object.defineProperty;
var __defProps$p = Object.defineProperties;
var __getOwnPropDescs$p = Object.getOwnPropertyDescriptors;
var __getOwnPropSymbols$p = Object.getOwnPropertySymbols;
var __hasOwnProp$p = Object.prototype.hasOwnProperty;
var __propIsEnum$p = Object.prototype.propertyIsEnumerable;
var __defNormalProp$p = (obj, key, value) => key in obj ? __defProp$p(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
var __spreadValues$p = (a, b) => {
for (var prop in b || (b = {}))
if (__hasOwnProp$p.call(b, prop))
__defNormalProp$p(a, prop, b[prop]);
if (__getOwnPropSymbols$p)
for (var prop of __getOwnPropSymbols$p(b)) {
if (__propIsEnum$p.call(b, prop))
__defNormalProp$p(a, prop, b[prop]);
}
return a;
};
var __spreadProps$p = (a, b) => __defProps$p(a, __getOwnPropDescs$p(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$p(__spreadValues$p({}, 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$p(__spreadValues$p({}, 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$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 adaptMethod(method, linkGenerator, baseHeadingLevel, translations) {
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: translations.markdown.details.signature,
value: buildSignature(method)
},
returnType: {
headingLevel: baseHeadingLevel + 1,
heading: translations.markdown.details.returnType,
value: __spreadProps$o(__spreadValues$o({}, 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: translations.markdown.details.throws,
value: (_c = method.docComment) == null ? void 0 : _c.throwsAnnotations.map((thrown) => mapThrows(thrown, linkGenerator))
},
parameters: {
headingLevel: baseHeadingLevel + 1,
heading: translations.markdown.details.parameters,
value: method.parameters.map((param) => mapParameters(method, param, linkGenerator))
},
inherited: method.inherited
};
}
function adaptConstructor(typeName, constructor, linkGenerator, baseHeadingLevel, translations) {
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: translations.markdown.details.signature,
value: buildSignature(typeName, constructor)
},
parameters: {
headingLevel: baseHeadingLevel + 1,
heading: translations.markdown.details.parameters,
value: constructor.parameters.map((param) => mapParameters(constructor, param, linkGenerator))
},
throws: {
headingLevel: baseHeadingLevel + 1,
heading: translations.markdown.details.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$o(__spreadValues$o({}, adaptDescribable(paramAnnotation == null ? void 0 : paramAnnotation.bodyLines, linkGenerator)), {
name: param.name,
type: linkGenerator(param.typeReference.rawDeclaration)
});
}
function mapThrows(thrown, linkGenerator) {
return __spreadProps$o(__spreadValues$o({}, adaptDescribable(thrown.bodyLines, linkGenerator)), {
type: linkGenerator(thrown.exceptionName)
});
}
function adaptFieldOrProperty(field, linkGenerator, baseHeadingLevel, translations) {
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: translations.markdown.details.type,
value: linkGenerator(field.typeReference.rawDeclaration)
},
inherited: field.inherited,
accessModifier: field.access_modifier,
signature: {
headingLevel: baseHeadingLevel + 1,
heading: translations.markdown.details.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$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 typeToRenderable$1(parsedFile, linkGenerator, config, translations) {
function getRenderable() {
const { type } = parsedFile;
switch (type.type_name) {
case "enum":
return enumTypeToEnumSource(type, linkGenerator, 1, translations);
case "interface":
return interfaceTypeToInterfaceSource(type, linkGenerator, 1, translations);
case "class":
return classTypeToClassSource(type, linkGenerator, 1, translations);
case "trigger":
return triggerMetadataToRenderable(type, linkGenerator, 1, translations);
case "customobject":
return objectMetadataToRenderable(type, config, translations);
}
}
return __spreadProps$n(__spreadValues$n({}, getRenderable()), {
filePath: isInSource(parsedFile.source) ? parsedFile.source.filePath : void 0,
namespace: config.namespace
});
}
function baseTypeAdapter(type, linkGenerator, baseHeadingLevel, translations) {
function getHeading(type2) {
const suffixMap = {
class: translations.markdown.typeSuffixes.class,
interface: translations.markdown.typeSuffixes.interface,
enum: translations.markdown.typeSuffixes.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, translations) {
return __spreadProps$n(__spreadValues$n({
type: "enum"
}, baseTypeAdapter(enumType, linkGenerator, baseHeadingLevel, translations)), {
values: {
headingLevel: baseHeadingLevel + 1,
heading: translations.markdown.sections.values,
value: enumType.values.map((value) => {
var _a;
return __spreadProps$n(__spreadValues$n({}, adaptDescribable((_a = value.docComment) == null ? void 0 : _a.descriptionLines, linkGenerator)), {
value: value.name
});
})
}
});
}
function interfaceTypeToInterfaceSource(interfaceType, linkGenerator, baseHeadingLevel = 1, translations) {
return __spreadProps$n(__spreadValues$n({
type: "interface"
}, baseTypeAdapter(interfaceType, linkGenerator, baseHeadingLevel, translations)), {
extends: interfaceType.extended_interfaces.map(linkGenerator),
methods: {
headingLevel: baseHeadingLevel + 1,
heading: translations.markdown.sections.methods,
value: interfaceType.methods.map(
(method) => adaptMethod(method, linkGenerator, baseHeadingLevel + 2, translations)
)
}
});
}
function classTypeToClassSource(classType, linkGenerator, baseHeadingLevel = 1, translations) {
return __spreadProps$n(__spreadValues$n({
type: "class"
}, baseTypeAdapter(classType, linkGenerator, baseHeadingLevel, translations)), {
classModifier: classType.classModifier,
sharingModifier: classType.sharingModifier,
implements: classType.implemented_interfaces.map(linkGenerator),
extends: classType.inheritanceChain.map(linkGenerator),
methods: adaptMembers(
translations.markdown.sections.methods,
classType.methods,
adaptMethod,
linkGenerator,
baseHeadingLevel + 1,
translations
),
constructors: adaptMembers(
translations.markdown.sections.constructors,
classType.constructors,
(constructor, linkGenerator2, baseHeadingLevel2, translations2) => adaptConstructor(classType.name, constructor, linkGenerator2, baseHeadingLevel2, translations2),
linkGenerator,
baseHeadingLevel + 1,
translations
),
fields: adaptMembers(
translations.markdown.sections.fields,
classType.fields,
adaptFieldOrProperty,
linkGenerator,
baseHeadingLevel + 1,
translations
),
properties: adaptMembers(
translations.markdown.sections.properties,
classType.properties,
adaptFieldOrProperty,
linkGenerator,
baseHeadingLevel + 1,
translations
),
innerClasses: {
headingLevel: baseHeadingLevel + 1,
heading: translations.markdown.sections.classes,
value: classType.classes.map(
(innerClass) => classTypeToClassSource(
__spreadProps$n(__spreadValues$n({}, innerClass), { inheritanceChain: [] }),
linkGenerator,
baseHeadingLevel + 2,
translations
)
)
},
innerEnums: {
headingLevel: baseHeadingLevel + 1,
heading: translations.markdown.sections.enums,
value: classType.enums.map(
(innerEnum) => enumTypeToEnumSource(innerEnum, linkGenerator, baseHeadingLevel + 2, translations)
)
},
innerInterfaces: {
headingLevel: baseHeadingLevel + 1,
heading: translations.markdown.sections.interfaces,
value: classType.interfaces.map(
(innerInterface) => interfaceTypeToInterfaceSource(innerInterface, linkGenerator, baseHeadingLevel + 2, translations)
)
}
});
}
function adaptMembers(heading, members, adapter, linkFromTypeNameGenerator, headingLevel, translations) {
return {
headingLevel,
heading,
isGrouped: hasGroup(members),
value: hasGroup(members) ? toGroupedMembers(members, adapter, linkFromTypeNameGenerator, headingLevel + 1, translations) : toFlat(members, adapter, linkFromTypeNameGenerator, headingLevel + 1, translations)
};
}
function hasGroup(members) {
return members.some((member) => member.group);
}
function toFlat(members, adapter, linkGenerator, baseHeadingLevel, translations) {
return members.map((member) => adapter(member, linkGenerator, baseHeadingLevel, translations));
}
function toGroupedMembers(members, adapter, linkGenerator, baseHeadingLevel, translations) {
const groupedMembers = groupByGroupName(members);
return Object.entries(groupedMembers).map(
([groupName, members2]) => singleGroup(baseHeadingLevel, groupName, adapter, members2, linkGenerator, translations)
);
}
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, translations) {
return {
headingLevel,
heading: groupName,
groupDescription: members[0].groupDescription,
// All fields in the group have the same description
value: toFlat(members, adapter, linkGenerator, headingLevel + 1, translations)
};
}
function triggerMetadataToRenderable(triggerMetadata, linkGenerator, baseHeadingLevel = 1, translations) {
function formatEvent(event) {
switch (event) {
case "beforeinsert":
return translations.markdown.triggerEvents.beforeInsert;
case "beforeupdate":
return translations.markdown.triggerEvents.beforeUpdate;
case "beforedelete":
return translations.markdown.triggerEvents.beforeDelete;
case "afterinsert":
return translations.markdown.triggerEvents.afterInsert;
case "afterupdate":
return translations.markdown.triggerEvents.afterUpdate;
case "afterdelete":
return translations.markdown.triggerEvents.afterDelete;
case "afterundelete":
return translations.markdown.triggerEvents.afterUndelete;
default:
return event;
}
}
return {
doc: adaptDocumentable(
{
docComment: triggerMetadata.docComment,
annotations: []
},
linkGenerator,
baseHeadingLevel + 1
),
name: triggerMetadata.name,
type: "trigger",
headingLevel: 1,
heading: triggerMetadata.name + " " + translations.markdown.typeSuffixes.trigger,
objectName: triggerMetadata.object_name,
events: triggerMetadata.events.map(formatEvent)
};
}
function objectMetadataToRenderable(objectMetadata, config, translations) {
var _a;
function toRenderablePublishBehavior(publishBehavior) {
switch (publishBehavior) {
case "PublishImmediately":
return translations.markdown.publishBehaviors.publishImmediately;
case "PublishAfterCommit":
return translations.markdown.publishBehaviors.publishAfterCommit;
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: translations.markdown.sections.fields,
value: objectMetadata.fields.map((field) => fieldMetadataToRenderable(field, config, 3, translations))
},
hasRecords: objectMetadata.metadataRecords.length > 0,
metadataRecords: {
headingLevel: 2,
heading: translations.markdown.sections.records,
value: objectMetadata.metadataRecords.map((metadata) => customMetadataToRenderable(metadata, 3))
},
publishBehavior: toRenderablePublishBehavior(objectMetadata.publishBehavior)
};
}
function fieldMetadataToRenderable(field, config, headingLevel, translations) {
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,
complianceGroup: renderComplianceGroup(field.complianceGroup, config),
securityClassification: renderComplianceGroup(field.securityClassification, config),
inlineHelpText: renderInlineHelpText(field.inlineHelpText, config),
pickListValues: field.pickListValues ? {
headingLevel: headingLevel + 1,
heading: translations.markdown.details.possibleValues,
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;
}
function renderComplianceGroup(complianceGroup, config) {
if (config.includeFieldSecurityMetadata) {
return complianceGroup;
} else {
return null;
}
}
function renderInlineHelpText(inlineHelpText, config) {
if (config.includeInlineHelpTextMetadata) {
return inlineHelpText;
} else {
return null;
}
}
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, translations) {
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,
translations
);
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$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));
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$m(__spreadValues$m({}, 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$m(__spreadValues$m({}, 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$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));
const addInheritanceChainToTypes = (parsedFiles) => parsedFiles.map((parsedFile) => __spreadProps$l(__spreadValues$l({}, 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$l(__spreadValues$l({}, current), {
inheritanceChain
});
}
}
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 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$k(__spreadValues$k({}, 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$k(__spreadValues$k({}, interfaceMirror), {
methods: parents.reduce(
(acc, currentValue) => [
...acc,
...currentValue.methods.filter((method) => !methodAlreadyExists(method.name, acc)).map((method) => __spreadProps$k(__spreadValues$k({}, 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$k(__spreadValues$k({}, member), {
inherited: true
}));
}
const parents = getParents(parentExtractor, classMirror, repository);
return __spreadProps$k(__spreadValues$k({}, 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}}
**{{@root.translations.markdown.details.group}}** {{doc.group}}
{{/if}}
{{#if doc.author}}
**{{@root.translations.markdown.details.author}}** {{doc.author}}
{{/if}}
{{#if doc.date}}
**{{@root.translations.markdown.details.date}}** {{doc.date}}
{{/if}}
{{#each doc.sees}}
**{{@root.translations.markdown.details.see}}** {{link this}}
{{/each}}
{{#if namespace}}
## {{@root.translations.markdown.sections.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.typ