@cparra/apexdocs 2.25.0-alpha.4 → 2.25.0-alpha.5

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 (189) hide show
  1. package/dist/cli/generate.js +2745 -39
  2. package/dist/defaults-DUwru49Q.js +12 -0
  3. package/dist/defaults-SH0Rsi5E.js +11 -0
  4. package/dist/index.d.ts +62 -2
  5. package/dist/index.js +36 -1
  6. package/examples/plain-markdown/docs/Miscellaneous/ns.BaseClass.md +1 -1
  7. package/examples/plain-markdown/docs/Miscellaneous/ns.MultiInheritanceClass.md +1 -1
  8. package/examples/plain-markdown/docs/Miscellaneous/ns.ParentInterface.md +1 -1
  9. package/examples/plain-markdown/docs/Miscellaneous/ns.ReferencedEnum.md +1 -1
  10. package/examples/plain-markdown/docs/Miscellaneous/ns.SampleException.md +1 -1
  11. package/examples/plain-markdown/docs/Miscellaneous/ns.SampleInterface.md +1 -1
  12. package/examples/plain-markdown/docs/Miscellaneous/ns.Url.md +1 -1
  13. package/examples/plain-markdown/docs/Sample-Enums/ns.SampleEnum.md +1 -1
  14. package/examples/plain-markdown/docs/SampleGroup/ns.SampleClass.md +1 -1
  15. package/examples/plain-markdown/docs/index.md +1 -1
  16. package/examples/plain-markdown/package.json +3 -4
  17. package/examples/vitepress/.forceignore +12 -0
  18. package/examples/vitepress/apexdocs.config.ts +108 -0
  19. package/examples/vitepress/config/project-scratch-def.json +13 -0
  20. package/examples/vitepress/docs/.vitepress/cache/deps/@theme_index.js +259 -0
  21. package/examples/vitepress/docs/.vitepress/cache/deps/@theme_index.js.map +7 -0
  22. package/examples/vitepress/docs/.vitepress/cache/deps/_metadata.json +40 -0
  23. package/examples/vitepress/docs/.vitepress/cache/deps/chunk-574YRH25.js +11474 -0
  24. package/examples/vitepress/docs/.vitepress/cache/deps/chunk-574YRH25.js.map +7 -0
  25. package/examples/vitepress/docs/.vitepress/cache/deps/chunk-E5DZZB2I.js +9172 -0
  26. package/examples/vitepress/docs/.vitepress/cache/deps/chunk-E5DZZB2I.js.map +7 -0
  27. package/examples/vitepress/docs/.vitepress/cache/deps/package.json +3 -0
  28. package/examples/vitepress/docs/.vitepress/cache/deps/vitepress___@vue_devtools-api.js +4339 -0
  29. package/examples/vitepress/docs/.vitepress/cache/deps/vitepress___@vue_devtools-api.js.map +7 -0
  30. package/examples/vitepress/docs/.vitepress/cache/deps/vitepress___@vueuse_core.js +567 -0
  31. package/examples/vitepress/docs/.vitepress/cache/deps/vitepress___@vueuse_core.js.map +7 -0
  32. package/examples/vitepress/docs/.vitepress/cache/deps/vue.js +323 -0
  33. package/examples/vitepress/docs/.vitepress/cache/deps/vue.js.map +7 -0
  34. package/examples/vitepress/docs/.vitepress/config.mts +21 -0
  35. package/examples/vitepress/docs/.vitepress/sidebar.json +119 -0
  36. package/examples/vitepress/docs/Miscellaneous/apexdocs.BaseClass.md +20 -0
  37. package/examples/vitepress/docs/Miscellaneous/apexdocs.MultiInheritanceClass.md +78 -0
  38. package/examples/vitepress/docs/Miscellaneous/apexdocs.ParentInterface.md +19 -0
  39. package/examples/vitepress/docs/Miscellaneous/apexdocs.ReferencedEnum.md +15 -0
  40. package/examples/vitepress/docs/Miscellaneous/apexdocs.SampleException.md +28 -0
  41. package/examples/vitepress/docs/Miscellaneous/apexdocs.SampleInterface.md +122 -0
  42. package/examples/vitepress/docs/Miscellaneous/apexdocs.Url.md +318 -0
  43. package/examples/vitepress/docs/Sample-Enums/apexdocs.SampleEnum.md +41 -0
  44. package/examples/vitepress/docs/SampleGroup/apexdocs.SampleClass.md +178 -0
  45. package/examples/vitepress/docs/api-examples.md +49 -0
  46. package/examples/vitepress/docs/index-frontmatter.md +16 -0
  47. package/examples/vitepress/docs/index.md +127 -0
  48. package/examples/vitepress/docs/markdown-examples.md +85 -0
  49. package/examples/vitepress/force-app/main/default/classes/BaseClass.cls +3 -0
  50. package/examples/vitepress/force-app/main/default/classes/MultiInheritanceClass.cls +1 -0
  51. package/examples/vitepress/force-app/main/default/classes/ParentInterface.cls +3 -0
  52. package/examples/vitepress/force-app/main/default/classes/ReferencedEnum.cls +5 -0
  53. package/examples/vitepress/force-app/main/default/classes/SampleClass.cls +72 -0
  54. package/examples/vitepress/force-app/main/default/classes/SampleEnum.cls +30 -0
  55. package/examples/vitepress/force-app/main/default/classes/SampleException.cls +17 -0
  56. package/examples/vitepress/force-app/main/default/classes/SampleInterface.cls +46 -0
  57. package/examples/vitepress/force-app/main/default/classes/Url.cls +195 -0
  58. package/examples/vitepress/package-lock.json +2574 -0
  59. package/examples/vitepress/package.json +18 -0
  60. package/examples/vitepress/sfdx-project.json +12 -0
  61. package/jest.config.js +1 -0
  62. package/package.json +10 -6
  63. package/src/application/Apexdocs.ts +16 -104
  64. package/src/application/__tests__/apex-file-reader.spec.ts +104 -0
  65. package/src/application/apex-file-reader.ts +42 -0
  66. package/src/application/file-writer.ts +25 -0
  67. package/src/application/generators/markdown.ts +53 -0
  68. package/src/application/generators/openapi.ts +56 -0
  69. package/src/cli/args.ts +17 -112
  70. package/src/cli/commands/markdown.ts +58 -0
  71. package/src/cli/generate.ts +7 -5
  72. package/src/{model/__tests__ → core/__test__}/manifest.spec.ts +1 -1
  73. package/src/core/manifest.ts +57 -51
  74. package/src/{__spec__/core → core/markdown/__test__}/expect-extensions.ts +5 -5
  75. package/src/core/markdown/__test__/generating-class-docs.spec.ts +727 -0
  76. package/src/{__spec__/core → core/markdown/__test__}/generating-enum-docs.spec.ts +82 -59
  77. package/src/{__spec__/core → core/markdown/__test__}/generating-interface-docs.spec.ts +94 -75
  78. package/src/core/markdown/__test__/generating-reference-guide.spec.ts +184 -0
  79. package/src/core/{__test__ → markdown/__test__}/inheritance-chain.test.ts +2 -2
  80. package/src/core/markdown/__test__/test-helpers.ts +22 -0
  81. package/src/core/{adapters → markdown/adapters}/__tests__/interface-adapter.spec.ts +38 -8
  82. package/src/core/{adapters → markdown/adapters}/apex-types.ts +7 -4
  83. package/src/core/{adapters → markdown/adapters}/inline.ts +1 -1
  84. package/src/core/markdown/adapters/renderable-bundle.ts +144 -0
  85. package/src/core/markdown/adapters/renderable-to-page-data.ts +92 -0
  86. package/src/core/{adapters → markdown/adapters}/types.d.ts +16 -2
  87. package/src/core/markdown/generate-docs.ts +158 -0
  88. package/src/core/markdown/reflection/error-handling.ts +37 -0
  89. package/src/core/markdown/reflection/filter-scope.ts +13 -0
  90. package/src/core/markdown/reflection/inheritance-chain-expanion.ts +22 -0
  91. package/src/core/markdown/reflection/inherited-member-expansion.ts +105 -0
  92. package/src/core/markdown/reflection/reflect-source.ts +41 -0
  93. package/src/core/markdown/reflection/sort-members.ts +59 -0
  94. package/src/{transpiler/markdown/plain-markdown → core/markdown/templates}/class-template.ts +2 -0
  95. package/src/core/markdown/templates/hookable.ts +7 -0
  96. package/src/core/{template.ts → markdown/templates/template.ts} +12 -12
  97. package/src/core/markdown/utils.ts +3 -0
  98. package/src/{transpiler → core}/openapi/__tests__/open-api-docs-processor.spec.ts +1 -1
  99. package/src/{model → core/openapi}/apex-type-wrappers/__tests__/ClassMirrorWrapper.spec.ts +3 -3
  100. package/src/core/openapi/file-container.ts +13 -0
  101. package/src/{service → core/openapi}/manifest-factory.ts +3 -3
  102. package/src/{transpiler → core}/openapi/open-api-docs-processor.ts +9 -10
  103. package/src/core/openapi/openapi-type-file.ts +14 -0
  104. package/src/{service → core/openapi}/parser.ts +8 -8
  105. package/src/{transpiler → core}/openapi/parsers/Builder.ts +2 -2
  106. package/src/{transpiler → core}/openapi/parsers/MethodParser.ts +5 -5
  107. package/src/{transpiler → core}/openapi/parsers/ParameterObjectBuilder.ts +2 -2
  108. package/src/{transpiler → core}/openapi/parsers/ReferenceBuilder.ts +3 -3
  109. package/src/{transpiler → core}/openapi/parsers/RequestBodyBuilder.ts +2 -2
  110. package/src/{transpiler → core}/openapi/parsers/ResponsesBuilder.ts +2 -2
  111. package/src/{transpiler → core}/openapi/parsers/__tests__/MethodParser.spec.ts +1 -1
  112. package/src/{transpiler → core}/openapi/parsers/__tests__/ParameterObjectBuilder.spec.ts +2 -2
  113. package/src/{transpiler → core}/openapi/parsers/__tests__/ReferenceBuilder.spec.ts +2 -2
  114. package/src/{transpiler → core}/openapi/parsers/__tests__/RequestBodyBuilder.spec.ts +2 -2
  115. package/src/{transpiler → core}/openapi/parsers/__tests__/ResponsesBuilder.spec.ts +1 -1
  116. package/src/{transpiler → core/openapi}/transpiler.ts +2 -6
  117. package/src/{model → core/openapi}/types-repository.ts +0 -9
  118. package/src/core/parse-apex-metadata.ts +14 -0
  119. package/src/core/settings.ts +56 -0
  120. package/src/core/shared/types.d.ts +92 -0
  121. package/src/core/shared/utils.ts +5 -0
  122. package/src/defaults.ts +8 -0
  123. package/src/index.ts +34 -2
  124. package/src/test-helpers/InterfaceMirrorBuilder.ts +0 -5
  125. package/src/test-helpers/SettingsBuilder.ts +1 -3
  126. package/src/util/logger.ts +2 -2
  127. package/src/util/string-utils.ts +0 -4
  128. package/tsconfig.json +5 -1
  129. package/apexdocs.config.ts +0 -13
  130. package/examples/plain-markdown/template.md +0 -3
  131. package/src/__spec__/core/generating-class-docs.spec.ts +0 -531
  132. package/src/__spec__/core/generating-reference-guide.spec.ts +0 -164
  133. package/src/__spec__/core/test-helpers.ts +0 -9
  134. package/src/application/generators/generate-markdown-files.ts +0 -53
  135. package/src/core/apex-bundle.ts +0 -3
  136. package/src/core/generate-docs.ts +0 -432
  137. package/src/model/markdown-file.ts +0 -122
  138. package/src/model/markdown-generation-util/doc-comment-annotation-util.ts +0 -50
  139. package/src/model/markdown-generation-util/field-declaration-util.ts +0 -71
  140. package/src/model/markdown-generation-util/index.ts +0 -3
  141. package/src/model/markdown-generation-util/method-declaration-util.ts +0 -166
  142. package/src/model/markdown-generation-util/type-declaration-util.ts +0 -91
  143. package/src/model/markdown-home-file.ts +0 -58
  144. package/src/model/markdown-type-file.ts +0 -169
  145. package/src/model/openapi/openapi-type-file.ts +0 -14
  146. package/src/model/outputFile.ts +0 -20
  147. package/src/service/__tests__/apex-file-reader.spec.ts +0 -93
  148. package/src/service/apex-file-reader.ts +0 -47
  149. package/src/service/file-writer.ts +0 -34
  150. package/src/service/metadata-processor.ts +0 -16
  151. package/src/service/state.ts +0 -24
  152. package/src/service/walkers/class-walker.ts +0 -30
  153. package/src/service/walkers/enum-walker.ts +0 -7
  154. package/src/service/walkers/interface-walker.ts +0 -12
  155. package/src/service/walkers/walker-factory.ts +0 -19
  156. package/src/service/walkers/walker.ts +0 -42
  157. package/src/settings.ts +0 -143
  158. package/src/transpiler/factory.ts +0 -31
  159. package/src/transpiler/file-container.ts +0 -13
  160. package/src/transpiler/generator-choices.ts +0 -1
  161. package/src/transpiler/markdown/class-file-generatorHelper.ts +0 -61
  162. package/src/transpiler/markdown/docsify/docsify-docs-processor.ts +0 -12
  163. package/src/transpiler/markdown/jekyll/jekyll-docsProcessor.ts +0 -50
  164. package/src/transpiler/markdown/markdown-transpiler-base.ts +0 -28
  165. package/src/transpiler/processor-type-transpiler.ts +0 -18
  166. /package/src/{service → application}/file-system.ts +0 -0
  167. /package/src/core/{adapters → markdown/adapters}/__tests__/documentables.spec.ts +0 -0
  168. /package/src/core/{adapters → markdown/adapters}/__tests__/references.spec.ts +0 -0
  169. /package/src/core/{adapters → markdown/adapters}/documentables.ts +0 -0
  170. /package/src/core/{adapters → markdown/adapters}/fields-and-properties.ts +0 -0
  171. /package/src/core/{adapters → markdown/adapters}/methods-and-constructors.ts +0 -0
  172. /package/src/core/{adapters → markdown/adapters}/type-utils.ts +0 -0
  173. /package/src/core/{inheritance-chain.ts → markdown/reflection/inheritance-chain.ts} +0 -0
  174. /package/src/{transpiler/markdown/plain-markdown → core/markdown/templates}/constructors-partial-template.ts +0 -0
  175. /package/src/{transpiler/markdown/plain-markdown → core/markdown/templates}/documentable-partial-template.ts +0 -0
  176. /package/src/{transpiler/markdown/plain-markdown → core/markdown/templates}/enum-template.ts +0 -0
  177. /package/src/{transpiler/markdown/plain-markdown → core/markdown/templates}/fieldsPartialTemplate.ts +0 -0
  178. /package/src/{transpiler/markdown/plain-markdown → core/markdown/templates}/grouped-members-partial-template.ts +0 -0
  179. /package/src/{transpiler/markdown/plain-markdown → core/markdown/templates}/interface-template.ts +0 -0
  180. /package/src/{transpiler/markdown/plain-markdown → core/markdown/templates}/methods-partial-template.ts +0 -0
  181. /package/src/core/{templates → markdown/templates}/reference-guide.ts +0 -0
  182. /package/src/{transpiler/markdown/plain-markdown → core/markdown/templates}/type-doc-partial.ts +0 -0
  183. /package/src/{service → core/openapi}/__tests__/manifest-factory.spec.ts +0 -0
  184. /package/src/{model → core}/openapi/__tests__/open-api.spec.ts +0 -0
  185. /package/src/{model → core}/openapi/apex-doc-types.ts +0 -0
  186. /package/src/{model → core/openapi}/apex-type-wrappers/ClassMirrorWrapper.ts +0 -0
  187. /package/src/{model → core/openapi}/apex-type-wrappers/MethodMirrorWrapper.ts +0 -0
  188. /package/src/{model → core}/openapi/open-api-types.ts +0 -0
  189. /package/src/{model → core}/openapi/open-api.ts +0 -0
@@ -1,53 +0,0 @@
1
- import ApexBundle from '../../core/apex-bundle';
2
- import { Settings, TargetFile } from '../../settings';
3
- import { DocumentationBundle, generateDocs, ReflectionError } 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
- const errorMessages = [
16
- 'Error(s) occurred while parsing files. Please review the following issues:',
17
- ...errors.map(formatReflectionError),
18
- ].join('\n');
19
-
20
- Logger.error(errorMessages);
21
- }),
22
- );
23
-
24
- function generateDocumentationBundle(bundles: ApexBundle[]) {
25
- return generateDocs(bundles, {
26
- scope: Settings.getInstance().scope,
27
- outputDir: Settings.getInstance().outputDir,
28
- namespace: Settings.getInstance().getNamespace(),
29
- sortMembersAlphabetically: Settings.getInstance().sortMembersAlphabetically(),
30
- defaultGroupName: Settings.getInstance().getDefaultGroupName(),
31
- });
32
- }
33
-
34
- function convertToMarkdownFiles(docBundle: DocumentationBundle): MarkdownFile[] {
35
- return [
36
- new MarkdownFile('index', '').addText(docBundle.referenceGuide),
37
- ...docBundle.docs.map((doc) =>
38
- new MarkdownFile(`${Settings.getInstance().getNamespacePrefix()}${doc.typeName}`, doc.directory).addText(
39
- doc.docContents,
40
- ),
41
- ),
42
- ];
43
- }
44
-
45
- function writeFilesToSystem(files: MarkdownFile[]) {
46
- FileWriter.write(files, (file: TargetFile) => {
47
- Logger.logSingle(`${file.name} processed.`, false, 'green', false);
48
- });
49
- }
50
-
51
- function formatReflectionError(error: ReflectionError) {
52
- return `Source file: ${error.file}\n${error.message}\n`;
53
- }
@@ -1,3 +0,0 @@
1
- export default class ApexBundle {
2
- constructor(public filePath: string, public rawTypeContent: string, public rawMetadataContent: string | null) {}
3
- }
@@ -1,432 +0,0 @@
1
- import { ClassMirror, InterfaceMirror, reflect as mirrorReflection, Type } from '@cparra/apex-reflection';
2
- import * as O from 'fp-ts/Option';
3
- import { pipe } from 'fp-ts/function';
4
- import * as E from 'fp-ts/Either';
5
-
6
- import { typeToRenderable } from './adapters/apex-types';
7
- import { Link, Renderable, RenderableContent, RenderableEnum, StringOrLink } from './adapters/types';
8
- import { CompilationRequest, Template } from './template';
9
- import { referenceGuideTemplate } from './templates/reference-guide';
10
- import { adaptDescribable } from './adapters/documentables';
11
- import { createInheritanceChain } from './inheritance-chain';
12
- import ApexBundle from './apex-bundle';
13
- import Manifest from './manifest';
14
-
15
- // TODO: The core should never depend on things from the outside, so it should never reference "back" (../)
16
- import { classMarkdownTemplate } from '../transpiler/markdown/plain-markdown/class-template';
17
- import { interfaceMarkdownTemplate } from '../transpiler/markdown/plain-markdown/interface-template';
18
- import { enumMarkdownTemplate } from '../transpiler/markdown/plain-markdown/enum-template';
19
- import MetadataProcessor from '../service/metadata-processor';
20
-
21
- export type DocumentationBundle = {
22
- format: 'markdown';
23
- referenceGuide: string; // Output file with links to all other files (e.g. index/table of contents)
24
- docs: DocOutput[];
25
- };
26
-
27
- type DocumentationConfig = {
28
- scope: string[];
29
- outputDir: string;
30
- namespace?: string;
31
- sortMembersAlphabetically?: boolean;
32
- defaultGroupName: string;
33
- referenceGuideTemplate: string;
34
- };
35
-
36
- type DocOutput = {
37
- directory: string;
38
- docContents: string;
39
- typeName: string;
40
- type: 'class' | 'interface' | 'enum';
41
- };
42
-
43
- const configDefaults: DocumentationConfig = {
44
- scope: ['public'],
45
- outputDir: 'docs',
46
- defaultGroupName: 'Miscellaneous',
47
- referenceGuideTemplate: referenceGuideTemplate,
48
- };
49
-
50
- export function generateDocs(
51
- input: ApexBundle[],
52
- config?: Partial<DocumentationConfig>,
53
- ): E.Either<ReflectionError[], DocumentationBundle> {
54
- const configWithDefaults = { ...configDefaults, ...config };
55
- return pipe(
56
- input,
57
- (input) => input.map((bundle) => reflectSourceBody(bundle)),
58
- checkForReflectionErrors,
59
- E.map((types) => filterTypesOutOfScope(types, configWithDefaults.scope)),
60
- E.map((types) => types.map((type) => addInheritedMembers(type, types))),
61
- E.map((types) => types.map((type) => addInheritanceChain(type, types))),
62
- E.map((types) => typesToRenderableBundle(types, configWithDefaults)),
63
- E.map(({ references, renderables }) => ({
64
- referenceGuide: pipe(referencesToReferenceGuide(references, configWithDefaults.referenceGuideTemplate)),
65
- docs: renderables.map((renderable) => renderableToOutputDoc(Object.values(references).flat(), renderable)),
66
- })),
67
- E.map(({ referenceGuide, docs }) => ({ format: 'markdown', referenceGuide: referenceGuide, docs })),
68
- );
69
- }
70
-
71
- type ReferenceGuideReference = {
72
- typeName: string;
73
- directory: string;
74
- title: Link;
75
- description: RenderableContent[] | undefined;
76
- };
77
-
78
- type RenderableBundle = {
79
- // References are grouped by their defined @group annotation
80
- references: {
81
- [key: string]: ReferenceGuideReference[];
82
- };
83
- renderables: Renderable[];
84
- };
85
-
86
- function typesToRenderableBundle(types: Type[], config: DocumentationConfig) {
87
- return types.reduce<RenderableBundle>(
88
- (acc, type) => {
89
- const renderable = typeToRenderable(
90
- type,
91
- (referenceName) => {
92
- return linkFromTypeNameGenerator(type, types, referenceName, config);
93
- },
94
- config.namespace,
95
- );
96
- acc.renderables.push(renderable);
97
-
98
- const descriptionLines = type.docComment?.descriptionLines;
99
- const reference = {
100
- typeName: type.name,
101
- directory: getDirectoryFromRoot(config, type),
102
- title: getLinkFromRoot(config, type),
103
- description: adaptDescribable(descriptionLines, (referenceName) =>
104
- getPossibleLinkFromRoot(config, referenceName, findType(types, referenceName)),
105
- ).description,
106
- };
107
-
108
- const group = getTypeGroup(type, config);
109
- if (!acc.references[group]) {
110
- acc.references[group] = [];
111
- }
112
- acc.references[group].push(reference);
113
-
114
- return acc;
115
- },
116
- {
117
- references: {},
118
- renderables: [],
119
- },
120
- );
121
- }
122
-
123
- function renderableToOutputDoc(referenceGuideReference: ReferenceGuideReference[], renderable: Renderable): DocOutput {
124
- function buildDocOutput(renderable: Renderable, docContents: string): DocOutput {
125
- const reference = referenceGuideReference.find(
126
- (ref) => ref.typeName.toLowerCase() === renderable.name.toLowerCase(),
127
- );
128
- return {
129
- directory: reference!.directory,
130
- docContents,
131
- typeName: renderable.name,
132
- type: renderable.type,
133
- };
134
- }
135
-
136
- return pipe(renderable, resolveApexTypeTemplate, compile, (docContents) => buildDocOutput(renderable, docContents));
137
- }
138
-
139
- function referencesToReferenceGuide(
140
- references: { [key: string]: ReferenceGuideReference[] },
141
- template: string,
142
- ): string {
143
- function alphabetizeReferences(references: { [key: string]: ReferenceGuideReference[] }): {
144
- [key: string]: ReferenceGuideReference[];
145
- } {
146
- return Object.keys(references)
147
- .sort((a, b) => a.localeCompare(b))
148
- .reduce<{ [key: string]: ReferenceGuideReference[] }>((acc, key) => {
149
- acc[key] = references[key].sort((a, b) => a.title.toString().localeCompare(b.title.toString()));
150
- return acc;
151
- }, {});
152
- }
153
-
154
- return pipe(references, alphabetizeReferences, (references) =>
155
- compile({
156
- template: template,
157
- source: references,
158
- }),
159
- );
160
- }
161
-
162
- function filterTypesOutOfScope(types: Type[], scope: string[]): Type[] {
163
- return new Manifest(types).filteredByAccessModifierAndAnnotations(scope);
164
- }
165
-
166
- function checkForReflectionErrors(reflectionResult: E.Either<ReflectionError, Type>[]) {
167
- function reduceReflectionResultIntoSingleEither(results: E.Either<ReflectionError, Type>[]): {
168
- errors: ReflectionError[];
169
- types: Type[];
170
- } {
171
- return results.reduce<{ errors: ReflectionError[]; types: Type[] }>(
172
- (acc, result) => {
173
- E.isLeft(result) ? acc.errors.push(result.left) : acc.types.push(result.right);
174
- return acc;
175
- },
176
- {
177
- errors: [],
178
- types: [],
179
- },
180
- );
181
- }
182
-
183
- return pipe(reflectionResult, reduceReflectionResultIntoSingleEither, ({ errors, types }) =>
184
- errors.length ? E.left(errors) : E.right(types),
185
- );
186
- }
187
-
188
- function addFileMetadataToTypeAnnotation(type: Type, metadata: string | null): Type {
189
- return pipe(
190
- O.fromNullable(metadata),
191
- O.map((metadata) => {
192
- const metadataParams = MetadataProcessor.process(metadata);
193
- metadataParams.forEach((value, key) => {
194
- const declaration = `${key}: ${value}`;
195
- type.annotations.push({
196
- rawDeclaration: declaration,
197
- name: declaration,
198
- type: declaration,
199
- });
200
- });
201
- return type;
202
- }),
203
- O.getOrElse(() => type),
204
- );
205
- }
206
-
207
- export class ReflectionError {
208
- constructor(
209
- public file: string,
210
- public message: string,
211
- ) {}
212
- }
213
-
214
- function reflectSourceBody(apexBundle: ApexBundle): E.Either<ReflectionError, Type> {
215
- const { filePath, rawTypeContent: input, rawMetadataContent: metadata } = apexBundle;
216
- const result = mirrorReflection(input);
217
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
218
- return result.error
219
- ? E.left(new ReflectionError(filePath, result.error.message))
220
- : E.right(addFileMetadataToTypeAnnotation(result.typeMirror!, metadata));
221
- }
222
-
223
- function resolveApexTypeTemplate(renderable: Renderable): CompilationRequest {
224
- function getTemplate(renderable: Renderable): string {
225
- switch (renderable.type) {
226
- case 'enum':
227
- return enumMarkdownTemplate;
228
- case 'interface':
229
- return interfaceMarkdownTemplate;
230
- case 'class':
231
- return classMarkdownTemplate;
232
- }
233
- }
234
-
235
- return {
236
- template: getTemplate(renderable),
237
- source: renderable as RenderableEnum,
238
- };
239
- }
240
-
241
- function compile(request: CompilationRequest): string {
242
- return Template.getInstance().compile(request);
243
- }
244
-
245
- function findType(repository: Type[], referenceName: string) {
246
- return repository.find((currentType: Type) => currentType.name.toLowerCase() === referenceName.toLowerCase());
247
- }
248
-
249
- function addInheritedMembers<T extends Type>(current: T, repository: Type[]): T {
250
- if (current.type_name === 'enum') {
251
- return current;
252
- } else if (current.type_name === 'interface') {
253
- return addInheritedInterfaceMethods(current as InterfaceMirror, repository) as T;
254
- } else {
255
- return addInheritedClassMembers(current as ClassMirror, repository) as T;
256
- }
257
- }
258
-
259
- function addInheritanceChain<T extends Type>(current: T, repository: Type[]): T {
260
- if (current.type_name === 'enum' || current.type_name === 'interface') {
261
- return current;
262
- } else {
263
- const inheritanceChain = createInheritanceChain(repository, current as ClassMirror);
264
- return {
265
- ...current,
266
- inheritanceChain,
267
- };
268
- }
269
- }
270
-
271
- function getParents<T extends Type>(
272
- extendedNamesExtractor: (current: T) => string[],
273
- current: T,
274
- repository: Type[],
275
- ): T[] {
276
- return pipe(
277
- extendedNamesExtractor(current),
278
- (interfaces: string[]) => interfaces.map((interfaceName) => repository.find((type) => type.name === interfaceName)),
279
- (interfaces = []) => interfaces.filter((type) => type !== undefined) as T[],
280
- (interfaces) =>
281
- interfaces.reduce<T[]>(
282
- (acc, current) => [...acc, ...getParents(extendedNamesExtractor, current, repository)],
283
- interfaces,
284
- ),
285
- );
286
- }
287
-
288
- function addInheritedInterfaceMethods(interfaceMirror: InterfaceMirror, repository: Type[]): InterfaceMirror {
289
- function methodAlreadyExists(memberName: string, members: { name: string }[]) {
290
- return members.some((member) => member.name.toLowerCase() === memberName.toLowerCase());
291
- }
292
-
293
- function parentExtractor(interfaceMirror: InterfaceMirror): string[] {
294
- return interfaceMirror.extended_interfaces;
295
- }
296
-
297
- const parents = getParents(parentExtractor, interfaceMirror, repository);
298
- return {
299
- ...interfaceMirror,
300
- methods: parents.reduce(
301
- (acc, currentValue) => [
302
- ...acc,
303
- ...currentValue.methods
304
- .filter((method) => !methodAlreadyExists(method.name, acc))
305
- .map((method) => ({
306
- ...method,
307
- inherited: true,
308
- })),
309
- ],
310
- interfaceMirror.methods,
311
- ),
312
- };
313
- }
314
-
315
- function addInheritedClassMembers(classMirror: ClassMirror, repository: Type[]): ClassMirror {
316
- function memberAlreadyExists(memberName: string, members: { name: string }[]) {
317
- return members.some((member) => member.name.toLowerCase() === memberName.toLowerCase());
318
- }
319
-
320
- function parentExtractor(classMirror: ClassMirror): string[] {
321
- return classMirror.extended_class ? [classMirror.extended_class] : [];
322
- }
323
-
324
- function filterMember<T extends { name: string; access_modifier: string }>(members: T[], existing: T[]): T[] {
325
- return members
326
- .filter((member) => member.access_modifier.toLowerCase() !== 'private')
327
- .filter((member) => !memberAlreadyExists(member.name, existing))
328
- .map((member) => ({
329
- ...member,
330
- inherited: true,
331
- }));
332
- }
333
-
334
- const parents = getParents(parentExtractor, classMirror, repository);
335
- return {
336
- ...classMirror,
337
- fields: parents.reduce(
338
- (acc, currentValue) => [...acc, ...filterMember(currentValue.fields, acc)],
339
- classMirror.fields,
340
- ),
341
- properties: parents.reduce(
342
- (acc, currentValue) => [...acc, ...filterMember(currentValue.properties, acc)],
343
- classMirror.properties,
344
- ),
345
- methods: parents.reduce(
346
- (acc, currentValue) => [...acc, ...filterMember(currentValue.methods, acc)],
347
- classMirror.methods,
348
- ),
349
- };
350
- }
351
-
352
- function linkFromTypeNameGenerator(
353
- typeBeingDocumented: Type,
354
- repository: Type[],
355
- referenceName: string,
356
- config: DocumentationConfig,
357
- ): StringOrLink {
358
- const type = findType(repository, referenceName);
359
- if (!type) {
360
- // If the type is not found, we return the type name as a string.
361
- return referenceName;
362
- }
363
-
364
- const [fullClassName, fileLink] = getFileLinkTuple(typeBeingDocumented, type, config);
365
- return {
366
- __type: 'link',
367
- title: fullClassName,
368
- url: fileLink,
369
- };
370
- }
371
-
372
- function getFileLinkTuple(
373
- typeBeingDocumented: Type,
374
- referencedType: Type,
375
- config: DocumentationConfig,
376
- ): [string, string] {
377
- const namespacePrefix = config.namespace ? `${config.namespace}.` : '';
378
- const directoryRoot = `${getDirectoryRoot(typeBeingDocumented, referencedType, config)}`;
379
- // TODO: Instead of adding a "." to the name when there is a namespace, maybe we want to create a folder for everything
380
- // within that namespace and put the files in there.
381
- const fullClassName = `${namespacePrefix}${referencedType.name}`;
382
- return [fullClassName, `${directoryRoot}${fullClassName}.md`];
383
- }
384
-
385
- function getDirectoryFromRoot(config: DocumentationConfig, type?: Type): string {
386
- if (!type) {
387
- return '';
388
- }
389
- return `./${getSanitizedGroup(type, config)}`;
390
- }
391
-
392
- function getPossibleLinkFromRoot(config: DocumentationConfig, fallback: string, type?: Type): StringOrLink {
393
- if (!type) {
394
- return fallback;
395
- }
396
- const namespacePrefix = config.namespace ? `${config.namespace}.` : '';
397
- const title = `${namespacePrefix}${type.name}`;
398
- return {
399
- __type: 'link',
400
- title: title,
401
- url: `${getDirectoryFromRoot(config, type)}/${title}.md`,
402
- };
403
- }
404
-
405
- function getLinkFromRoot(config: DocumentationConfig, type: Type): Link {
406
- const namespacePrefix = config.namespace ? `${config.namespace}.` : '';
407
- const title = `${namespacePrefix}${type.name}`;
408
- return {
409
- __type: 'link',
410
- title: title,
411
- url: `${getDirectoryFromRoot(config, type)}/${title}.md`,
412
- };
413
- }
414
-
415
- function getDirectoryRoot(typeBeingDocumented: Type, referencedType: Type, config: DocumentationConfig) {
416
- if (getTypeGroup(typeBeingDocumented, config) === getTypeGroup(referencedType, config)) {
417
- // If the types the same groups then we simply link directly to that file
418
- return './';
419
- } else {
420
- // If the types have different groups, then we have to go up a directory
421
- return `../${getSanitizedGroup(referencedType, config)}/`;
422
- }
423
- }
424
-
425
- function getTypeGroup(type: Type, config: DocumentationConfig): string {
426
- const groupAnnotation = type.docComment?.annotations.find((annotation) => annotation.name.toLowerCase() === 'group');
427
- return groupAnnotation?.body ?? config.defaultGroupName;
428
- }
429
-
430
- function getSanitizedGroup(classModel: Type, config: DocumentationConfig) {
431
- return getTypeGroup(classModel, config).replace(/ /g, '-').replace('.', '');
432
- }
@@ -1,122 +0,0 @@
1
- import { OutputFile } from './outputFile';
2
- import ClassFileGeneratorHelper from '../transpiler/markdown/class-file-generatorHelper';
3
-
4
- export class MarkdownFile extends OutputFile {
5
- fileExtension(): string {
6
- return '.md';
7
- }
8
-
9
- addTitle(text: string, level = 1) {
10
- let title = '';
11
- for (let i = 0; i < level; i++) {
12
- title += '#';
13
- }
14
-
15
- title += ' ';
16
- title += text;
17
- this._contents += title;
18
- this.addBlankLine();
19
- }
20
-
21
- public addText(text: string) {
22
- super.addText(text);
23
- return this;
24
- }
25
-
26
- public addLink(text: string) {
27
- this.addText(`{@link ${text}}`);
28
- }
29
-
30
- startCodeBlock(language = 'apex') {
31
- this.addText(`\`\`\`${language}`);
32
- }
33
-
34
- endCodeBlock() {
35
- this.addText('```');
36
- this.addBlankLine();
37
- }
38
-
39
- addHorizontalRule() {
40
- this._contents += '---';
41
- this.addBlankLine();
42
- }
43
-
44
- initializeTable(...headers: string[]) {
45
- this.addBlankLine();
46
- this._contents += '|';
47
- headers.forEach((header) => {
48
- this._contents += header + '|';
49
- });
50
- this.addBlankLine();
51
- this._contents += '|';
52
- headers.forEach(() => {
53
- this._contents += '---' + '|';
54
- });
55
- this.addBlankLine();
56
- }
57
-
58
- addTableRow(...columns: string[]) {
59
- this._contents += '|';
60
- columns.forEach((column) => {
61
- this._contents += this._replaceInlineReferences(column) + '|';
62
- });
63
- this.addBlankLine();
64
- }
65
-
66
- addListItem(text: string) {
67
- this._contents += `* ${text}`;
68
- }
69
-
70
- protected static replaceInlineLinks(text: string) {
71
- // Parsing text to extract possible linking classes.
72
- const possibleLinks = text.match(/<<.*?>>/g);
73
- possibleLinks?.forEach((currentMatch) => {
74
- const classNameForMatch = currentMatch.replace('<<', '').replace('>>', '');
75
- text = text.replace(currentMatch, ClassFileGeneratorHelper.getFileLinkByTypeName(classNameForMatch));
76
- });
77
-
78
- // Parsing links using {@link ClassName} format
79
- const linkFormatRegEx = '{@link (.*?)}';
80
- const expression = new RegExp(linkFormatRegEx, 'gi');
81
- let match;
82
- const matches = [];
83
-
84
- do {
85
- match = expression.exec(text);
86
- if (match) {
87
- matches.push(match);
88
- }
89
- } while (match);
90
-
91
- for (const currentMatch of matches) {
92
- text = text.replace(currentMatch[0], ClassFileGeneratorHelper.getFileLinkByTypeName(currentMatch[1]));
93
- }
94
- return text;
95
- }
96
-
97
- protected static replaceInlineEmails(text: string) {
98
- // Parsing links using {@link ClassName} format
99
- const linkFormatRegEx = '{@email (.*?)}';
100
- const expression = new RegExp(linkFormatRegEx, 'gi');
101
- let match;
102
- const matches = [];
103
-
104
- do {
105
- match = expression.exec(text);
106
- if (match) {
107
- matches.push(match);
108
- }
109
- } while (match);
110
-
111
- for (const currentMatch of matches) {
112
- text = text.replace(currentMatch[0], `[${currentMatch[1]}](mailto:${currentMatch[1]})`);
113
- }
114
- return text;
115
- }
116
-
117
- private _replaceInlineReferences(text: string): string {
118
- text = MarkdownFile.replaceInlineLinks(text);
119
- text = MarkdownFile.replaceInlineEmails(text);
120
- return text;
121
- }
122
- }
@@ -1,50 +0,0 @@
1
- import { DocComment, DocCommentAnnotation } from '@cparra/apex-reflection';
2
- import ClassFileGeneratorHelper from '../../transpiler/markdown/class-file-generatorHelper';
3
- import { MarkdownFile } from '../markdown-file';
4
-
5
- interface DocCommentAware {
6
- docComment?: DocComment;
7
- }
8
-
9
- export function addMermaid(markdownFile: MarkdownFile, docCommentAware: DocCommentAware) {
10
- const mermaid = docCommentAware.docComment?.annotations.find((annotation) => annotation.name === 'mermaid');
11
- if (!mermaid) {
12
- return;
13
- }
14
-
15
- markdownFile.addBlankLine();
16
- markdownFile.startCodeBlock('mermaid');
17
- mermaid.bodyLines.forEach((line) => {
18
- markdownFile.addText(line);
19
- });
20
- markdownFile.endCodeBlock();
21
- markdownFile.addBlankLine();
22
- }
23
-
24
- export function addCustomDocCommentAnnotations(markdownFile: MarkdownFile, docCommentAware: DocCommentAware) {
25
- docCommentAware.docComment?.annotations
26
- .filter((currentAnnotation: DocCommentAnnotation) => currentAnnotation.name !== 'description')
27
- .filter((currentAnnotation: DocCommentAnnotation) => currentAnnotation.name !== 'mermaid')
28
- .forEach((currentAnnotation: DocCommentAnnotation) => {
29
- markdownFile.addBlankLine();
30
- markdownFile.addText(buildDocAnnotationText(currentAnnotation));
31
- markdownFile.addBlankLine();
32
- });
33
-
34
- function splitAndCapitalize(text: string) {
35
- const words = text.split(/[-_]+/);
36
- const capitalizedWords = [];
37
- for (const word of words) {
38
- capitalizedWords.push(word.charAt(0).toUpperCase() + word.slice(1));
39
- }
40
- return capitalizedWords.join(' ');
41
- }
42
-
43
- function buildDocAnnotationText(annotation: DocCommentAnnotation) {
44
- let annotationBodyText = annotation.body;
45
- if (annotation.name.toLowerCase() === 'see') {
46
- annotationBodyText = ClassFileGeneratorHelper.getFileLinkByTypeName(annotation.body);
47
- }
48
- return `**${splitAndCapitalize(annotation.name)}** ${annotationBodyText}`;
49
- }
50
- }