@cparra/apexdocs 2.25.0-alpha.6 → 2.25.0-alpha.9

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 (53) hide show
  1. package/dist/cli/generate.js +192 -225
  2. package/dist/index.d.ts +51 -13
  3. package/examples/plain-markdown/docs/index.md +25 -33
  4. package/examples/plain-markdown/docs/{Miscellaneous/ns.BaseClass.md → miscellaneous/BaseClass.md} +1 -1
  5. package/examples/plain-markdown/docs/{Miscellaneous/ns.MultiInheritanceClass.md → miscellaneous/MultiInheritanceClass.md} +5 -6
  6. package/examples/plain-markdown/docs/{Miscellaneous/ns.SampleException.md → miscellaneous/SampleException.md} +3 -4
  7. package/examples/plain-markdown/docs/{Miscellaneous/ns.SampleInterface.md → miscellaneous/SampleInterface.md} +22 -29
  8. package/examples/plain-markdown/docs/{Miscellaneous/ns.Url.md → miscellaneous/Url.md} +32 -43
  9. package/examples/plain-markdown/docs/sample-enums/SampleEnum.md +36 -0
  10. package/examples/plain-markdown/docs/{SampleGroup/ns.SampleClass.md → samplegroup/SampleClass.md} +8 -11
  11. package/examples/vitepress/apexdocs.config.ts +1 -3
  12. package/examples/vitepress/docs/.vitepress/sidebar.json +18 -18
  13. package/examples/vitepress/docs/index.md +11 -82
  14. package/examples/vitepress/docs/{Miscellaneous/apexdocs.BaseClass.md → miscellaneous/BaseClass.md} +1 -1
  15. package/examples/vitepress/docs/{Miscellaneous/apexdocs.MultiInheritanceClass.md → miscellaneous/MultiInheritanceClass.md} +4 -6
  16. package/examples/vitepress/docs/{Miscellaneous/apexdocs.SampleException.md → miscellaneous/SampleException.md} +1 -1
  17. package/examples/vitepress/docs/{Miscellaneous/apexdocs.SampleInterface.md → miscellaneous/SampleInterface.md} +22 -28
  18. package/examples/vitepress/docs/{Miscellaneous/apexdocs.Url.md → miscellaneous/Url.md} +31 -32
  19. package/examples/vitepress/docs/sample-enums/SampleEnum.md +40 -0
  20. package/examples/vitepress/docs/{SampleGroup/apexdocs.SampleClass.md → samplegroup/SampleClass.md} +6 -10
  21. package/examples/vitepress/force-app/main/default/classes/Url.cls +7 -4
  22. package/package.json +1 -1
  23. package/src/application/apex-file-reader.ts +3 -3
  24. package/src/application/file-writer.ts +5 -9
  25. package/src/application/generators/markdown.ts +9 -4
  26. package/src/application/generators/openapi.ts +4 -4
  27. package/src/core/markdown/__test__/generating-class-docs.spec.ts +11 -3
  28. package/src/core/markdown/__test__/generating-enum-docs.spec.ts +7 -3
  29. package/src/core/markdown/__test__/generating-interface-docs.spec.ts +11 -3
  30. package/src/core/markdown/__test__/generating-reference-guide.spec.ts +3 -7
  31. package/src/core/markdown/__test__/test-helpers.ts +3 -3
  32. package/src/core/markdown/adapters/__tests__/interface-adapter.spec.ts +40 -5
  33. package/src/core/markdown/adapters/apex-types.ts +3 -2
  34. package/src/core/markdown/adapters/documentables.ts +49 -68
  35. package/src/core/markdown/adapters/reference-guide.ts +35 -0
  36. package/src/core/markdown/adapters/renderable-bundle.ts +43 -119
  37. package/src/core/markdown/adapters/renderable-to-page-data.ts +12 -15
  38. package/src/core/markdown/adapters/types.d.ts +5 -8
  39. package/src/core/markdown/generate-docs.ts +99 -42
  40. package/src/core/markdown/reflection/inheritance-chain-expanion.ts +1 -1
  41. package/src/core/markdown/reflection/reflect-source.ts +8 -4
  42. package/src/core/markdown/templates/documentable-partial-template.ts +1 -1
  43. package/src/core/openapi/manifest-factory.ts +2 -2
  44. package/src/core/openapi/openapi-type-file.ts +1 -3
  45. package/src/core/openapi/parser.ts +4 -4
  46. package/src/core/shared/types.d.ts +52 -14
  47. package/src/index.ts +2 -1
  48. package/examples/plain-markdown/docs/Sample-Enums/ns.SampleEnum.md +0 -38
  49. package/examples/vitepress/docs/Sample-Enums/apexdocs.SampleEnum.md +0 -41
  50. /package/examples/plain-markdown/docs/{Miscellaneous/ns.ParentInterface.md → miscellaneous/ParentInterface.md} +0 -0
  51. /package/examples/plain-markdown/docs/{Miscellaneous/ns.ReferencedEnum.md → miscellaneous/ReferencedEnum.md} +0 -0
  52. /package/examples/vitepress/docs/{Miscellaneous/apexdocs.ParentInterface.md → miscellaneous/ParentInterface.md} +0 -0
  53. /package/examples/vitepress/docs/{Miscellaneous/apexdocs.ReferencedEnum.md → miscellaneous/ReferencedEnum.md} +0 -0
@@ -1,144 +1,68 @@
1
- import { ParsedFile } from '../../shared/types';
2
- import { Link, RenderableBundle, StringOrLink } from './types';
1
+ import { DocPageReference, ParsedFile } from '../../shared/types';
2
+ import { Link, ReferenceGuideReference, Renderable, RenderableBundle, StringOrLink } from './types';
3
3
  import { typeToRenderable } from './apex-types';
4
4
  import { adaptDescribable } from './documentables';
5
- import { Type } from '@cparra/apex-reflection';
6
5
  import { MarkdownGeneratorConfig } from '../generate-docs';
6
+ import { apply } from '#utils/fp';
7
+ import { Type } from '@cparra/apex-reflection';
7
8
 
8
9
  export function parsedFilesToRenderableBundle(
9
10
  config: MarkdownGeneratorConfig,
10
11
  parsedFiles: ParsedFile[],
12
+ references: Record<string, DocPageReference>,
11
13
  ): RenderableBundle {
12
- return parsedFiles.reduce<RenderableBundle>(
13
- (acc, parsedFile) => {
14
- const renderable = typeToRenderable(
15
- parsedFile,
16
- (referenceName) => {
17
- return linkFromTypeNameGenerator(
18
- parsedFile.type,
19
- parsedFiles.map((file) => file.type),
20
- referenceName,
21
- config,
22
- );
23
- },
24
- config,
25
- );
26
- acc.renderables.push(renderable);
14
+ const referenceFinder = apply(linkGenerator, references);
27
15
 
28
- const descriptionLines = parsedFile.type.docComment?.descriptionLines;
29
- const reference = {
30
- typeName: parsedFile.type.name,
31
- directory: getDirectoryFromRoot(config, parsedFile.type),
32
- title: getLinkFromRoot(config, parsedFile.type),
33
- description: adaptDescribable(descriptionLines, (referenceName) =>
34
- getPossibleLinkFromRoot(
35
- config,
36
- referenceName,
37
- findType(
38
- parsedFiles.map((file) => file.type),
39
- referenceName,
40
- ),
41
- ),
42
- ).description,
43
- };
44
-
45
- const group = getTypeGroup(parsedFile.type, config);
46
- if (!acc.references[group]) {
47
- acc.references[group] = [];
48
- }
49
- acc.references[group].push(reference);
16
+ function toReferenceGuide(parsedFiles: ParsedFile[]): Record<string, ReferenceGuideReference[]> {
17
+ return parsedFiles.reduce<Record<string, ReferenceGuideReference[]>>(
18
+ addToReferenceGuide(referenceFinder, config, references),
19
+ {},
20
+ );
21
+ }
50
22
 
23
+ function toRenderables(parsedFiles: ParsedFile[]): Renderable[] {
24
+ return parsedFiles.reduce<Renderable[]>((acc, parsedFile) => {
25
+ const renderable = typeToRenderable(parsedFile, referenceFinder, config);
26
+ acc.push(renderable);
51
27
  return acc;
52
- },
53
- {
54
- references: {},
55
- renderables: [],
56
- },
57
- );
58
- }
59
-
60
- function linkFromTypeNameGenerator(
61
- typeBeingDocumented: Type,
62
- repository: Type[],
63
- referenceName: string,
64
- config: MarkdownGeneratorConfig,
65
- ): StringOrLink {
66
- const type = findType(repository, referenceName);
67
- if (!type) {
68
- // If the type is not found, we return the type name as a string.
69
- return referenceName;
28
+ }, []);
70
29
  }
71
30
 
72
- const [fullClassName, fileLink] = getFileLinkTuple(typeBeingDocumented, type, config);
73
31
  return {
74
- __type: 'link',
75
- title: fullClassName,
76
- url: fileLink,
32
+ referencesByGroup: toReferenceGuide(parsedFiles),
33
+ renderables: toRenderables(parsedFiles),
77
34
  };
78
35
  }
79
36
 
80
- function getPossibleLinkFromRoot(config: MarkdownGeneratorConfig, fallback: string, type?: Type): StringOrLink {
81
- if (!type) {
82
- return fallback;
83
- }
84
- const namespacePrefix = config.namespace ? `${config.namespace}.` : '';
85
- const title = `${namespacePrefix}${type.name}`;
86
- return {
87
- __type: 'link',
88
- title: title,
89
- url: `${getDirectoryFromRoot(config, type)}/${title}.md`,
90
- };
91
- }
92
-
93
- function getDirectoryFromRoot(config: MarkdownGeneratorConfig, type?: Type): string {
94
- if (!type) {
95
- return '';
96
- }
97
- return `./${getSanitizedGroup(type, config)}`;
98
- }
99
-
100
- function findType(repository: Type[], referenceName: string) {
101
- return repository.find((currentType: Type) => currentType.name.toLowerCase() === referenceName.toLowerCase());
102
- }
103
-
104
- function getFileLinkTuple(
105
- typeBeingDocumented: Type,
106
- referencedType: Type,
37
+ function addToReferenceGuide(
38
+ findLinkFromHome: (referenceName: string) => string | Link,
107
39
  config: MarkdownGeneratorConfig,
108
- ): [string, string] {
109
- const namespacePrefix = config.namespace ? `${config.namespace}.` : '';
110
- const directoryRoot = `${getDirectoryRoot(typeBeingDocumented, referencedType, config)}`;
111
- // TODO: Instead of adding a "." to the name when there is a namespace, maybe we want to create a folder for everything
112
- // within that namespace and put the files in there.
113
- const fullClassName = `${namespacePrefix}${referencedType.name}`;
114
- return [fullClassName, `${directoryRoot}${fullClassName}.md`];
115
- }
40
+ references: Record<string, DocPageReference>,
41
+ ) {
42
+ return (acc: Record<string, ReferenceGuideReference[]>, parsedFile: ParsedFile) => {
43
+ const group: string = getTypeGroup(parsedFile.type, config);
44
+ if (!acc[group]) {
45
+ acc[group] = [];
46
+ }
47
+ acc[group].push({
48
+ reference: references[parsedFile.type.name],
49
+ title: findLinkFromHome(parsedFile.type.name) as Link,
50
+ description: adaptDescribable(parsedFile.type.docComment?.descriptionLines, findLinkFromHome).description ?? null,
51
+ });
116
52
 
117
- function getDirectoryRoot(typeBeingDocumented: Type, referencedType: Type, config: MarkdownGeneratorConfig) {
118
- if (getTypeGroup(typeBeingDocumented, config) === getTypeGroup(referencedType, config)) {
119
- // If the types the same groups then we simply link directly to that file
120
- return './';
121
- } else {
122
- // If the types have different groups, then we have to go up a directory
123
- return `../${getSanitizedGroup(referencedType, config)}/`;
124
- }
53
+ return acc;
54
+ };
125
55
  }
126
56
 
57
+ const linkGenerator = (references: Record<string, DocPageReference>, referenceName: string): StringOrLink => {
58
+ const reference: DocPageReference | undefined = references[referenceName];
59
+ return reference
60
+ ? // Starting the path with a "/" will ensure the link will always be relative to the root of the site.
61
+ { __type: 'link', title: reference.displayName, url: `/${reference.pathFromRoot}` }
62
+ : referenceName;
63
+ };
64
+
127
65
  function getTypeGroup(type: Type, config: MarkdownGeneratorConfig): string {
128
66
  const groupAnnotation = type.docComment?.annotations.find((annotation) => annotation.name.toLowerCase() === 'group');
129
67
  return groupAnnotation?.body ?? config.defaultGroupName;
130
68
  }
131
-
132
- function getSanitizedGroup(classModel: Type, config: MarkdownGeneratorConfig) {
133
- return getTypeGroup(classModel, config).replace(/ /g, '-').replace('.', '');
134
- }
135
-
136
- function getLinkFromRoot(config: MarkdownGeneratorConfig, type: Type): Link {
137
- const namespacePrefix = config.namespace ? `${config.namespace}.` : '';
138
- const title = `${namespacePrefix}${type.name}`;
139
- return {
140
- __type: 'link',
141
- title: title,
142
- url: `${getDirectoryFromRoot(config, type)}/${title}.md`,
143
- };
144
- }
@@ -5,19 +5,20 @@ import { CompilationRequest, Template } from '../templates/template';
5
5
  import { enumMarkdownTemplate } from '../templates/enum-template';
6
6
  import { interfaceMarkdownTemplate } from '../templates/interface-template';
7
7
  import { classMarkdownTemplate } from '../templates/class-template';
8
+ import { defaults } from '../../../defaults';
8
9
 
9
10
  export const convertToDocumentationBundle = (
10
11
  referenceGuideTemplate: string,
11
- { references, renderables }: RenderableBundle,
12
+ { referencesByGroup, renderables }: RenderableBundle,
12
13
  ): DocumentationBundle => ({
13
14
  referenceGuide: {
14
- directory: '',
15
15
  frontmatter: null,
16
- content: referencesToReferenceGuideContent(references, referenceGuideTemplate),
17
- fileExtension: 'md',
18
- fileName: 'index',
16
+ content: referencesToReferenceGuideContent(referencesByGroup, referenceGuideTemplate),
17
+ filePath: 'index.md',
19
18
  },
20
- docs: renderables.map((renderable: Renderable) => renderableToPageData(Object.values(references).flat(), renderable)),
19
+ docs: renderables.map((renderable: Renderable) =>
20
+ renderableToPageData(Object.values(referencesByGroup).flat(), renderable),
21
+ ),
21
22
  });
22
23
 
23
24
  function referencesToReferenceGuideContent(
@@ -45,11 +46,9 @@ function referencesToReferenceGuideContent(
45
46
 
46
47
  function renderableToPageData(referenceGuideReference: ReferenceGuideReference[], renderable: Renderable): DocPageData {
47
48
  function buildDocOutput(renderable: Renderable, docContents: string): DocPageData {
48
- const reference = referenceGuideReference.find(
49
- (ref) => ref.typeName.toLowerCase() === renderable.name.toLowerCase(),
50
- );
51
-
52
- const namespacePrefix = renderable.namespace ? `${renderable.namespace}.` : '';
49
+ const reference: ReferenceGuideReference = referenceGuideReference.find(
50
+ (ref) => ref.reference.source.name.toLowerCase() === renderable.name.toLowerCase(),
51
+ )!;
53
52
 
54
53
  return {
55
54
  source: {
@@ -57,12 +56,10 @@ function renderableToPageData(referenceGuideReference: ReferenceGuideReference[]
57
56
  name: renderable.name,
58
57
  type: renderable.type,
59
58
  },
60
- fileName: `${namespacePrefix}${renderable.name}`,
61
- fileExtension: 'md',
62
- directory: `${reference?.directory}`,
59
+ filePath: reference!.reference.pathFromRoot,
63
60
  frontmatter: null,
64
61
  content: docContents,
65
- group: renderable.doc.group ?? 'Miscellaneous',
62
+ group: renderable.doc.group ?? defaults.defaultGroupName,
66
63
  };
67
64
  }
68
65
 
@@ -7,6 +7,7 @@ import {
7
7
  MethodMirror,
8
8
  PropertyMirror,
9
9
  } from '@cparra/apex-reflection';
10
+ import { DocPageReference } from '../../shared/types';
10
11
 
11
12
  export type Describable = string[] | undefined;
12
13
 
@@ -24,17 +25,14 @@ export type MethodMirrorWithInheritance = MethodMirror & InheritanceSupport;
24
25
  // Renderable types
25
26
 
26
27
  export type ReferenceGuideReference = {
27
- typeName: string;
28
- directory: string;
28
+ reference: DocPageReference;
29
29
  title: Link;
30
- description: RenderableContent[] | undefined;
30
+ description: RenderableContent[] | null;
31
31
  };
32
32
 
33
33
  export type RenderableBundle = {
34
34
  // References are grouped by their defined @group annotation
35
- references: {
36
- [key: string]: ReferenceGuideReference[];
37
- };
35
+ referencesByGroup: Record<string, ReferenceGuideReference[]>;
38
36
  renderables: Renderable[];
39
37
  };
40
38
 
@@ -84,8 +82,7 @@ type RenderableDocumentation = {
84
82
  annotations?: Annotation[];
85
83
  description?: RenderableContent[];
86
84
  customTags?: CustomTag[];
87
- mermaid: RenderableSection<CodeBlock | undefined>;
88
- example: RenderableSection<CodeBlock | undefined>;
85
+ example: RenderableSection<RenderableContent[] | undefined>;
89
86
  group?: string;
90
87
  author?: string;
91
88
  date?: string;
@@ -10,11 +10,14 @@ import {
10
10
  Frontmatter,
11
11
  PostHookDocumentationBundle,
12
12
  ReferenceGuidePageData,
13
- SourceFile,
13
+ UnparsedSourceFile,
14
14
  TransformDocPage,
15
15
  TransformDocs,
16
16
  TransformReferenceGuide,
17
17
  UserDefinedMarkdownConfig,
18
+ DocPageReference,
19
+ TransformReference,
20
+ ParsedFile,
18
21
  } from '../shared/types';
19
22
  import { parsedFilesToRenderableBundle } from './adapters/renderable-bundle';
20
23
  import { reflectSourceCode } from './reflection/reflect-source';
@@ -27,6 +30,7 @@ import { Template } from './templates/template';
27
30
  import { hookableTemplate } from './templates/hookable';
28
31
  import { sortMembers } from './reflection/sort-members';
29
32
  import { isSkip } from '../shared/utils';
33
+ import { parsedFilesToReferenceGuide } from './adapters/reference-guide';
30
34
 
31
35
  export type MarkdownGeneratorConfig = Pick<
32
36
  UserDefinedMarkdownConfig,
@@ -37,6 +41,7 @@ export type MarkdownGeneratorConfig = Pick<
37
41
  | 'transformReferenceGuide'
38
42
  | 'transformDocs'
39
43
  | 'transformDocPage'
44
+ | 'transformReference'
40
45
  > & {
41
46
  referenceGuideTemplate: string;
42
47
  sortMembersAlphabetically: boolean;
@@ -48,8 +53,9 @@ export class HookError {
48
53
  constructor(public error: unknown) {}
49
54
  }
50
55
 
51
- export function generateDocs(apexBundles: SourceFile[], config: MarkdownGeneratorConfig) {
56
+ export function generateDocs(apexBundles: UnparsedSourceFile[], config: MarkdownGeneratorConfig) {
52
57
  const filterOutOfScope = apply(filterScope, config.scope);
58
+ const convertToReferences = apply(parsedFilesToReferenceGuide, config);
53
59
  const convertToRenderableBundle = apply(parsedFilesToRenderableBundle, config);
54
60
  const convertToDocumentationBundleForTemplate = apply(convertToDocumentationBundle, config.referenceGuideTemplate);
55
61
  const sortTypeMembers = apply(sortMembers, config.sortMembersAlphabetically);
@@ -62,53 +68,45 @@ export function generateDocs(apexBundles: SourceFile[], config: MarkdownGenerato
62
68
  E.map(addInheritedMembersToTypes),
63
69
  E.map(addInheritanceChainToTypes),
64
70
  E.map(sortTypeMembers),
65
- E.map(convertToRenderableBundle),
66
- E.map(convertToDocumentationBundleForTemplate),
71
+ E.bindTo('parsedFiles'),
72
+ E.bind('references', ({ parsedFiles }) => E.right(convertToReferences(parsedFiles))),
67
73
  TE.fromEither,
68
- TE.flatMap((bundle) =>
69
- TE.tryCatch(
70
- () => documentationBundleHook(bundle, config),
71
- (error) => new HookError(error),
72
- ),
73
- ),
74
- TE.map((bundle: PostHookDocumentationBundle) => ({
75
- referenceGuide: isSkip(bundle.referenceGuide)
76
- ? bundle.referenceGuide
77
- : {
78
- ...bundle.referenceGuide,
79
- content: Template.getInstance().compile({
80
- source: {
81
- frontmatter: toFrontmatterString(bundle.referenceGuide.frontmatter),
82
- content: bundle.referenceGuide.content,
83
- },
84
- template: hookableTemplate,
85
- }),
86
- },
87
- docs: bundle.docs.map((doc) => ({
88
- ...doc,
89
- content: Template.getInstance().compile({
90
- source: {
91
- frontmatter: toFrontmatterString(doc.frontmatter),
92
- content: doc.content,
93
- },
94
- template: hookableTemplate,
95
- }),
96
- })),
97
- })),
74
+ TE.flatMap(({ parsedFiles, references }) => transformReferenceHook(config)({ references, parsedFiles })),
75
+ TE.map(({ parsedFiles, references }) => convertToRenderableBundle(parsedFiles, references)),
76
+ TE.map(convertToDocumentationBundleForTemplate),
77
+ TE.flatMap(transformDocumentationBundleHook(config)),
78
+ TE.map(postHookCompile),
98
79
  );
99
80
  }
100
81
 
101
- function toFrontmatterString(frontmatter: Frontmatter): string {
102
- if (typeof frontmatter === 'string') {
103
- return frontmatter;
82
+ function transformReferenceHook(config: MarkdownGeneratorConfig) {
83
+ async function _execute(
84
+ references: Record<string, DocPageReference>,
85
+ parsedFiles: ParsedFile[],
86
+ transformReference?: TransformReference | undefined,
87
+ ): Promise<{
88
+ references: Record<string, DocPageReference>;
89
+ parsedFiles: ParsedFile[];
90
+ }> {
91
+ return {
92
+ references: await execTransformReferenceHook(Object.values(references), transformReference),
93
+ parsedFiles,
94
+ };
104
95
  }
105
96
 
106
- if (!frontmatter) {
107
- return '';
108
- }
97
+ return ({ references, parsedFiles }: { references: Record<string, DocPageReference>; parsedFiles: ParsedFile[] }) =>
98
+ TE.tryCatch(
99
+ () => _execute(references, parsedFiles, config.transformReference),
100
+ (error) => new HookError(error),
101
+ );
102
+ }
109
103
 
110
- const yamlString = yaml.dump(frontmatter);
111
- return `---\n${yamlString}---\n`;
104
+ function transformDocumentationBundleHook(config: MarkdownGeneratorConfig) {
105
+ return (bundle: DocumentationBundle) =>
106
+ TE.tryCatch(
107
+ () => documentationBundleHook(bundle, config),
108
+ (error) => new HookError(error),
109
+ );
112
110
  }
113
111
 
114
112
  // Configurable hooks
@@ -116,6 +114,25 @@ function passThroughHook<T>(value: T): T {
116
114
  return value;
117
115
  }
118
116
 
117
+ const execTransformReferenceHook = async (
118
+ references: DocPageReference[],
119
+ hook: TransformReference = passThroughHook,
120
+ ): Promise<Record<string, DocPageReference>> => {
121
+ const hooked = references.map<Promise<DocPageReference>>(async (reference) => {
122
+ const hookedResult = await hook(reference);
123
+ return {
124
+ ...reference,
125
+ ...hookedResult,
126
+ };
127
+ });
128
+ const awaited = await Promise.all(hooked);
129
+
130
+ return awaited.reduce<Record<string, DocPageReference>>((acc, reference) => {
131
+ acc[reference.source.name] = reference;
132
+ return acc;
133
+ }, {});
134
+ };
135
+
119
136
  const documentationBundleHook = async (
120
137
  bundle: DocumentationBundle,
121
138
  config: MarkdownGeneratorConfig,
@@ -156,3 +173,43 @@ const transformDocPage = async (doc: DocPageData, hook: TransformDocPage = passT
156
173
  ...(await hook(doc)),
157
174
  };
158
175
  };
176
+
177
+ function postHookCompile(bundle: PostHookDocumentationBundle) {
178
+ return {
179
+ referenceGuide: isSkip(bundle.referenceGuide)
180
+ ? bundle.referenceGuide
181
+ : {
182
+ ...bundle.referenceGuide,
183
+ content: Template.getInstance().compile({
184
+ source: {
185
+ frontmatter: toFrontmatterString(bundle.referenceGuide.frontmatter),
186
+ content: bundle.referenceGuide.content,
187
+ },
188
+ template: hookableTemplate,
189
+ }),
190
+ },
191
+ docs: bundle.docs.map((doc) => ({
192
+ ...doc,
193
+ content: Template.getInstance().compile({
194
+ source: {
195
+ frontmatter: toFrontmatterString(doc.frontmatter),
196
+ content: doc.content,
197
+ },
198
+ template: hookableTemplate,
199
+ }),
200
+ })),
201
+ };
202
+ }
203
+
204
+ function toFrontmatterString(frontmatter: Frontmatter): string {
205
+ if (typeof frontmatter === 'string') {
206
+ return frontmatter;
207
+ }
208
+
209
+ if (!frontmatter) {
210
+ return '';
211
+ }
212
+
213
+ const yamlString = yaml.dump(frontmatter);
214
+ return `---\n${yamlString}---\n`;
215
+ }
@@ -3,7 +3,7 @@ import { createInheritanceChain } from './inheritance-chain';
3
3
  import { ParsedFile } from '../../shared/types';
4
4
  import { parsedFilesToTypes } from '../utils';
5
5
 
6
- export const addInheritanceChainToTypes = (parsedFiles: ParsedFile[]) =>
6
+ export const addInheritanceChainToTypes = (parsedFiles: ParsedFile[]): ParsedFile[] =>
7
7
  parsedFiles.map((parsedFile) => ({
8
8
  ...parsedFile,
9
9
  type: addInheritanceChain(parsedFile.type, parsedFilesToTypes(parsedFiles)),
@@ -1,4 +1,4 @@
1
- import { ParsedFile, SourceFile } from '../../shared/types';
1
+ import { ParsedFile, UnparsedSourceFile } from '../../shared/types';
2
2
  import * as E from 'fp-ts/Either';
3
3
  import { reflect as mirrorReflection, Type } from '@cparra/apex-reflection';
4
4
  import { pipe } from 'fp-ts/function';
@@ -6,17 +6,21 @@ import * as O from 'fp-ts/Option';
6
6
  import { parseApexMetadata } from '../../parse-apex-metadata';
7
7
  import { ReflectionError } from './error-handling';
8
8
 
9
- export function reflectSourceCode(apexBundles: SourceFile[]) {
9
+ export function reflectSourceCode(apexBundles: UnparsedSourceFile[]) {
10
10
  return apexBundles.map(reflectSourceBody);
11
11
  }
12
12
 
13
- function reflectSourceBody(apexBundle: SourceFile): E.Either<ReflectionError, ParsedFile> {
13
+ function reflectSourceBody(apexBundle: UnparsedSourceFile): E.Either<ReflectionError, ParsedFile> {
14
14
  const { filePath, content: input, metadataContent: metadata } = apexBundle;
15
15
  const result = mirrorReflection(input);
16
16
  return result.error
17
17
  ? E.left(new ReflectionError(filePath, result.error.message))
18
18
  : E.right({
19
- filePath,
19
+ source: {
20
+ filePath,
21
+ name: result.typeMirror!.name,
22
+ type: result.typeMirror!.type_name,
23
+ },
20
24
  type: addFileMetadataToTypeAnnotation(result.typeMirror!, metadata),
21
25
  });
22
26
  }
@@ -21,6 +21,6 @@ export const documentablePartialTemplate = `
21
21
 
22
22
  {{#if doc.example.value}}
23
23
  {{ heading doc.example.headingLevel doc.example.heading }}
24
- {{code doc.example.value}}
24
+ {{{renderContent doc.example.value}}}
25
25
  {{/if}}
26
26
  `.trim();
@@ -1,7 +1,7 @@
1
1
  import Manifest from '../manifest';
2
2
  import { TypeParser } from './parser';
3
3
  import { ReflectionResult } from '@cparra/apex-reflection';
4
- import { SourceFile } from '../shared/types';
4
+ import { UnparsedSourceFile } from '../shared/types';
5
5
 
6
6
  /**
7
7
  * Builds a new Manifest object, sourcing its types from the received TypeParser.
@@ -10,7 +10,7 @@ import { SourceFile } from '../shared/types';
10
10
  */
11
11
  export function createManifest(
12
12
  typeParser: TypeParser,
13
- reflect: (apexBundle: SourceFile) => ReflectionResult,
13
+ reflect: (apexBundle: UnparsedSourceFile) => ReflectionResult,
14
14
  ): Manifest {
15
15
  return new Manifest(typeParser.parse(reflect));
16
16
  }
@@ -4,9 +4,7 @@ import { OpenApiPageData } from '../shared/types';
4
4
  export function createOpenApiFile(fileName: string, openApiModel: OpenApi): OpenApiPageData {
5
5
  const content = JSON.stringify({ ...openApiModel, namespace: undefined }, null, 2);
6
6
  return {
7
- fileExtension: 'json',
8
- fileName,
9
- directory: '',
7
+ filePath: '',
10
8
  content,
11
9
  frontmatter: null,
12
10
  group: null,
@@ -1,18 +1,18 @@
1
1
  import { ClassMirror, InterfaceMirror, ReflectionResult, Type } from '@cparra/apex-reflection';
2
2
  import { parseApexMetadata } from '../parse-apex-metadata';
3
3
  import { Logger } from '#utils/logger';
4
- import { SourceFile } from '../shared/types';
4
+ import { UnparsedSourceFile } from '../shared/types';
5
5
 
6
6
  export interface TypeParser {
7
- parse(reflect: (apexBundle: SourceFile) => ReflectionResult): Type[];
7
+ parse(reflect: (apexBundle: UnparsedSourceFile) => ReflectionResult): Type[];
8
8
  }
9
9
 
10
10
  type NameAware = { name: string };
11
11
 
12
12
  export class RawBodyParser implements TypeParser {
13
- constructor(public typeBundles: SourceFile[]) {}
13
+ constructor(public typeBundles: UnparsedSourceFile[]) {}
14
14
 
15
- parse(reflect: (apexBundle: SourceFile) => ReflectionResult): Type[] {
15
+ parse(reflect: (apexBundle: UnparsedSourceFile) => ReflectionResult): Type[] {
16
16
  const types = this.typeBundles
17
17
  .map((currentBundle) => {
18
18
  Logger.log(`Parsing file: ${currentBundle.filePath}`);