@cparra/apexdocs 2.25.0-alpha.8 → 3.0.0-alpha.1
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.
- package/dist/cli/generate.js +167 -180
- package/dist/defaults-jLXD2y8-.js +13 -0
- package/dist/index.d.ts +53 -14
- package/dist/index.js +1 -1
- package/examples/{plain-markdown → markdown}/docs/index.md +25 -33
- package/examples/{plain-markdown/docs/Miscellaneous/ns.BaseClass.md → markdown/docs/miscellaneous/BaseClass.md} +1 -1
- package/examples/{plain-markdown/docs/Miscellaneous/ns.MultiInheritanceClass.md → markdown/docs/miscellaneous/MultiInheritanceClass.md} +5 -6
- package/examples/{plain-markdown/docs/Miscellaneous/ns.SampleException.md → markdown/docs/miscellaneous/SampleException.md} +3 -4
- package/examples/{plain-markdown/docs/Miscellaneous/ns.SampleInterface.md → markdown/docs/miscellaneous/SampleInterface.md} +22 -29
- package/examples/{plain-markdown/docs/Miscellaneous/ns.Url.md → markdown/docs/miscellaneous/Url.md} +32 -43
- package/examples/markdown/docs/sample-enums/SampleEnum.md +36 -0
- package/examples/{plain-markdown/docs/SampleGroup/ns.SampleClass.md → markdown/docs/samplegroup/SampleClass.md} +8 -11
- package/examples/vitepress/apexdocs.config.ts +1 -3
- package/examples/vitepress/docs/.vitepress/sidebar.json +18 -18
- package/examples/vitepress/docs/index.md +10 -10
- package/examples/vitepress/docs/{Miscellaneous/apexdocs.BaseClass.md → miscellaneous/BaseClass.md} +1 -1
- package/examples/vitepress/docs/{Miscellaneous/apexdocs.MultiInheritanceClass.md → miscellaneous/MultiInheritanceClass.md} +2 -2
- package/examples/vitepress/docs/{Miscellaneous/apexdocs.SampleException.md → miscellaneous/SampleException.md} +1 -1
- package/examples/vitepress/docs/{Miscellaneous/apexdocs.SampleInterface.md → miscellaneous/SampleInterface.md} +6 -6
- package/examples/vitepress/docs/{Miscellaneous/apexdocs.Url.md → miscellaneous/Url.md} +3 -3
- package/examples/vitepress/docs/{Sample-Enums/apexdocs.SampleEnum.md → sample-enums/SampleEnum.md} +3 -3
- package/examples/vitepress/docs/{SampleGroup/apexdocs.SampleClass.md → samplegroup/SampleClass.md} +4 -4
- package/package.json +1 -1
- package/src/application/apex-file-reader.ts +3 -3
- package/src/application/file-writer.ts +5 -9
- package/src/application/generators/markdown.ts +9 -4
- package/src/application/generators/openapi.ts +4 -4
- package/src/cli/args.ts +1 -1
- package/src/cli/commands/markdown.ts +6 -12
- package/src/cli/generate.ts +3 -3
- package/src/core/markdown/__test__/generating-class-docs.spec.ts +5 -3
- package/src/core/markdown/__test__/generating-enum-docs.spec.ts +3 -3
- package/src/core/markdown/__test__/generating-interface-docs.spec.ts +5 -3
- package/src/core/markdown/__test__/generating-reference-guide.spec.ts +3 -7
- package/src/core/markdown/__test__/test-helpers.ts +4 -3
- package/src/core/markdown/adapters/__tests__/interface-adapter.spec.ts +41 -5
- package/src/core/markdown/adapters/apex-types.ts +3 -2
- package/src/core/markdown/adapters/reference-guide.ts +35 -0
- package/src/core/markdown/adapters/renderable-bundle.ts +52 -118
- package/src/core/markdown/adapters/renderable-to-page-data.ts +12 -15
- package/src/core/markdown/adapters/types.d.ts +4 -6
- package/src/core/markdown/generate-docs.ts +100 -42
- package/src/core/markdown/reflection/inheritance-chain-expanion.ts +1 -1
- package/src/core/markdown/reflection/reflect-source.ts +8 -4
- package/src/core/openapi/manifest-factory.ts +2 -2
- package/src/core/openapi/openapi-type-file.ts +1 -3
- package/src/core/openapi/parser.ts +4 -4
- package/src/core/shared/types.d.ts +53 -14
- package/src/defaults.ts +1 -0
- package/src/index.ts +8 -2
- package/examples/plain-markdown/docs/Sample-Enums/ns.SampleEnum.md +0 -38
- /package/examples/{plain-markdown → markdown}/.forceignore +0 -0
- /package/examples/{plain-markdown → markdown}/config/project-scratch-def.json +0 -0
- /package/examples/{plain-markdown/docs/Miscellaneous/ns.ParentInterface.md → markdown/docs/miscellaneous/ParentInterface.md} +0 -0
- /package/examples/{plain-markdown/docs/Miscellaneous/ns.ReferencedEnum.md → markdown/docs/miscellaneous/ReferencedEnum.md} +0 -0
- /package/examples/{plain-markdown → markdown}/force-app/classes/BaseClass.cls +0 -0
- /package/examples/{plain-markdown → markdown}/force-app/classes/MultiInheritanceClass.cls +0 -0
- /package/examples/{plain-markdown → markdown}/force-app/classes/ParentInterface.cls +0 -0
- /package/examples/{plain-markdown → markdown}/force-app/classes/ReferencedEnum.cls +0 -0
- /package/examples/{plain-markdown → markdown}/force-app/classes/SampleClass.cls +0 -0
- /package/examples/{plain-markdown → markdown}/force-app/classes/SampleEnum.cls +0 -0
- /package/examples/{plain-markdown → markdown}/force-app/classes/SampleException.cls +0 -0
- /package/examples/{plain-markdown → markdown}/force-app/classes/SampleInterface.cls +0 -0
- /package/examples/{plain-markdown → markdown}/force-app/classes/Url.cls +0 -0
- /package/examples/{plain-markdown → markdown}/package-lock.json +0 -0
- /package/examples/{plain-markdown → markdown}/package.json +0 -0
- /package/examples/{plain-markdown → markdown}/sfdx-project.json +0 -0
- /package/examples/vitepress/docs/{Miscellaneous/apexdocs.ParentInterface.md → miscellaneous/ParentInterface.md} +0 -0
- /package/examples/vitepress/docs/{Miscellaneous/apexdocs.ReferencedEnum.md → miscellaneous/ReferencedEnum.md} +0 -0
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { UnparsedSourceFile } from '../../shared/types';
|
|
2
2
|
import { generateDocs as gen, MarkdownGeneratorConfig } from '../generate-docs';
|
|
3
3
|
import { referenceGuideTemplate } from '../templates/reference-guide';
|
|
4
4
|
|
|
5
|
-
export function apexBundleFromRawString(raw: string, rawMetadata?: string):
|
|
5
|
+
export function apexBundleFromRawString(raw: string, rawMetadata?: string): UnparsedSourceFile {
|
|
6
6
|
return {
|
|
7
7
|
filePath: 'test.cls',
|
|
8
8
|
content: raw,
|
|
@@ -10,7 +10,7 @@ export function apexBundleFromRawString(raw: string, rawMetadata?: string): Sour
|
|
|
10
10
|
};
|
|
11
11
|
}
|
|
12
12
|
|
|
13
|
-
export function generateDocs(apexBundles:
|
|
13
|
+
export function generateDocs(apexBundles: UnparsedSourceFile[], config?: Partial<MarkdownGeneratorConfig>) {
|
|
14
14
|
return gen(apexBundles, {
|
|
15
15
|
targetDir: 'target',
|
|
16
16
|
scope: ['global', 'public'],
|
|
@@ -18,5 +18,6 @@ export function generateDocs(apexBundles: SourceFile[], config?: Partial<Markdow
|
|
|
18
18
|
sortMembersAlphabetically: true,
|
|
19
19
|
referenceGuideTemplate: referenceGuideTemplate,
|
|
20
20
|
...config,
|
|
21
|
+
documentationRootDir: '',
|
|
21
22
|
});
|
|
22
23
|
}
|
|
@@ -15,13 +15,21 @@ const defaultMarkdownGeneratorConfig: MarkdownGeneratorConfig = {
|
|
|
15
15
|
defaultGroupName: 'Miscellaneous',
|
|
16
16
|
referenceGuideTemplate: '',
|
|
17
17
|
sortMembersAlphabetically: false,
|
|
18
|
+
documentationRootDir: '',
|
|
18
19
|
};
|
|
19
20
|
|
|
20
21
|
describe('Conversion from InterfaceMirror to InterfaceSource understandable by the templating engine', () => {
|
|
21
22
|
it('converts the name', () => {
|
|
22
23
|
const interfaceMirror = new InterfaceMirrorBuilder().withName('SampleInterface').build();
|
|
23
24
|
const interfaceSource = typeToRenderable(
|
|
24
|
-
{
|
|
25
|
+
{
|
|
26
|
+
source: {
|
|
27
|
+
filePath: '',
|
|
28
|
+
type: 'interface',
|
|
29
|
+
name: 'SampleInterface',
|
|
30
|
+
},
|
|
31
|
+
type: interfaceMirror,
|
|
32
|
+
},
|
|
25
33
|
linkGenerator,
|
|
26
34
|
defaultMarkdownGeneratorConfig,
|
|
27
35
|
);
|
|
@@ -32,7 +40,14 @@ describe('Conversion from InterfaceMirror to InterfaceSource understandable by t
|
|
|
32
40
|
it('converts the access modifier', () => {
|
|
33
41
|
const interfaceMirror = new InterfaceMirrorBuilder().build();
|
|
34
42
|
const interfaceSource = typeToRenderable(
|
|
35
|
-
{
|
|
43
|
+
{
|
|
44
|
+
source: {
|
|
45
|
+
filePath: '',
|
|
46
|
+
type: 'interface',
|
|
47
|
+
name: 'SampleInterface',
|
|
48
|
+
},
|
|
49
|
+
type: interfaceMirror,
|
|
50
|
+
},
|
|
36
51
|
linkGenerator,
|
|
37
52
|
defaultMarkdownGeneratorConfig,
|
|
38
53
|
);
|
|
@@ -45,7 +60,14 @@ describe('Conversion from InterfaceMirror to InterfaceSource understandable by t
|
|
|
45
60
|
.addAnnotation(new AnnotationBuilder().withName('MyAnnotation').build())
|
|
46
61
|
.build();
|
|
47
62
|
const interfaceSource = typeToRenderable(
|
|
48
|
-
{
|
|
63
|
+
{
|
|
64
|
+
source: {
|
|
65
|
+
filePath: '',
|
|
66
|
+
type: 'interface',
|
|
67
|
+
name: 'SampleInterface',
|
|
68
|
+
},
|
|
69
|
+
type: interfaceMirror,
|
|
70
|
+
},
|
|
49
71
|
linkGenerator,
|
|
50
72
|
defaultMarkdownGeneratorConfig,
|
|
51
73
|
);
|
|
@@ -67,7 +89,14 @@ describe('Conversion from InterfaceMirror to InterfaceSource understandable by t
|
|
|
67
89
|
.build();
|
|
68
90
|
|
|
69
91
|
const interfaceSource = typeToRenderable(
|
|
70
|
-
{
|
|
92
|
+
{
|
|
93
|
+
source: {
|
|
94
|
+
filePath: '',
|
|
95
|
+
type: 'interface',
|
|
96
|
+
name: 'SampleInterface',
|
|
97
|
+
},
|
|
98
|
+
type: interfaceMirror,
|
|
99
|
+
},
|
|
71
100
|
linkGenerator,
|
|
72
101
|
defaultMarkdownGeneratorConfig,
|
|
73
102
|
);
|
|
@@ -99,7 +128,14 @@ describe('Conversion from InterfaceMirror to InterfaceSource understandable by t
|
|
|
99
128
|
.build();
|
|
100
129
|
|
|
101
130
|
const interfaceSource = typeToRenderable(
|
|
102
|
-
{
|
|
131
|
+
{
|
|
132
|
+
source: {
|
|
133
|
+
filePath: '',
|
|
134
|
+
type: 'interface',
|
|
135
|
+
name: 'SampleInterface',
|
|
136
|
+
},
|
|
137
|
+
type: interfaceMirror,
|
|
138
|
+
},
|
|
103
139
|
linkGenerator,
|
|
104
140
|
defaultMarkdownGeneratorConfig,
|
|
105
141
|
);
|
|
@@ -15,6 +15,7 @@ import { adaptDescribable, adaptDocumentable } from './documentables';
|
|
|
15
15
|
import { adaptConstructor, adaptMethod } from './methods-and-constructors';
|
|
16
16
|
import { adaptFieldOrProperty } from './fields-and-properties';
|
|
17
17
|
import { MarkdownGeneratorConfig } from '../generate-docs';
|
|
18
|
+
import { SourceFileMetadata } from '../../shared/types';
|
|
18
19
|
|
|
19
20
|
type GetReturnRenderable<T extends Type> = T extends InterfaceMirror
|
|
20
21
|
? RenderableInterface
|
|
@@ -23,7 +24,7 @@ type GetReturnRenderable<T extends Type> = T extends InterfaceMirror
|
|
|
23
24
|
: RenderableEnum;
|
|
24
25
|
|
|
25
26
|
export function typeToRenderable<T extends Type>(
|
|
26
|
-
parsedFile: {
|
|
27
|
+
parsedFile: { source: SourceFileMetadata; type: T },
|
|
27
28
|
linkGenerator: GetRenderableContentByTypeName,
|
|
28
29
|
config: MarkdownGeneratorConfig,
|
|
29
30
|
): GetReturnRenderable<T> & { filePath: string; namespace?: string } {
|
|
@@ -41,7 +42,7 @@ export function typeToRenderable<T extends Type>(
|
|
|
41
42
|
|
|
42
43
|
return {
|
|
43
44
|
...(getRenderable() as GetReturnRenderable<T>),
|
|
44
|
-
filePath: parsedFile.filePath,
|
|
45
|
+
filePath: parsedFile.source.filePath,
|
|
45
46
|
namespace: config.namespace,
|
|
46
47
|
};
|
|
47
48
|
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { MarkdownGeneratorConfig } from '../generate-docs';
|
|
2
|
+
import { DocPageReference, ParsedFile } from '../../shared/types';
|
|
3
|
+
import { Type } from '@cparra/apex-reflection';
|
|
4
|
+
|
|
5
|
+
export function parsedFilesToReferenceGuide(
|
|
6
|
+
config: MarkdownGeneratorConfig,
|
|
7
|
+
parsedFiles: ParsedFile[],
|
|
8
|
+
): Record<string, DocPageReference> {
|
|
9
|
+
return parsedFiles.reduce<Record<string, DocPageReference>>((acc, parsedFile) => {
|
|
10
|
+
acc[parsedFile.type.name] = parsedFileToDocPageReference(config, parsedFile);
|
|
11
|
+
return acc;
|
|
12
|
+
}, {});
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
function parsedFileToDocPageReference(config: MarkdownGeneratorConfig, parsedFile: ParsedFile): DocPageReference {
|
|
16
|
+
return {
|
|
17
|
+
source: parsedFile.source,
|
|
18
|
+
displayName: parsedFile.type.name,
|
|
19
|
+
pathFromRoot: `${slugify(getTypeGroup(parsedFile.type, config))}/${parsedFile.type.name}.md`,
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
function getTypeGroup(type: Type, config: MarkdownGeneratorConfig): string {
|
|
24
|
+
const groupAnnotation = type.docComment?.annotations.find((annotation) => annotation.name.toLowerCase() === 'group');
|
|
25
|
+
return groupAnnotation?.body ?? config.defaultGroupName;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
function slugify(text: string): string {
|
|
29
|
+
return text
|
|
30
|
+
.toLowerCase()
|
|
31
|
+
.replace(/[^a-z0-9\s-]/g, '') // Remove non-alphanumeric characters except spaces and hyphens
|
|
32
|
+
.trim()
|
|
33
|
+
.replace(/\s+/g, '-') // Replace spaces with hyphens
|
|
34
|
+
.replace(/-+/g, '-'); // Replace multiple hyphens with a single hyphen
|
|
35
|
+
}
|
|
@@ -1,144 +1,78 @@
|
|
|
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';
|
|
8
|
+
import * as path from 'path';
|
|
7
9
|
|
|
8
10
|
export function parsedFilesToRenderableBundle(
|
|
9
11
|
config: MarkdownGeneratorConfig,
|
|
10
12
|
parsedFiles: ParsedFile[],
|
|
13
|
+
references: Record<string, DocPageReference>,
|
|
11
14
|
): RenderableBundle {
|
|
12
|
-
|
|
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);
|
|
15
|
+
const referenceFinder = apply(linkGenerator, references, config.documentationRootDir);
|
|
27
16
|
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
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);
|
|
17
|
+
function toReferenceGuide(parsedFiles: ParsedFile[]): Record<string, ReferenceGuideReference[]> {
|
|
18
|
+
return parsedFiles.reduce<Record<string, ReferenceGuideReference[]>>(
|
|
19
|
+
addToReferenceGuide(referenceFinder, config, references),
|
|
20
|
+
{},
|
|
21
|
+
);
|
|
22
|
+
}
|
|
50
23
|
|
|
24
|
+
function toRenderables(parsedFiles: ParsedFile[]): Renderable[] {
|
|
25
|
+
return parsedFiles.reduce<Renderable[]>((acc, parsedFile) => {
|
|
26
|
+
const renderable = typeToRenderable(parsedFile, referenceFinder, config);
|
|
27
|
+
acc.push(renderable);
|
|
51
28
|
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;
|
|
29
|
+
}, []);
|
|
70
30
|
}
|
|
71
31
|
|
|
72
|
-
const [fullClassName, fileLink] = getFileLinkTuple(typeBeingDocumented, type, config);
|
|
73
32
|
return {
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
url: fileLink,
|
|
33
|
+
referencesByGroup: toReferenceGuide(parsedFiles),
|
|
34
|
+
renderables: toRenderables(parsedFiles),
|
|
77
35
|
};
|
|
78
36
|
}
|
|
79
37
|
|
|
80
|
-
function
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
return '';
|
|
96
|
-
}
|
|
97
|
-
return `./${getSanitizedGroup(type, config)}`;
|
|
98
|
-
}
|
|
38
|
+
function addToReferenceGuide(
|
|
39
|
+
findLinkFromHome: (referenceName: string) => string | Link,
|
|
40
|
+
config: MarkdownGeneratorConfig,
|
|
41
|
+
references: Record<string, DocPageReference>,
|
|
42
|
+
) {
|
|
43
|
+
return (acc: Record<string, ReferenceGuideReference[]>, parsedFile: ParsedFile) => {
|
|
44
|
+
const group: string = getTypeGroup(parsedFile.type, config);
|
|
45
|
+
if (!acc[group]) {
|
|
46
|
+
acc[group] = [];
|
|
47
|
+
}
|
|
48
|
+
acc[group].push({
|
|
49
|
+
reference: references[parsedFile.type.name],
|
|
50
|
+
title: findLinkFromHome(parsedFile.type.name) as Link,
|
|
51
|
+
description: adaptDescribable(parsedFile.type.docComment?.descriptionLines, findLinkFromHome).description ?? null,
|
|
52
|
+
});
|
|
99
53
|
|
|
100
|
-
|
|
101
|
-
|
|
54
|
+
return acc;
|
|
55
|
+
};
|
|
102
56
|
}
|
|
103
57
|
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
):
|
|
109
|
-
const
|
|
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
|
-
}
|
|
58
|
+
const linkGenerator = (
|
|
59
|
+
references: Record<string, DocPageReference>,
|
|
60
|
+
documentationRootDir: string,
|
|
61
|
+
referenceName: string,
|
|
62
|
+
): StringOrLink => {
|
|
63
|
+
const reference: DocPageReference | undefined = references[referenceName];
|
|
116
64
|
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
}
|
|
65
|
+
return reference
|
|
66
|
+
? // Starting the path with a "/" will ensure the link will always be relative to the root of the site.
|
|
67
|
+
{
|
|
68
|
+
__type: 'link',
|
|
69
|
+
title: reference.displayName,
|
|
70
|
+
url: path.join('/', documentationRootDir, reference.pathFromRoot),
|
|
71
|
+
}
|
|
72
|
+
: referenceName;
|
|
73
|
+
};
|
|
126
74
|
|
|
127
75
|
function getTypeGroup(type: Type, config: MarkdownGeneratorConfig): string {
|
|
128
76
|
const groupAnnotation = type.docComment?.annotations.find((annotation) => annotation.name.toLowerCase() === 'group');
|
|
129
77
|
return groupAnnotation?.body ?? config.defaultGroupName;
|
|
130
78
|
}
|
|
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
|
-
{
|
|
12
|
+
{ referencesByGroup, renderables }: RenderableBundle,
|
|
12
13
|
): DocumentationBundle => ({
|
|
13
14
|
referenceGuide: {
|
|
14
|
-
directory: '',
|
|
15
15
|
frontmatter: null,
|
|
16
|
-
content: referencesToReferenceGuideContent(
|
|
17
|
-
|
|
18
|
-
fileName: 'index',
|
|
16
|
+
content: referencesToReferenceGuideContent(referencesByGroup, referenceGuideTemplate),
|
|
17
|
+
filePath: 'index.md',
|
|
19
18
|
},
|
|
20
|
-
docs: renderables.map((renderable: 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.
|
|
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
|
-
|
|
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 ??
|
|
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
|
-
|
|
28
|
-
directory: string;
|
|
28
|
+
reference: DocPageReference;
|
|
29
29
|
title: Link;
|
|
30
|
-
description: RenderableContent[] |
|
|
30
|
+
description: RenderableContent[] | null;
|
|
31
31
|
};
|
|
32
32
|
|
|
33
33
|
export type RenderableBundle = {
|
|
34
34
|
// References are grouped by their defined @group annotation
|
|
35
|
-
|
|
36
|
-
[key: string]: ReferenceGuideReference[];
|
|
37
|
-
};
|
|
35
|
+
referencesByGroup: Record<string, ReferenceGuideReference[]>;
|
|
38
36
|
renderables: Renderable[];
|
|
39
37
|
};
|
|
40
38
|
|
|
@@ -10,11 +10,14 @@ import {
|
|
|
10
10
|
Frontmatter,
|
|
11
11
|
PostHookDocumentationBundle,
|
|
12
12
|
ReferenceGuidePageData,
|
|
13
|
-
|
|
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,8 @@ export type MarkdownGeneratorConfig = Pick<
|
|
|
37
41
|
| 'transformReferenceGuide'
|
|
38
42
|
| 'transformDocs'
|
|
39
43
|
| 'transformDocPage'
|
|
44
|
+
| 'transformReference'
|
|
45
|
+
| 'documentationRootDir'
|
|
40
46
|
> & {
|
|
41
47
|
referenceGuideTemplate: string;
|
|
42
48
|
sortMembersAlphabetically: boolean;
|
|
@@ -48,8 +54,9 @@ export class HookError {
|
|
|
48
54
|
constructor(public error: unknown) {}
|
|
49
55
|
}
|
|
50
56
|
|
|
51
|
-
export function generateDocs(apexBundles:
|
|
57
|
+
export function generateDocs(apexBundles: UnparsedSourceFile[], config: MarkdownGeneratorConfig) {
|
|
52
58
|
const filterOutOfScope = apply(filterScope, config.scope);
|
|
59
|
+
const convertToReferences = apply(parsedFilesToReferenceGuide, config);
|
|
53
60
|
const convertToRenderableBundle = apply(parsedFilesToRenderableBundle, config);
|
|
54
61
|
const convertToDocumentationBundleForTemplate = apply(convertToDocumentationBundle, config.referenceGuideTemplate);
|
|
55
62
|
const sortTypeMembers = apply(sortMembers, config.sortMembersAlphabetically);
|
|
@@ -62,53 +69,45 @@ export function generateDocs(apexBundles: SourceFile[], config: MarkdownGenerato
|
|
|
62
69
|
E.map(addInheritedMembersToTypes),
|
|
63
70
|
E.map(addInheritanceChainToTypes),
|
|
64
71
|
E.map(sortTypeMembers),
|
|
65
|
-
E.
|
|
66
|
-
E.
|
|
72
|
+
E.bindTo('parsedFiles'),
|
|
73
|
+
E.bind('references', ({ parsedFiles }) => E.right(convertToReferences(parsedFiles))),
|
|
67
74
|
TE.fromEither,
|
|
68
|
-
TE.flatMap((
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
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
|
-
})),
|
|
75
|
+
TE.flatMap(({ parsedFiles, references }) => transformReferenceHook(config)({ references, parsedFiles })),
|
|
76
|
+
TE.map(({ parsedFiles, references }) => convertToRenderableBundle(parsedFiles, references)),
|
|
77
|
+
TE.map(convertToDocumentationBundleForTemplate),
|
|
78
|
+
TE.flatMap(transformDocumentationBundleHook(config)),
|
|
79
|
+
TE.map(postHookCompile),
|
|
98
80
|
);
|
|
99
81
|
}
|
|
100
82
|
|
|
101
|
-
function
|
|
102
|
-
|
|
103
|
-
|
|
83
|
+
function transformReferenceHook(config: MarkdownGeneratorConfig) {
|
|
84
|
+
async function _execute(
|
|
85
|
+
references: Record<string, DocPageReference>,
|
|
86
|
+
parsedFiles: ParsedFile[],
|
|
87
|
+
transformReference?: TransformReference | undefined,
|
|
88
|
+
): Promise<{
|
|
89
|
+
references: Record<string, DocPageReference>;
|
|
90
|
+
parsedFiles: ParsedFile[];
|
|
91
|
+
}> {
|
|
92
|
+
return {
|
|
93
|
+
references: await execTransformReferenceHook(Object.values(references), transformReference),
|
|
94
|
+
parsedFiles,
|
|
95
|
+
};
|
|
104
96
|
}
|
|
105
97
|
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
98
|
+
return ({ references, parsedFiles }: { references: Record<string, DocPageReference>; parsedFiles: ParsedFile[] }) =>
|
|
99
|
+
TE.tryCatch(
|
|
100
|
+
() => _execute(references, parsedFiles, config.transformReference),
|
|
101
|
+
(error) => new HookError(error),
|
|
102
|
+
);
|
|
103
|
+
}
|
|
109
104
|
|
|
110
|
-
|
|
111
|
-
return
|
|
105
|
+
function transformDocumentationBundleHook(config: MarkdownGeneratorConfig) {
|
|
106
|
+
return (bundle: DocumentationBundle) =>
|
|
107
|
+
TE.tryCatch(
|
|
108
|
+
() => documentationBundleHook(bundle, config),
|
|
109
|
+
(error) => new HookError(error),
|
|
110
|
+
);
|
|
112
111
|
}
|
|
113
112
|
|
|
114
113
|
// Configurable hooks
|
|
@@ -116,6 +115,25 @@ function passThroughHook<T>(value: T): T {
|
|
|
116
115
|
return value;
|
|
117
116
|
}
|
|
118
117
|
|
|
118
|
+
const execTransformReferenceHook = async (
|
|
119
|
+
references: DocPageReference[],
|
|
120
|
+
hook: TransformReference = passThroughHook,
|
|
121
|
+
): Promise<Record<string, DocPageReference>> => {
|
|
122
|
+
const hooked = references.map<Promise<DocPageReference>>(async (reference) => {
|
|
123
|
+
const hookedResult = await hook(reference);
|
|
124
|
+
return {
|
|
125
|
+
...reference,
|
|
126
|
+
...hookedResult,
|
|
127
|
+
};
|
|
128
|
+
});
|
|
129
|
+
const awaited = await Promise.all(hooked);
|
|
130
|
+
|
|
131
|
+
return awaited.reduce<Record<string, DocPageReference>>((acc, reference) => {
|
|
132
|
+
acc[reference.source.name] = reference;
|
|
133
|
+
return acc;
|
|
134
|
+
}, {});
|
|
135
|
+
};
|
|
136
|
+
|
|
119
137
|
const documentationBundleHook = async (
|
|
120
138
|
bundle: DocumentationBundle,
|
|
121
139
|
config: MarkdownGeneratorConfig,
|
|
@@ -156,3 +174,43 @@ const transformDocPage = async (doc: DocPageData, hook: TransformDocPage = passT
|
|
|
156
174
|
...(await hook(doc)),
|
|
157
175
|
};
|
|
158
176
|
};
|
|
177
|
+
|
|
178
|
+
function postHookCompile(bundle: PostHookDocumentationBundle) {
|
|
179
|
+
return {
|
|
180
|
+
referenceGuide: isSkip(bundle.referenceGuide)
|
|
181
|
+
? bundle.referenceGuide
|
|
182
|
+
: {
|
|
183
|
+
...bundle.referenceGuide,
|
|
184
|
+
content: Template.getInstance().compile({
|
|
185
|
+
source: {
|
|
186
|
+
frontmatter: toFrontmatterString(bundle.referenceGuide.frontmatter),
|
|
187
|
+
content: bundle.referenceGuide.content,
|
|
188
|
+
},
|
|
189
|
+
template: hookableTemplate,
|
|
190
|
+
}),
|
|
191
|
+
},
|
|
192
|
+
docs: bundle.docs.map((doc) => ({
|
|
193
|
+
...doc,
|
|
194
|
+
content: Template.getInstance().compile({
|
|
195
|
+
source: {
|
|
196
|
+
frontmatter: toFrontmatterString(doc.frontmatter),
|
|
197
|
+
content: doc.content,
|
|
198
|
+
},
|
|
199
|
+
template: hookableTemplate,
|
|
200
|
+
}),
|
|
201
|
+
})),
|
|
202
|
+
};
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
function toFrontmatterString(frontmatter: Frontmatter): string {
|
|
206
|
+
if (typeof frontmatter === 'string') {
|
|
207
|
+
return frontmatter;
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
if (!frontmatter) {
|
|
211
|
+
return '';
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
const yamlString = yaml.dump(frontmatter);
|
|
215
|
+
return `---\n${yamlString}---\n`;
|
|
216
|
+
}
|
|
@@ -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)),
|