@cparra/apexdocs 2.25.0-alpha.0 → 2.25.0-alpha.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (215) hide show
  1. package/__mocks__/chalk.js +12 -0
  2. package/__mocks__/log-update.js +6 -0
  3. package/eslint.config.mjs +10 -0
  4. package/examples/plain-markdown/docs/Miscellaneous/ns.BaseClass.md +16 -0
  5. package/examples/plain-markdown/docs/Miscellaneous/ns.MultiInheritanceClass.md +73 -0
  6. package/examples/plain-markdown/docs/Miscellaneous/ns.ParentInterface.md +15 -0
  7. package/examples/plain-markdown/docs/Miscellaneous/ns.ReferencedEnum.md +8 -0
  8. package/examples/plain-markdown/docs/Miscellaneous/ns.SampleException.md +7 -0
  9. package/examples/plain-markdown/docs/Miscellaneous/ns.SampleInterface.md +115 -0
  10. package/examples/plain-markdown/docs/Sample-Enums/ns.SampleEnum.md +36 -0
  11. package/examples/plain-markdown/docs/SampleGroup/ns.SampleClass.md +173 -0
  12. package/examples/plain-markdown/docs/index.md +33 -0
  13. package/examples/plain-markdown/force-app/classes/MultiInheritanceClass.cls +1 -0
  14. package/examples/plain-markdown/force-app/classes/SampleClass.cls +37 -0
  15. package/examples/plain-markdown/package.json +2 -6
  16. package/jest.config.js +4 -0
  17. package/jest.d.ts +7 -0
  18. package/lib/__spec__/core/expect-extensions.d.ts +3 -0
  19. package/lib/__spec__/core/expect-extensions.js +54 -0
  20. package/lib/__spec__/core/expect-extensions.js.map +1 -0
  21. package/lib/__spec__/core/generating-class-docs.spec.d.ts +1 -0
  22. package/lib/__spec__/core/generating-class-docs.spec.js +427 -0
  23. package/lib/__spec__/core/generating-class-docs.spec.js.map +1 -0
  24. package/lib/__spec__/core/generating-enum-docs.spec.d.ts +1 -0
  25. package/lib/__spec__/core/generating-enum-docs.spec.js +303 -0
  26. package/lib/__spec__/core/generating-enum-docs.spec.js.map +1 -0
  27. package/lib/__spec__/core/generating-interface-docs.spec.d.ts +1 -0
  28. package/lib/__spec__/core/generating-interface-docs.spec.js +361 -0
  29. package/lib/__spec__/core/generating-interface-docs.spec.js.map +1 -0
  30. package/lib/__spec__/core/generating-reference-guide.spec.d.ts +1 -0
  31. package/lib/__spec__/core/generating-reference-guide.spec.js +161 -0
  32. package/lib/__spec__/core/generating-reference-guide.spec.js.map +1 -0
  33. package/lib/adapters/apex-types.d.ts +5 -5
  34. package/lib/adapters/apex-types.js +97 -22
  35. package/lib/adapters/apex-types.js.map +1 -1
  36. package/lib/adapters/documentables.d.ts +4 -3
  37. package/lib/adapters/documentables.js +23 -8
  38. package/lib/adapters/documentables.js.map +1 -1
  39. package/lib/adapters/fields-and-properties.d.ts +4 -3
  40. package/lib/adapters/fields-and-properties.js +26 -5
  41. package/lib/adapters/fields-and-properties.js.map +1 -1
  42. package/lib/adapters/methods-and-constructors.d.ts +4 -3
  43. package/lib/adapters/methods-and-constructors.js +54 -12
  44. package/lib/adapters/methods-and-constructors.js.map +1 -1
  45. package/lib/adapters/references.d.ts +1 -1
  46. package/lib/adapters/references.js +3 -3
  47. package/lib/adapters/references.js.map +1 -1
  48. package/lib/adapters/type-utils.d.ts +1 -1
  49. package/lib/adapters/type-utils.js +1 -2
  50. package/lib/adapters/type-utils.js.map +1 -1
  51. package/lib/application/Apexdocs.js +21 -15
  52. package/lib/application/Apexdocs.js.map +1 -1
  53. package/lib/application/flows/generate-markdown-files.d.ts +3 -0
  54. package/lib/application/flows/generate-markdown-files.js +57 -0
  55. package/lib/application/flows/generate-markdown-files.js.map +1 -0
  56. package/lib/cli/generate.js +7 -7
  57. package/lib/cli/generate.js.map +1 -1
  58. package/lib/core/__test__/inheritance-chain.test.d.ts +1 -0
  59. package/lib/core/__test__/inheritance-chain.test.js +42 -0
  60. package/lib/core/__test__/inheritance-chain.test.js.map +1 -0
  61. package/lib/core/generate-docs.d.ts +24 -0
  62. package/lib/core/generate-docs.js +267 -0
  63. package/lib/core/generate-docs.js.map +1 -0
  64. package/lib/core/inheritance-chain.d.ts +2 -0
  65. package/lib/core/inheritance-chain.js +35 -0
  66. package/lib/core/inheritance-chain.js.map +1 -0
  67. package/lib/core/template.d.ts +10 -0
  68. package/lib/core/template.js +92 -0
  69. package/lib/core/template.js.map +1 -0
  70. package/lib/core/templates/reference-guide.d.ts +1 -0
  71. package/lib/core/templates/reference-guide.js +18 -0
  72. package/lib/core/templates/reference-guide.js.map +1 -0
  73. package/lib/index.d.ts +2 -1
  74. package/lib/index.js +14 -3
  75. package/lib/index.js.map +1 -1
  76. package/lib/model/inheritance.d.ts +4 -1
  77. package/lib/model/manifest.js +8 -2
  78. package/lib/model/manifest.js.map +1 -1
  79. package/lib/model/markdown-file.d.ts +2 -2
  80. package/lib/model/markdown-file.js +5 -4
  81. package/lib/model/markdown-file.js.map +1 -1
  82. package/lib/model/markdown-generation-util/doc-comment-annotation-util.js +3 -4
  83. package/lib/model/markdown-generation-util/doc-comment-annotation-util.js.map +1 -1
  84. package/lib/model/markdown-generation-util/field-declaration-util.js +1 -2
  85. package/lib/model/markdown-generation-util/field-declaration-util.js.map +1 -1
  86. package/lib/model/markdown-generation-util/method-declaration-util.js +2 -3
  87. package/lib/model/markdown-generation-util/method-declaration-util.js.map +1 -1
  88. package/lib/model/markdown-generation-util/type-declaration-util.js +1 -2
  89. package/lib/model/markdown-generation-util/type-declaration-util.js.map +1 -1
  90. package/lib/model/markdown-home-file.js.map +1 -1
  91. package/lib/model/markdown-type-file.js.map +1 -1
  92. package/lib/model/openapi/open-api.js.map +1 -1
  93. package/lib/model/outputFile.d.ts +1 -1
  94. package/lib/model/outputFile.js +2 -9
  95. package/lib/model/outputFile.js.map +1 -1
  96. package/lib/model/types-repository.js.map +1 -1
  97. package/lib/service/apex-file-reader.js.map +1 -1
  98. package/lib/service/file-writer.js.map +1 -1
  99. package/lib/service/manifest-factory.js +1 -2
  100. package/lib/service/manifest-factory.js.map +1 -1
  101. package/lib/service/metadata-processor.js.map +1 -1
  102. package/lib/service/parser.js +1 -1
  103. package/lib/service/parser.js.map +1 -1
  104. package/lib/service/state.js.map +1 -1
  105. package/lib/service/walkers/class-walker.js.map +1 -1
  106. package/lib/service/walkers/interface-walker.js.map +1 -1
  107. package/lib/service/walkers/walker-factory.js.map +1 -1
  108. package/lib/service/walkers/walker.js.map +1 -1
  109. package/lib/settings.d.ts +0 -6
  110. package/lib/settings.js +0 -11
  111. package/lib/settings.js.map +1 -1
  112. package/lib/test-helpers/ClassMirrorBuilder.d.ts +4 -0
  113. package/lib/test-helpers/ClassMirrorBuilder.js +11 -1
  114. package/lib/test-helpers/ClassMirrorBuilder.js.map +1 -1
  115. package/lib/transpiler/factory.js.map +1 -1
  116. package/lib/transpiler/markdown/class-file-generatorHelper.d.ts +1 -1
  117. package/lib/transpiler/markdown/class-file-generatorHelper.js.map +1 -1
  118. package/lib/transpiler/markdown/jekyll/jekyll-docsProcessor.js.map +1 -1
  119. package/lib/transpiler/markdown/plain-markdown/class-template.js +53 -12
  120. package/lib/transpiler/markdown/plain-markdown/class-template.js.map +1 -1
  121. package/lib/transpiler/markdown/plain-markdown/constructors-partial-template.js +13 -16
  122. package/lib/transpiler/markdown/plain-markdown/constructors-partial-template.js.map +1 -1
  123. package/lib/transpiler/markdown/plain-markdown/documentable-partial-template.js +11 -8
  124. package/lib/transpiler/markdown/plain-markdown/documentable-partial-template.js.map +1 -1
  125. package/lib/transpiler/markdown/plain-markdown/enum-template.js +7 -6
  126. package/lib/transpiler/markdown/plain-markdown/enum-template.js.map +1 -1
  127. package/lib/transpiler/markdown/plain-markdown/fieldsPartialTemplate.js +9 -6
  128. package/lib/transpiler/markdown/plain-markdown/fieldsPartialTemplate.js.map +1 -1
  129. package/lib/transpiler/markdown/plain-markdown/grouped-members-partial-template.d.ts +1 -0
  130. package/lib/transpiler/markdown/plain-markdown/grouped-members-partial-template.js +10 -0
  131. package/lib/transpiler/markdown/plain-markdown/grouped-members-partial-template.js.map +1 -0
  132. package/lib/transpiler/markdown/plain-markdown/interface-template.js +4 -4
  133. package/lib/transpiler/markdown/plain-markdown/methods-partial-template.js +18 -20
  134. package/lib/transpiler/markdown/plain-markdown/methods-partial-template.js.map +1 -1
  135. package/lib/transpiler/markdown/plain-markdown/plain-docsProcessor.d.ts +0 -4
  136. package/lib/transpiler/markdown/plain-markdown/plain-docsProcessor.js +6 -86
  137. package/lib/transpiler/markdown/plain-markdown/plain-docsProcessor.js.map +1 -1
  138. package/lib/transpiler/markdown/plain-markdown/type-doc-partial.d.ts +1 -0
  139. package/lib/transpiler/markdown/plain-markdown/type-doc-partial.js +31 -0
  140. package/lib/transpiler/markdown/plain-markdown/type-doc-partial.js.map +1 -0
  141. package/lib/transpiler/openapi/open-api-docs-processor.js.map +1 -1
  142. package/lib/transpiler/openapi/parsers/Builder.js.map +1 -1
  143. package/lib/transpiler/openapi/parsers/MethodParser.js.map +1 -1
  144. package/lib/transpiler/openapi/parsers/ReferenceBuilder.js +3 -2
  145. package/lib/transpiler/openapi/parsers/ReferenceBuilder.js.map +1 -1
  146. package/lib/transpiler/openapi/parsers/ResponsesBuilder.js.map +1 -1
  147. package/lib/transpiler/transpiler.js.map +1 -1
  148. package/lib/util/error-logger.js.map +1 -1
  149. package/lib/util/logger.js +1 -1
  150. package/lib/util/logger.js.map +1 -1
  151. package/lib/util/string-utils.js +2 -2
  152. package/lib/util/string-utils.js.map +1 -1
  153. package/package.json +17 -17
  154. package/src/__spec__/core/expect-extensions.ts +32 -0
  155. package/src/__spec__/core/generating-class-docs.spec.ts +511 -0
  156. package/src/__spec__/core/generating-enum-docs.spec.ts +355 -0
  157. package/src/__spec__/core/generating-interface-docs.spec.ts +431 -0
  158. package/src/__spec__/core/generating-reference-guide.spec.ts +163 -0
  159. package/src/adapters/__tests__/interface-adapter.spec.ts +15 -11
  160. package/src/adapters/__tests__/references.spec.ts +1 -1
  161. package/src/adapters/apex-types.ts +205 -41
  162. package/src/adapters/documentables.ts +44 -9
  163. package/src/adapters/fields-and-properties.ts +31 -7
  164. package/src/adapters/methods-and-constructors.ts +65 -22
  165. package/src/adapters/references.ts +1 -1
  166. package/src/adapters/type-utils.ts +1 -1
  167. package/src/application/Apexdocs.ts +21 -15
  168. package/src/application/flows/generate-markdown-files.ts +47 -0
  169. package/src/cli/generate.ts +96 -96
  170. package/src/core/__test__/inheritance-chain.test.ts +54 -0
  171. package/src/core/generate-docs.ts +396 -0
  172. package/src/core/inheritance-chain.ts +23 -0
  173. package/src/core/renderable/types.d.ts +131 -0
  174. package/src/core/template.ts +108 -0
  175. package/src/core/templates/reference-guide.ts +14 -0
  176. package/src/index.ts +3 -1
  177. package/src/model/inheritance.ts +2 -1
  178. package/src/model/manifest.ts +12 -2
  179. package/src/model/markdown-file.ts +5 -4
  180. package/src/model/markdown-generation-util/doc-comment-annotation-util.ts +1 -1
  181. package/src/model/markdown-generation-util/method-declaration-util.ts +1 -1
  182. package/src/model/outputFile.ts +2 -11
  183. package/src/service/parser.ts +1 -1
  184. package/src/settings.ts +0 -15
  185. package/src/test-helpers/ClassMirrorBuilder.ts +14 -1
  186. package/src/transpiler/markdown/class-file-generatorHelper.ts +1 -1
  187. package/src/transpiler/markdown/plain-markdown/class-template.ts +53 -12
  188. package/src/transpiler/markdown/plain-markdown/constructors-partial-template.ts +13 -16
  189. package/src/transpiler/markdown/plain-markdown/documentable-partial-template.ts +11 -8
  190. package/src/transpiler/markdown/plain-markdown/enum-template.ts +7 -6
  191. package/src/transpiler/markdown/plain-markdown/fieldsPartialTemplate.ts +9 -6
  192. package/src/transpiler/markdown/plain-markdown/grouped-members-partial-template.ts +6 -0
  193. package/src/transpiler/markdown/plain-markdown/interface-template.ts +4 -4
  194. package/src/transpiler/markdown/plain-markdown/methods-partial-template.ts +18 -20
  195. package/src/transpiler/markdown/plain-markdown/plain-docsProcessor.ts +8 -100
  196. package/src/transpiler/markdown/plain-markdown/type-doc-partial.ts +27 -0
  197. package/src/transpiler/openapi/parsers/ReferenceBuilder.ts +3 -2
  198. package/src/util/logger.ts +1 -1
  199. package/tsconfig.json +1 -1
  200. package/.eslintrc.js +0 -12
  201. package/examples/plain-markdown/README.md +0 -301
  202. package/lib/templating/compile.d.ts +0 -7
  203. package/lib/templating/compile.js +0 -98
  204. package/lib/templating/compile.js.map +0 -1
  205. package/lib/templating/helpers.d.ts +0 -2
  206. package/lib/templating/helpers.js +0 -18
  207. package/lib/templating/helpers.js.map +0 -1
  208. package/lib/transpiler/markdown/plain-markdown/type-level-apex-doc-partial-template.d.ts +0 -1
  209. package/lib/transpiler/markdown/plain-markdown/type-level-apex-doc-partial-template.js +0 -31
  210. package/lib/transpiler/markdown/plain-markdown/type-level-apex-doc-partial-template.js.map +0 -1
  211. package/src/templating/__tests__/compile.spec.ts +0 -741
  212. package/src/templating/compile.ts +0 -187
  213. package/src/templating/helpers.ts +0 -14
  214. package/src/templating/types.d.ts +0 -104
  215. package/src/transpiler/markdown/plain-markdown/type-level-apex-doc-partial-template.ts +0 -27
@@ -1,67 +1,231 @@
1
1
  import { ClassMirror, EnumMirror, InterfaceMirror, Type } from '@cparra/apex-reflection';
2
- import { BaseTypeSource, ClassSource, EnumSource, InterfaceSource } from '../templating/types';
2
+ import {
3
+ RenderableType,
4
+ RenderableClass,
5
+ RenderableEnum,
6
+ RenderableInterface,
7
+ Renderable,
8
+ RenderableSection,
9
+ GroupedMember,
10
+ } from '../core/renderable/types';
3
11
  import { adaptDescribable, adaptDocumentable } from './documentables';
4
- import { linkFromTypeNameGenerator } from './references';
5
- import { FieldMirrorWithInheritance } from '../model/inheritance';
12
+ import { GetRenderableContentByTypeName } from './references';
13
+ import {
14
+ ClassMirrorWithInheritanceChain,
15
+ FieldMirrorWithInheritance,
16
+ PropertyMirrorWithInheritance,
17
+ } from '../model/inheritance';
6
18
  import { adaptConstructor, adaptMethod } from './methods-and-constructors';
7
- import { adaptField } from './fields-and-properties';
19
+ import { adaptFieldOrProperty } from './fields-and-properties';
8
20
 
9
- function baseTypeAdapter(type: EnumMirror | InterfaceMirror | ClassMirror): BaseTypeSource {
10
- function extractAnnotationBody(type: Type, annotationName: string): string | undefined {
11
- return type.docComment?.annotations.find(
12
- (currentAnnotation) => currentAnnotation.name.toLowerCase() === annotationName,
13
- )?.body;
21
+ export function typeToRenderableType(
22
+ type: Type,
23
+ linkGenerator: GetRenderableContentByTypeName,
24
+ namespace?: string,
25
+ ): Renderable {
26
+ function getRenderable() {
27
+ switch (type.type_name) {
28
+ case 'enum':
29
+ return enumTypeToEnumSource(type as EnumMirror, linkGenerator);
30
+ case 'interface':
31
+ return interfaceTypeToInterfaceSource(type as InterfaceMirror, linkGenerator);
32
+ case 'class':
33
+ return classTypeToClassSource(type as ClassMirrorWithInheritanceChain, linkGenerator);
34
+ }
14
35
  }
15
36
 
16
- function extractSeeAnnotations(type: Type): string[] {
17
- return (
18
- type.docComment?.annotations
19
- .filter((currentAnnotation) => currentAnnotation.name.toLowerCase() === 'see')
20
- .map((currentAnnotation) => currentAnnotation.body) ?? []
21
- );
37
+ return {
38
+ ...getRenderable(),
39
+ namespace,
40
+ };
41
+ }
42
+
43
+ function baseTypeAdapter(
44
+ type: EnumMirror | InterfaceMirror | ClassMirror,
45
+ linkGenerator: GetRenderableContentByTypeName,
46
+ baseHeadingLevel: number,
47
+ ): RenderableType {
48
+ function getHeading(type: Type): string {
49
+ const suffixMap = {
50
+ class: 'Class',
51
+ interface: 'Interface',
52
+ enum: 'Enum',
53
+ };
54
+
55
+ return `${type.name} ${suffixMap[type.type_name]}`;
22
56
  }
23
57
 
24
58
  return {
25
- ...adaptDocumentable(type),
26
- accessModifier: type.access_modifier,
59
+ headingLevel: baseHeadingLevel,
60
+ heading: getHeading(type),
61
+ doc: adaptDocumentable(type, linkGenerator, baseHeadingLevel + 1),
27
62
  name: type.name,
28
- group: extractAnnotationBody(type, 'group'),
29
- author: extractAnnotationBody(type, 'author'),
30
- date: extractAnnotationBody(type, 'date'),
31
- sees: extractSeeAnnotations(type).map(linkFromTypeNameGenerator),
63
+ meta: {
64
+ accessModifier: type.access_modifier,
65
+ },
32
66
  };
33
67
  }
34
68
 
35
- export function enumTypeToEnumSource(enumType: EnumMirror): EnumSource {
69
+ function enumTypeToEnumSource(
70
+ enumType: EnumMirror,
71
+ linkGenerator: GetRenderableContentByTypeName,
72
+ baseHeadingLevel: number = 1,
73
+ ): RenderableEnum {
36
74
  return {
37
- __type: 'enum',
38
- ...baseTypeAdapter(enumType),
39
- values: enumType.values.map((value) => ({
40
- ...adaptDescribable(value.docComment?.descriptionLines),
41
- value: value.name,
42
- })),
75
+ type: 'enum',
76
+ ...baseTypeAdapter(enumType, linkGenerator, baseHeadingLevel),
77
+ values: {
78
+ headingLevel: baseHeadingLevel + 1,
79
+ heading: 'Values',
80
+ value: enumType.values.map((value) => ({
81
+ ...adaptDescribable(value.docComment?.descriptionLines, linkGenerator),
82
+ value: value.name,
83
+ })),
84
+ },
43
85
  };
44
86
  }
45
87
 
46
- export function interfaceTypeToInterfaceSource(interfaceType: InterfaceMirror): InterfaceSource {
88
+ export function interfaceTypeToInterfaceSource(
89
+ interfaceType: InterfaceMirror,
90
+ linkGenerator: GetRenderableContentByTypeName,
91
+ baseHeadingLevel: number = 1,
92
+ ): RenderableInterface {
47
93
  return {
48
- __type: 'interface',
49
- ...baseTypeAdapter(interfaceType),
50
- extends: interfaceType.extended_interfaces.map(linkFromTypeNameGenerator),
51
- methods: interfaceType.methods.map(adaptMethod),
94
+ type: 'interface',
95
+ ...baseTypeAdapter(interfaceType, linkGenerator, baseHeadingLevel),
96
+ extends: interfaceType.extended_interfaces.map(linkGenerator),
97
+ methods: {
98
+ headingLevel: baseHeadingLevel + 1,
99
+ heading: 'Methods',
100
+ value: interfaceType.methods.map((method) => adaptMethod(method, linkGenerator, baseHeadingLevel + 2)),
101
+ },
52
102
  };
53
103
  }
54
104
 
55
- export function classTypeToClassSource(classType: ClassMirror): ClassSource {
105
+ function classTypeToClassSource(
106
+ classType: ClassMirrorWithInheritanceChain,
107
+ linkGenerator: GetRenderableContentByTypeName,
108
+ baseHeadingLevel: number = 1,
109
+ ): RenderableClass {
56
110
  return {
57
- __type: 'class',
58
- ...baseTypeAdapter(classType),
111
+ type: 'class',
112
+ ...baseTypeAdapter(classType, linkGenerator, baseHeadingLevel),
59
113
  classModifier: classType.classModifier,
60
114
  sharingModifier: classType.sharingModifier,
61
- implements: classType.implemented_interfaces.map(linkFromTypeNameGenerator),
62
- extends: classType.extended_class ? linkFromTypeNameGenerator(classType.extended_class) : undefined,
63
- methods: classType.methods.map(adaptMethod),
64
- constructors: classType.constructors.map((constructor) => adaptConstructor(classType.name, constructor)),
65
- fields: classType.fields.map((field) => adaptField(field as FieldMirrorWithInheritance)),
115
+ implements: classType.implemented_interfaces.map(linkGenerator),
116
+ extends: classType.inheritanceChain.map(linkGenerator),
117
+ methods: adaptMembers('Methods', classType.methods, adaptMethod, linkGenerator, baseHeadingLevel + 1),
118
+ constructors: adaptMembers(
119
+ 'Constructors',
120
+ classType.constructors,
121
+ (constructor, linkGenerator, baseHeadingLevel) =>
122
+ adaptConstructor(classType.name, constructor, linkGenerator, baseHeadingLevel),
123
+ linkGenerator,
124
+ baseHeadingLevel + 1,
125
+ ),
126
+ fields: adaptMembers(
127
+ 'Fields',
128
+ classType.fields as FieldMirrorWithInheritance[],
129
+ adaptFieldOrProperty,
130
+ linkGenerator,
131
+ baseHeadingLevel + 1,
132
+ ),
133
+ properties: adaptMembers(
134
+ 'Properties',
135
+ classType.properties as PropertyMirrorWithInheritance[],
136
+ adaptFieldOrProperty,
137
+ linkGenerator,
138
+ baseHeadingLevel + 1,
139
+ ),
140
+ innerClasses: {
141
+ headingLevel: baseHeadingLevel + 1,
142
+ heading: 'Classes',
143
+ value: classType.classes.map((innerClass) =>
144
+ classTypeToClassSource({ ...innerClass, inheritanceChain: [] }, linkGenerator, baseHeadingLevel + 2),
145
+ ),
146
+ },
147
+ innerEnums: {
148
+ headingLevel: baseHeadingLevel + 1,
149
+ heading: 'Enums',
150
+ value: classType.enums.map((innerEnum) => enumTypeToEnumSource(innerEnum, linkGenerator, baseHeadingLevel + 2)),
151
+ },
152
+ innerInterfaces: {
153
+ headingLevel: baseHeadingLevel + 1,
154
+ heading: 'Interfaces',
155
+ value: classType.interfaces.map((innerInterface) =>
156
+ interfaceTypeToInterfaceSource(innerInterface, linkGenerator, baseHeadingLevel + 2),
157
+ ),
158
+ },
159
+ };
160
+ }
161
+
162
+ type Groupable = { group?: string; groupDescription?: string };
163
+
164
+ function adaptMembers<T extends Groupable, K>(
165
+ heading: string,
166
+ members: T[],
167
+ adapter: (member: T, linkGenerator: GetRenderableContentByTypeName, baseHeadingLevel: number) => K,
168
+ linkFromTypeNameGenerator: GetRenderableContentByTypeName,
169
+ headingLevel: number,
170
+ ): RenderableSection<K[] | GroupedMember<K>[]> & { isGrouped: boolean } {
171
+ return {
172
+ headingLevel,
173
+ heading,
174
+ isGrouped: hasGroup(members),
175
+ value: hasGroup(members)
176
+ ? toGroupedMembers(members, adapter, linkFromTypeNameGenerator, headingLevel + 1)
177
+ : toFlat(members, adapter, linkFromTypeNameGenerator, headingLevel + 1),
178
+ };
179
+ }
180
+
181
+ function hasGroup(members: Groupable[]): boolean {
182
+ return members.some((member) => member.group);
183
+ }
184
+
185
+ function toFlat<T extends Groupable, K>(
186
+ members: T[],
187
+ adapter: (member: T, linkGenerator: GetRenderableContentByTypeName, baseHeadingLevel: number) => K,
188
+ linkGenerator: GetRenderableContentByTypeName,
189
+ baseHeadingLevel: number,
190
+ ): K[] {
191
+ return members.map((member) => adapter(member, linkGenerator, baseHeadingLevel));
192
+ }
193
+
194
+ function toGroupedMembers<T extends Groupable, K>(
195
+ members: T[],
196
+ adapter: (member: T, linkGenerator: GetRenderableContentByTypeName, baseHeadingLevel: number) => K,
197
+ linkGenerator: GetRenderableContentByTypeName,
198
+ baseHeadingLevel: number,
199
+ ): GroupedMember<K>[] {
200
+ const groupedMembers = groupByGroupName(members);
201
+ return Object.entries(groupedMembers).map(([groupName, members]) =>
202
+ singleGroup(baseHeadingLevel, groupName, adapter, members, linkGenerator),
203
+ );
204
+ }
205
+
206
+ function groupByGroupName<T extends Groupable>(members: T[]): Record<string, T[]> {
207
+ return members.reduce(
208
+ (acc, member) => {
209
+ const groupName = member.group ?? 'Other';
210
+ acc[groupName] = acc[groupName] ?? [];
211
+ acc[groupName].push(member);
212
+ return acc;
213
+ },
214
+ {} as Record<string, T[]>,
215
+ );
216
+ }
217
+
218
+ function singleGroup<T extends Groupable, K>(
219
+ headingLevel: number,
220
+ groupName: string,
221
+ adapter: (member: T, linkGenerator: GetRenderableContentByTypeName, baseHeadingLevel: number) => K,
222
+ members: T[],
223
+ linkGenerator: GetRenderableContentByTypeName,
224
+ ): GroupedMember<K> {
225
+ return {
226
+ headingLevel: headingLevel,
227
+ heading: groupName,
228
+ groupDescription: members[0].groupDescription, // All fields in the group have the same description
229
+ value: toFlat(members, adapter, linkGenerator, headingLevel + 1),
66
230
  };
67
231
  }
@@ -1,9 +1,14 @@
1
- import { CustomTag, DocumentableSource, RenderableContent } from '../templating/types';
1
+ import { CustomTag, RenderableDocumentation, RenderableContent } from '../core/renderable/types';
2
2
  import { Describable, Documentable } from './types';
3
- import { replaceInlineReferences } from './references';
3
+ import { GetRenderableContentByTypeName, replaceInlineReferences } from './references';
4
4
  import { isEmptyLine } from './type-utils';
5
5
 
6
- export function adaptDescribable(describable: Describable): { description?: RenderableContent[] } {
6
+ export function adaptDescribable(
7
+ describable: Describable,
8
+ linkGenerator: GetRenderableContentByTypeName,
9
+ ): {
10
+ description?: RenderableContent[];
11
+ } {
7
12
  function describableToRenderableContent(describable: Describable): RenderableContent[] | undefined {
8
13
  if (!describable) {
9
14
  return;
@@ -12,7 +17,7 @@ export function adaptDescribable(describable: Describable): { description?: Rend
12
17
  return (
13
18
  describable
14
19
  .map<RenderableContent[]>((line) => [
15
- ...replaceInlineReferences(line),
20
+ ...replaceInlineReferences(line, linkGenerator),
16
21
  {
17
22
  type: 'empty-line',
18
23
  },
@@ -28,7 +33,11 @@ export function adaptDescribable(describable: Describable): { description?: Rend
28
33
  };
29
34
  }
30
35
 
31
- export function adaptDocumentable(documentable: Documentable): DocumentableSource {
36
+ export function adaptDocumentable(
37
+ documentable: Documentable,
38
+ linkGenerator: GetRenderableContentByTypeName,
39
+ subHeadingLevel: number,
40
+ ): RenderableDocumentation {
32
41
  function extractCustomTags(type: Documentable): CustomTag[] {
33
42
  const baseTags = ['description', 'group', 'author', 'date', 'see', 'example', 'mermaid', 'throws', 'exception'];
34
43
 
@@ -36,7 +45,7 @@ export function adaptDocumentable(documentable: Documentable): DocumentableSourc
36
45
  type.docComment?.annotations
37
46
  .filter((currentAnnotation) => !baseTags.includes(currentAnnotation.name.toLowerCase()))
38
47
  .map<CustomTag>((currentAnnotation) => ({
39
- ...adaptDescribable(currentAnnotation.bodyLines),
48
+ ...adaptDescribable(currentAnnotation.bodyLines, linkGenerator),
40
49
  name: currentAnnotation.name,
41
50
  })) ?? []
42
51
  );
@@ -48,11 +57,37 @@ export function adaptDocumentable(documentable: Documentable): DocumentableSourc
48
57
  )?.bodyLines;
49
58
  }
50
59
 
60
+ function extractAnnotationBody(type: Documentable, annotationName: string): string | undefined {
61
+ return type.docComment?.annotations.find(
62
+ (currentAnnotation) => currentAnnotation.name.toLowerCase() === annotationName,
63
+ )?.body;
64
+ }
65
+
66
+ function extractSeeAnnotations(type: Documentable): string[] {
67
+ return (
68
+ type.docComment?.annotations
69
+ .filter((currentAnnotation) => currentAnnotation.name.toLowerCase() === 'see')
70
+ .map((currentAnnotation) => currentAnnotation.body) ?? []
71
+ );
72
+ }
73
+
51
74
  return {
52
- ...adaptDescribable(documentable.docComment?.descriptionLines),
75
+ ...adaptDescribable(documentable.docComment?.descriptionLines, linkGenerator),
53
76
  annotations: documentable.annotations.map((annotation) => annotation.type.toUpperCase()),
54
77
  customTags: extractCustomTags(documentable),
55
- mermaid: extractAnnotationBodyLines(documentable, 'mermaid'),
56
- example: documentable.docComment?.exampleAnnotation?.bodyLines,
78
+ mermaid: {
79
+ headingLevel: subHeadingLevel,
80
+ heading: 'Diagram',
81
+ value: extractAnnotationBodyLines(documentable, 'mermaid'),
82
+ },
83
+ example: {
84
+ headingLevel: subHeadingLevel,
85
+ heading: 'Example',
86
+ value: documentable.docComment?.exampleAnnotation?.bodyLines,
87
+ },
88
+ group: extractAnnotationBody(documentable, 'group'),
89
+ author: extractAnnotationBody(documentable, 'author'),
90
+ date: extractAnnotationBody(documentable, 'date'),
91
+ sees: extractSeeAnnotations(documentable).map(linkGenerator),
57
92
  };
58
93
  }
@@ -1,14 +1,38 @@
1
- import { FieldMirrorWithInheritance } from '../model/inheritance';
2
- import { FieldSource } from '../templating/types';
1
+ import { FieldMirrorWithInheritance, PropertyMirrorWithInheritance } from '../model/inheritance';
2
+ import { RenderableField } from '../core/renderable/types';
3
3
  import { adaptDocumentable } from './documentables';
4
- import { linkFromTypeNameGenerator } from './references';
4
+ import { GetRenderableContentByTypeName } from './references';
5
+
6
+ export function adaptFieldOrProperty(
7
+ field: FieldMirrorWithInheritance | PropertyMirrorWithInheritance,
8
+ linkGenerator: GetRenderableContentByTypeName,
9
+ baseHeadingLevel: number,
10
+ ): RenderableField {
11
+ function buildSignature() {
12
+ const { access_modifier, name } = field;
13
+ const memberModifiers = field.memberModifiers.join(' ');
14
+ return (
15
+ `${access_modifier} ${memberModifiers} ${name}`
16
+ // remove double spaces
17
+ .replace(/ {2}/g, ' ')
18
+ );
19
+ }
5
20
 
6
- export function adaptField(field: FieldMirrorWithInheritance): FieldSource {
7
21
  return {
8
- ...adaptDocumentable(field),
9
- name: field.name,
10
- type: linkFromTypeNameGenerator(field.typeReference.rawDeclaration),
22
+ headingLevel: baseHeadingLevel,
23
+ doc: adaptDocumentable(field, linkGenerator, baseHeadingLevel + 1),
24
+ heading: field.name,
25
+ type: {
26
+ headingLevel: baseHeadingLevel + 1,
27
+ heading: 'Type',
28
+ value: linkGenerator(field.typeReference.rawDeclaration),
29
+ },
11
30
  inherited: field.inherited,
12
31
  accessModifier: field.access_modifier,
32
+ signature: {
33
+ headingLevel: baseHeadingLevel + 1,
34
+ heading: 'Signature',
35
+ value: [buildSignature()],
36
+ },
13
37
  };
14
38
  }
@@ -1,11 +1,15 @@
1
1
  import { ConstructorMirror, MethodMirror, ParameterMirror, ThrowsAnnotation } from '@cparra/apex-reflection';
2
- import { ConstructorSource, MethodSource } from '../templating/types';
2
+ import { RenderableConstructor, RenderableMethod } from '../core/renderable/types';
3
3
  import { MethodMirrorWithInheritance } from '../model/inheritance';
4
4
  import { adaptDescribable, adaptDocumentable } from './documentables';
5
- import { linkFromTypeNameGenerator } from './references';
5
+ import { GetRenderableContentByTypeName } from './references';
6
6
  import { Documentable } from './types';
7
7
 
8
- export function adaptMethod(method: MethodMirror): MethodSource {
8
+ export function adaptMethod(
9
+ method: MethodMirror,
10
+ linkGenerator: GetRenderableContentByTypeName,
11
+ baseHeadingLevel: number,
12
+ ): RenderableMethod {
9
13
  function buildTitle(method: MethodMirrorWithInheritance): string {
10
14
  const { name, parameters } = method;
11
15
  const parametersString = parameters.map((param) => param.name).join(', ');
@@ -22,20 +26,42 @@ export function adaptMethod(method: MethodMirror): MethodSource {
22
26
  }
23
27
 
24
28
  return {
25
- ...adaptDocumentable(method),
26
- title: buildTitle(method as MethodMirrorWithInheritance),
27
- signature: buildSignature(method as MethodMirrorWithInheritance),
29
+ headingLevel: baseHeadingLevel,
30
+ doc: adaptDocumentable(method, linkGenerator, baseHeadingLevel + 1),
31
+ heading: buildTitle(method as MethodMirrorWithInheritance),
32
+ signature: {
33
+ headingLevel: baseHeadingLevel + 1,
34
+ heading: 'Signature',
35
+ value: [buildSignature(method as MethodMirrorWithInheritance)],
36
+ },
28
37
  returnType: {
29
- ...adaptDescribable(method.docComment?.returnAnnotation?.bodyLines),
30
- type: linkFromTypeNameGenerator(method.typeReference.rawDeclaration),
38
+ headingLevel: baseHeadingLevel + 1,
39
+ heading: 'Return Type',
40
+ value: {
41
+ ...adaptDescribable(method.docComment?.returnAnnotation?.bodyLines, linkGenerator),
42
+ type: linkGenerator(method.typeReference.rawDeclaration),
43
+ },
44
+ },
45
+ throws: {
46
+ headingLevel: baseHeadingLevel + 1,
47
+ heading: 'Throws',
48
+ value: method.docComment?.throwsAnnotations.map((thrown) => mapThrows(thrown, linkGenerator)),
49
+ },
50
+ parameters: {
51
+ headingLevel: baseHeadingLevel + 1,
52
+ heading: 'Parameters',
53
+ value: method.parameters.map((param) => mapParameters(method, param, linkGenerator)),
31
54
  },
32
- throws: method.docComment?.throwsAnnotations.map((thrown) => mapThrows(thrown)),
33
- parameters: method.parameters.map((param) => mapParameters(method, param)),
34
55
  inherited: (method as MethodMirrorWithInheritance).inherited,
35
56
  };
36
57
  }
37
58
 
38
- export function adaptConstructor(typeName: string, constructor: ConstructorMirror): ConstructorSource {
59
+ export function adaptConstructor(
60
+ typeName: string,
61
+ constructor: ConstructorMirror,
62
+ linkGenerator: GetRenderableContentByTypeName,
63
+ baseHeadingLevel: number,
64
+ ): RenderableConstructor {
39
65
  function buildTitle(name: string, constructor: ConstructorMirror): string {
40
66
  const { parameters } = constructor;
41
67
  const parametersString = parameters.map((param) => param.name).join(', ');
@@ -51,28 +77,45 @@ export function adaptConstructor(typeName: string, constructor: ConstructorMirro
51
77
  }
52
78
 
53
79
  return {
54
- ...adaptDocumentable(constructor),
55
- title: buildTitle(typeName, constructor),
56
- signature: buildSignature(typeName, constructor),
57
- parameters: constructor.parameters.map((param) => mapParameters(constructor, param)),
58
- throws: constructor.docComment?.throwsAnnotations.map((thrown) => mapThrows(thrown)),
80
+ doc: adaptDocumentable(constructor, linkGenerator, baseHeadingLevel + 1),
81
+ headingLevel: baseHeadingLevel,
82
+ heading: buildTitle(typeName, constructor),
83
+ signature: {
84
+ headingLevel: baseHeadingLevel + 1,
85
+ heading: 'Signature',
86
+ value: [buildSignature(typeName, constructor)],
87
+ },
88
+ parameters: {
89
+ headingLevel: baseHeadingLevel + 1,
90
+ heading: 'Parameters',
91
+ value: constructor.parameters.map((param) => mapParameters(constructor, param, linkGenerator)),
92
+ },
93
+ throws: {
94
+ headingLevel: baseHeadingLevel + 1,
95
+ heading: 'Throws',
96
+ value: constructor.docComment?.throwsAnnotations.map((thrown) => mapThrows(thrown, linkGenerator)),
97
+ },
59
98
  };
60
99
  }
61
100
 
62
- function mapParameters(documentable: Documentable, param: ParameterMirror) {
101
+ function mapParameters(
102
+ documentable: Documentable,
103
+ param: ParameterMirror,
104
+ linkGenerator: GetRenderableContentByTypeName,
105
+ ) {
63
106
  const paramAnnotation = documentable.docComment?.paramAnnotations.find(
64
107
  (pa) => pa.paramName.toLowerCase() === param.name.toLowerCase(),
65
108
  );
66
109
  return {
67
- ...adaptDescribable(paramAnnotation?.bodyLines),
110
+ ...adaptDescribable(paramAnnotation?.bodyLines, linkGenerator),
68
111
  name: param.name,
69
- type: linkFromTypeNameGenerator(param.typeReference.rawDeclaration),
112
+ type: linkGenerator(param.typeReference.rawDeclaration),
70
113
  };
71
114
  }
72
115
 
73
- function mapThrows(thrown: ThrowsAnnotation) {
116
+ function mapThrows(thrown: ThrowsAnnotation, linkGenerator: GetRenderableContentByTypeName) {
74
117
  return {
75
- ...adaptDescribable(thrown.bodyLines),
76
- type: linkFromTypeNameGenerator(thrown.exceptionName),
118
+ ...adaptDescribable(thrown.bodyLines, linkGenerator),
119
+ type: linkGenerator(thrown.exceptionName),
77
120
  };
78
121
  }
@@ -1,5 +1,5 @@
1
1
  import ClassFileGeneratorHelper from '../transpiler/markdown/class-file-generatorHelper';
2
- import { Link, RenderableContent, StringOrLink } from '../templating/types';
2
+ import { Link, RenderableContent, StringOrLink } from '../core/renderable/types';
3
3
 
4
4
  export type GetRenderableContentByTypeName = (typeName: string) => StringOrLink;
5
5
 
@@ -1,4 +1,4 @@
1
- import { EmptyLine, RenderableContent } from '../templating/types';
1
+ import { EmptyLine, RenderableContent } from '../core/renderable/types';
2
2
 
3
3
  export function isEmptyLine(content: RenderableContent): content is EmptyLine {
4
4
  return Object.keys(content).includes('type') && (content as { type: string }).type === 'empty-line';
@@ -12,6 +12,7 @@ import ApexBundle from '../model/apex-bundle';
12
12
  import Manifest from '../model/manifest';
13
13
  import { TypesRepository } from '../model/types-repository';
14
14
  import { TypeTranspilerFactory } from '../transpiler/factory';
15
+ import { generateMarkdownFiles } from './flows/generate-markdown-files';
15
16
 
16
17
  /**
17
18
  * Application entry-point to generate documentation out of Apex source files.
@@ -23,24 +24,29 @@ export class Apexdocs {
23
24
  static generate(): void {
24
25
  Logger.log('Initializing...');
25
26
  const fileBodies = ApexFileReader.processFiles(new DefaultFileSystem());
26
- const manifest = createManifest(new RawBodyParser(fileBodies), this._reflectionWithLogger);
27
- TypesRepository.getInstance().populateAll(manifest.types);
28
- const filteredTypes = this.filterByScopes(manifest);
29
- TypesRepository.getInstance().populateScoped(filteredTypes);
30
- const processor = TypeTranspilerFactory.get(Settings.getInstance().targetGenerator);
31
- Transpiler.generate(filteredTypes, processor);
32
- const generatedFiles = processor.fileBuilder().files();
33
27
 
34
- const files: TargetFile[] = [];
35
- FileWriter.write(generatedFiles, (file: TargetFile) => {
36
- Logger.logSingle(`${file.name} processed.`, false, 'green', false);
37
- files.push(file);
38
- });
28
+ if (Settings.getInstance().targetGenerator === 'plain-markdown') {
29
+ generateMarkdownFiles(fileBodies);
30
+ } else {
31
+ const manifest = createManifest(new RawBodyParser(fileBodies), this._reflectionWithLogger);
32
+ TypesRepository.getInstance().populateAll(manifest.types);
33
+ const filteredTypes = this.filterByScopes(manifest);
34
+ TypesRepository.getInstance().populateScoped(filteredTypes);
35
+ const processor = TypeTranspilerFactory.get(Settings.getInstance().targetGenerator);
36
+ Transpiler.generate(filteredTypes, processor);
37
+ const generatedFiles = processor.fileBuilder().files();
38
+
39
+ const files: TargetFile[] = [];
40
+ FileWriter.write(generatedFiles, (file: TargetFile) => {
41
+ Logger.logSingle(`${file.name} processed.`, false, 'green', false);
42
+ files.push(file);
43
+ });
39
44
 
40
- Settings.getInstance().onAfterProcess(files);
45
+ Settings.getInstance().onAfterProcess(files);
41
46
 
42
- // Error logging
43
- ErrorLogger.logErrors(filteredTypes);
47
+ // Error logging
48
+ ErrorLogger.logErrors(filteredTypes);
49
+ }
44
50
  }
45
51
 
46
52
  private static filterByScopes(manifest: Manifest) {
@@ -0,0 +1,47 @@
1
+ import ApexBundle from '../../model/apex-bundle';
2
+ import { Settings, TargetFile } from '../../settings';
3
+ import { DocumentationBundle, generateDocs } from '../../core/generate-docs';
4
+ import { MarkdownFile } from '../../model/markdown-file';
5
+ import { FileWriter } from '../../service/file-writer';
6
+ import { Logger } from '../../util/logger';
7
+ import { flow } from 'fp-ts/function';
8
+ import * as E from 'fp-ts/Either';
9
+
10
+ export const generateMarkdownFiles = flow(
11
+ generateDocumentationBundle,
12
+ E.map(convertToMarkdownFiles),
13
+ E.map(writeFilesToSystem),
14
+ E.mapLeft((errors) => {
15
+ Logger.error(errors.join('\n'));
16
+ }),
17
+ );
18
+
19
+ function generateDocumentationBundle(bundles: ApexBundle[]) {
20
+ return generateDocs(
21
+ bundles.map((file) => file.rawTypeContent),
22
+ {
23
+ scope: Settings.getInstance().scope,
24
+ outputDir: Settings.getInstance().outputDir,
25
+ namespace: Settings.getInstance().getNamespace(),
26
+ sortMembersAlphabetically: Settings.getInstance().sortMembersAlphabetically(),
27
+ defaultGroupName: Settings.getInstance().getDefaultGroupName(),
28
+ },
29
+ );
30
+ }
31
+
32
+ function convertToMarkdownFiles(docBundle: DocumentationBundle): MarkdownFile[] {
33
+ return [
34
+ new MarkdownFile('index', '').addText(docBundle.referenceGuide),
35
+ ...docBundle.docs.map((doc) =>
36
+ new MarkdownFile(`${Settings.getInstance().getNamespacePrefix()}${doc.typeName}`, doc.directory).addText(
37
+ doc.docContents,
38
+ ),
39
+ ),
40
+ ];
41
+ }
42
+
43
+ function writeFilesToSystem(files: MarkdownFile[]) {
44
+ FileWriter.write(files, (file: TargetFile) => {
45
+ Logger.logSingle(`${file.name} processed.`, false, 'green', false);
46
+ });
47
+ }