UNPKG

@cparra/apexdocs

Version:

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

1,467 lines (1,448 loc) 230 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 node_worker_threads = require('node:worker_threads'); var path$1 = require('node:path'); var os = require('node:os'); var fs = require('node:fs'); var Handlebars = require('handlebars'); var boolean = require('fp-ts/boolean'); var A$1 = require('fp-ts/Array'); var fs$1 = 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$1); 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" }, lwc: { exposed: "Exposed", targets: "Targets", targetConfigs: "Target Configs", properties: "Properties" } } }; var __defProp$s = Object.defineProperty; var __getOwnPropSymbols$s = Object.getOwnPropertySymbols; var __hasOwnProp$s = Object.prototype.hasOwnProperty; var __propIsEnum$s = Object.prototype.propertyIsEnumerable; var __defNormalProp$s = (obj, key, value) => key in obj ? __defProp$s(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value; var __spreadValues$s = (a, b) => { for (var prop in b || (b = {})) if (__hasOwnProp$s.call(b, prop)) __defNormalProp$s(a, prop, b[prop]); if (__getOwnPropSymbols$s) for (var prop of __getOwnPropSymbols$s(b)) { if (__propIsEnum$s.call(b, prop)) __defNormalProp$s(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$s({}, 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$r = Object.defineProperty; var __defProps$p = Object.defineProperties; var __getOwnPropDescs$p = Object.getOwnPropertyDescriptors; var __getOwnPropSymbols$r = Object.getOwnPropertySymbols; var __hasOwnProp$r = Object.prototype.hasOwnProperty; var __propIsEnum$r = Object.prototype.propertyIsEnumerable; var __defNormalProp$r = (obj, key, value) => key in obj ? __defProp$r(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value; var __spreadValues$r = (a, b) => { for (var prop in b || (b = {})) if (__hasOwnProp$r.call(b, prop)) __defNormalProp$r(a, prop, b[prop]); if (__getOwnPropSymbols$r) for (var prop of __getOwnPropSymbols$r(b)) { if (__propIsEnum$r.call(b, prop)) __defNormalProp$r(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$r({}, 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$r({}, 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$q = Object.defineProperty; var __defProps$o = Object.defineProperties; var __getOwnPropDescs$o = Object.getOwnPropertyDescriptors; 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; }; 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$q({}, 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$q({}, adaptDescribable(paramAnnotation == null ? void 0 : paramAnnotation.bodyLines, linkGenerator)), { name: param.name, type: linkGenerator(param.typeReference.rawDeclaration) }); } function mapThrows(thrown, linkGenerator) { return __spreadProps$o(__spreadValues$q({}, 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) && !isLwcType(type); } function isTriggerType(type) { return type.type_name === "trigger"; } function isLwcType(type) { return type.type_name === "lwc"; } 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; case "lwc": return config.lwcGroupName; 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$p = Object.defineProperty; var __defProps$n = Object.defineProperties; var __getOwnPropDescs$n = 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$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); case "lwc": return lwcMetadataToRenderable(type, config, translations); } } return __spreadProps$n(__spreadValues$p({}, 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$p({ 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$p({}, adaptDescribable((_a = value.docComment) == null ? void 0 : _a.descriptionLines, linkGenerator)), { value: value.name }); }) } }); } function interfaceTypeToInterfaceSource(interfaceType, linkGenerator, baseHeadingLevel = 1, translations) { return __spreadProps$n(__spreadValues$p({ 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$p({ 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$p({}, 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 lwcMetadataToRenderable(metadata, config, translations) { var _a, _b, _c, _d, _e; function toTargetConfigRenderable(targetConfig) { var _a2, _b2; return { targetName: targetConfig["@_targets"], properties: (_b2 = (_a2 = targetConfig.property) == null ? void 0 : _a2.map((prop) => { var _a3, _b3; return { description: prop["@_description"], required: (_a3 = prop["@_required"]) != null ? _a3 : false, type: prop["@_type"], label: (_b3 = prop["@_label"]) != null ? _b3 : prop["@_name"], name: prop["@_name"] }; })) != null ? _b2 : [] }; } return { type: "lwc", headingLevel: 1, heading: metadata.name, name: metadata.name, description: metadata.description, exposed: metadata.isExposed, targets: { heading: translations.markdown.lwc.targets, headingLevel: 2, value: (_b = (_a = metadata.targets) == null ? void 0 : _a.target) != null ? _b : [] }, targetConfigs: { heading: translations.markdown.lwc.targetConfigs, headingLevel: 2, value: (_e = (_d = (_c = metadata.targetConfigs) == null ? void 0 : _c.targetConfig) == null ? void 0 : _d.map(toTargetConfigRenderable)) != null ? _e : [] }, doc: { group: getTypeGroup(metadata, config) } }; } 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; case "lwc": 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 __async$6 = (__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()); }); }; class WorkerPool { constructor(createWorker, options = {}) { this.nextTaskId = 1; this.terminating = false; this.idleWorkers = []; this.busyWorkers = /* @__PURE__ */ new Set(); this.allWorkers = /* @__PURE__ */ new Set(); this.queue = []; this.inFlightByWorker = /* @__PURE__ */ new Map(); this.createdWorkers = 0; this.completedTasks = 0; this.failedTasks = 0; var _a, _b, _c, _d, _e, _f; this.createWorker = createWorker; const cpuCount = Math.max(1, (_b = (_a = os.cpus()) == null ? void 0 : _a.length) != null ? _b : 1); this.maxWorkers = Math.max(1, (_c = options.maxWorkers) != null ? _c : cpuCount); this.maxQueueSize = (_d = options.maxQueueSize) != null ? _d : Number.POSITIVE_INFINITY; this.drainOnTerminate = (_e = options.drainOnTerminate) != null ? _e : false; this.unrefWorkers = (_f = options.unrefWorkers) != null ? _f : false; } /** * Enqueue a task and resolve with the worker's response `result`. */ run(payload) { if (this.terminating) { return Promise.reject(new Error("WorkerPool is terminating; cannot accept new tasks.")); } if (this.queue.length >= this.maxQueueSize) { return Promise.reject(new Error(`WorkerPool queue limit exceeded (maxQueueSize=${this.maxQueueSize}).`)); } const id = this.nextTaskId++; return new Promise((resolve, reject) => { this.queue.push({ id, payload, resolve, reject }); this.pump(); }); } /** * Terminates all workers and rejects queued tasks (unless drainOnTerminate=true). * * - If `drainOnTerminate` is false (default), queued tasks are rejected immediately, * and in-flight tasks are rejected when each worker is terminated. * - If `drainOnTerminate` is true, the pool stops accepting new tasks and will attempt * to finish queued + in-flight tasks before terminating workers. */ terminate() { return __async$6(this, null, function* () { if (this.terminating) { return; } this.terminating = true; if (!this.drainOnTerminate) { while (this.queue.length) { const task = this.queue.shift(); task.reject(new Error("WorkerPool terminated before task could start.")); this.failedTasks++; } } if (this.drainOnTerminate) { yield this.waitForDrain(); } const terminations = Array.from(this.allWorkers).map((worker) => __async$6(this, null, function* () { this.rejectInFlight(worker, new Error("WorkerPool terminated with task still in flight.")); try { yield worker.terminate(); } catch (e) { } })); yield Promise.all(terminations); this.idleWorkers.length = 0; this.busyWorkers.clear(); this.allWorkers.clear(); this.inFlightByWorker.clear(); }); } /** * Wait until all queued tasks have been processed and no tasks are in flight. * This does NOT terminate workers. */ drain() { return __async$6(this, null, function* () { yield this.waitForDrain(); }); } pump() { if (this.terminating && !this.drainOnTerminate) { return; } while (this.queue.length > 0) { const worker = this.getIdleOrCreateWorker(); if (!worker) { return; } const task = this.queue.shift(); this.assign(worker, task); } } getIdleOrCreateWorker() { const idleWorker = this.idleWorkers.pop(); if (idleWorker) return idleWorker; if (this.allWorkers.size < this.maxWorkers) { return this.spawnWorker(); } return null; } spawnWorker() { const worker = this.createWorker(); this.createdWorkers++; this.allWorkers.add(worker); if (this.unrefWorkers) { worker.unref(); } worker.on("message", (msg) => this.onWorkerMessage(worker, msg)); worker.on("error", (err) => this.onWorkerError(worker, err)); worker.on("exit", (code) => this.onWorkerExit(worker, code)); this.idleWorkers.push(worker); return worker; } assign(worker, task) { this.idleWorkersRemove(worker); this.busyWorkers.add(worker); this.inFlightByWorker.set(worker, { id: task.id, resolve: task.resolve, reject: task.reject }); try { worker.postMessage({ id: task.id, payload: task.payload }); } catch (error) { this.inFlightByWorker.delete(worker); this.busyWorkers.delete(worker); this.idleWorkers.push(worker); task.reject(error); this.failedTasks++; this.pump(); } } onWorkerMessage(worker, msg) { var _a; const inFlight = this.inFlightByWorker.get(worker); if (!inFlight) { return; } const message = msg; const isSameTaskId = typeof (message == null ? void 0 : message.id) === "number" && message.id === inFlight.id; const hasOkFlag = typeof (message == null ? void 0 : message.ok) === "boolean"; if (!isSameTaskId || !hasOkFlag) { this.finishTask(worker); inFlight.reject(new Error("WorkerPool received an invalid response message for the in-flight task.")); this.failedTasks++; this.pump(); return; } this.finishTask(worker); if (message.ok) { this.completedTasks++; inFlight.resolve(message.result); } else { this.failedTasks++; inFlight.reject((_a = message.error) != null ? _a : new Error("Worker indicated failure without an error payload.")); } this.pump(); } onWorkerError(worker, err) { this.rejectInFlight(worker, err); this.removeWorker(worker); this.pump(); } onWorkerExit(worker, code) { this.rejectInFlight(worker, new Error(`Worker exited unexpectedly (code=${code}).`)); this.removeWorker(worker); this.pump(); } finishTask(worker) { this.inFlightByWorker.delete(worker); this.busyWorkers.delete(worker); if (!this.terminating || this.drainOnTerminate) { this.idleWorkers.push(worker); } } rejectInFlight(worker, reason) { const inFlight = this.inFlightByWorker.get(worker); if (!inFlight) return; this.inFlightByWorker.delete(worker); this.busyWorkers.delete(worker); inFlight.reject(reason); this.failedTasks++; } removeWorker(worker) { this.inFlightByWorker.delete(worker); this.busyWorkers.delete(worker); this.idleWorkersRemove(worker); this.allWorkers.delete(worker); } idleWorkersRemove(worker) { const workerIndex = this.idleWorkers.indexOf(worker); if (workerIndex !== -1) { this.idleWorkers.splice(workerIndex, 1); } } waitForDrain() { return __async$6(this, null, function* () { if (this.queue.length === 0 && this.inFlightByWorker.size === 0) { return; } yield new Promise((resolve) => { const tick = () => { this.pump(); if (this.queue.length === 0 && this.inFlightByWorker.size === 0) { resolve(); return; } setTimeout(tick, 10); }; tick(); }); }); } } var __defProp$o = Object.defineProperty; var __defProps$m = Object.defineProperties; var __getOwnPropDescs$m = 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$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()); }); }; const noopReflectionDebugLogger = { onStart: () => { }, onSuccess: () => { }, onFailure: () => { } }; const noopDebugLogger = noopReflectionDebugLogger; function reflectAsync(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 supportsWorkerThreads() { try { return typeof node_worker_threads.Worker === "function"; } catch (e) { return false; } } function isWorkerReflectionEnabled(config) { var _a, _b; const env = ((_a = process.env.APEXDOCS_WORKER_REFLECTION) != null ? _a : "").toLowerCase(); if (env === "true" || env === "1") { return true; } if (env === "false" || env === "0") { return false; } return (_b = config == null ? void 0 : config.parallelReflection) != null ? _b : true; } function getWorkerEntrypointPath() { const candidate = path$1.resolve(__dirname, "./apex-reflection.worker.js"); if (fs.existsSync(candidate)) { return candid