@cparra/apexdocs 3.0.0-rc.0 → 3.0.0

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 (107) hide show
  1. package/README.md +50 -571
  2. package/dist/cli/generate.js +73 -3094
  3. package/dist/defaults-BcE8DTat.js +13 -0
  4. package/dist/defaults-D07y_bq4.js +40 -0
  5. package/dist/defaults-gPzwP66p.js +14 -0
  6. package/dist/index.d.ts +35 -3
  7. package/dist/index.js +90 -2
  8. package/dist/logger-BEbUIfqN.js +3282 -0
  9. package/dist/logger-BGuf1PnL.js +3281 -0
  10. package/dist/logger-CWBRF2za.js +3284 -0
  11. package/dist/logger-CdBmDEN1.js +3283 -0
  12. package/dist/logger-Ce4QqPFR.js +3278 -0
  13. package/dist/logger-CyEVYaAC.js +3284 -0
  14. package/dist/logger-D7a83ycP.js +3277 -0
  15. package/dist/logger-DGaHeBKk.js +3279 -0
  16. package/dist/logger-Dqhl_lO_.js +3278 -0
  17. package/dist/logger-aySSWi0G.js +3280 -0
  18. package/dist/logger-qLCcAtiy.js +3284 -0
  19. package/examples/README.md +5 -0
  20. package/examples/docsify/README.md +17 -0
  21. package/examples/docsify/apexdocs.config.ts +13 -0
  22. package/examples/docsify/classes/ASampleClass.cls +57 -0
  23. package/examples/docsify/classes/CodeControl.cls +19 -0
  24. package/examples/docsify/classes/SampleClass.cls +95 -0
  25. package/examples/docsify/classes/SampleInterface.cls +17 -0
  26. package/examples/docsify/classes/SomeDto.cls +122 -0
  27. package/examples/docsify/docs/.nojekyll +0 -0
  28. package/examples/docsify/docs/README.md +25 -0
  29. package/examples/docsify/docs/_config.yml +1 -0
  30. package/examples/docsify/docs/index.html +22 -0
  31. package/examples/docsify/docs/miscellaneous/ASampleClass.md +88 -0
  32. package/examples/docsify/docs/miscellaneous/CodeControl.md +107 -0
  33. package/examples/docsify/docs/miscellaneous/SomeDto.md +244 -0
  34. package/examples/docsify/docs/sample-classes/SampleClass.md +171 -0
  35. package/examples/docsify/docs/sample-interfaces/SampleInterface.md +36 -0
  36. package/examples/docsify/package-lock.json +2459 -0
  37. package/examples/docsify/package.json +14 -0
  38. package/examples/imported/.forceignore +12 -0
  39. package/examples/imported/README.md +6 -0
  40. package/examples/imported/config/project-scratch-def.json +5 -0
  41. package/examples/imported/docs/index.md +109 -0
  42. package/examples/imported/docs/miscellaneous/BaseClass.md +13 -0
  43. package/examples/imported/docs/miscellaneous/MultiInheritanceClass.md +69 -0
  44. package/examples/imported/docs/miscellaneous/ParentInterface.md +12 -0
  45. package/examples/imported/docs/miscellaneous/ReferencedEnum.md +5 -0
  46. package/examples/imported/docs/miscellaneous/SampleException.md +21 -0
  47. package/examples/imported/docs/miscellaneous/SampleInterface.md +113 -0
  48. package/examples/imported/docs/miscellaneous/Url.md +308 -0
  49. package/examples/imported/docs/sample-enums/SampleEnum.md +33 -0
  50. package/examples/imported/docs/samplegroup/SampleClass.md +167 -0
  51. package/examples/imported/force-app/classes/BaseClass.cls +3 -0
  52. package/examples/imported/force-app/classes/MultiInheritanceClass.cls +1 -0
  53. package/examples/imported/force-app/classes/ParentInterface.cls +3 -0
  54. package/examples/imported/force-app/classes/ReferencedEnum.cls +3 -0
  55. package/examples/imported/force-app/classes/SampleClass.cls +72 -0
  56. package/examples/imported/force-app/classes/SampleInterface.cls +50 -0
  57. package/examples/imported/force-app/classes/Url.cls +196 -0
  58. package/examples/imported/package-lock.json +665 -0
  59. package/examples/imported/package.json +6 -0
  60. package/examples/imported/scripts/process-docs.mjs +16 -0
  61. package/examples/imported/sfdx-project.json +12 -0
  62. package/examples/markdown/README.md +7 -0
  63. package/examples/markdown-jsconfig/README.md +9 -0
  64. package/examples/markdown-jsconfig/apexdocs.config.mjs +1 -0
  65. package/examples/markdown-jsconfig/docs/index.md +1 -1
  66. package/examples/open-api/README.md +5 -0
  67. package/examples/open-api/docs/openapi.json +2 -570
  68. package/examples/vitepress/README.md +25 -0
  69. package/examples/vitepress/apexdocs.config.ts +2 -0
  70. package/examples/vitepress/force-app/main/default/classes/{SampleClass.cls → feature-a/SampleClass.cls} +1 -0
  71. package/examples/vitepress/force-app/main/default/classes/feature-a/SampleEnum.cls +30 -0
  72. package/examples/vitepress/force-app/main/default/classes/feature-a/SampleException.cls +17 -0
  73. package/package.json +2 -2
  74. package/src/application/Apexdocs.ts +16 -19
  75. package/src/application/__tests__/apex-file-reader.spec.ts +108 -67
  76. package/src/application/apex-file-reader.ts +1 -0
  77. package/src/application/generators/openapi.ts +17 -13
  78. package/src/cli/args.ts +12 -3
  79. package/src/cli/commands/markdown.ts +14 -9
  80. package/src/cli/commands/openapi.ts +5 -5
  81. package/src/cli/generate.ts +20 -4
  82. package/src/core/markdown/__test__/generating-class-docs.spec.ts +14 -257
  83. package/src/core/markdown/__test__/generating-docs.spec.ts +271 -4
  84. package/src/core/markdown/__test__/generating-enum-docs.spec.ts +4 -264
  85. package/src/core/markdown/__test__/generating-interface-docs.spec.ts +4 -232
  86. package/src/core/markdown/__test__/generating-reference-guide.spec.ts +17 -1
  87. package/src/core/markdown/__test__/test-helpers.ts +3 -1
  88. package/src/core/markdown/adapters/__tests__/interface-adapter.spec.ts +3 -1
  89. package/src/core/markdown/adapters/renderable-to-page-data.ts +6 -4
  90. package/src/core/markdown/generate-docs.ts +13 -15
  91. package/src/core/markdown/reflection/__test__/filter-scope.spec.ts +2 -18
  92. package/src/core/markdown/reflection/__test__/helpers.ts +18 -0
  93. package/src/core/markdown/reflection/__test__/remove-excluded-tags.spec.ts +200 -0
  94. package/src/core/markdown/reflection/remove-excluded-tags.ts +168 -0
  95. package/src/core/markdown/reflection/{sort-members.ts → sort-types-and-members.ts} +7 -5
  96. package/src/core/markdown/templates/reference-guide.ts +2 -2
  97. package/src/core/openapi/__tests__/open-api-docs-processor.spec.ts +6 -3
  98. package/src/core/openapi/open-api-docs-processor.ts +3 -3
  99. package/src/core/openapi/parser.ts +5 -2
  100. package/src/core/shared/types.d.ts +4 -2
  101. package/src/defaults.ts +15 -3
  102. package/src/index.ts +65 -4
  103. package/src/util/error-logger.ts +36 -36
  104. package/src/util/logger.ts +18 -11
  105. /package/examples/{vitepress/force-app/main/default → imported/force-app}/classes/SampleEnum.cls +0 -0
  106. /package/examples/{vitepress/force-app/main/default → imported/force-app}/classes/SampleException.cls +0 -0
  107. /package/examples/vitepress/force-app/main/default/classes/{SampleInterface.cls → feature-a/SampleInterface.cls} +0 -0
@@ -26,24 +26,16 @@ import { convertToDocumentationBundle } from './adapters/renderable-to-page-data
26
26
  import { filterScope } from './reflection/filter-scope';
27
27
  import { Template } from './templates/template';
28
28
  import { hookableTemplate } from './templates/hookable';
29
- import { sortMembers } from './reflection/sort-members';
29
+ import { sortTypesAndMembers } from './reflection/sort-types-and-members';
30
30
  import { isSkip } from '../shared/utils';
31
31
  import { parsedFilesToReferenceGuide } from './adapters/reference-guide';
32
+ import { removeExcludedTags } from './reflection/remove-excluded-tags';
32
33
 
33
- export type MarkdownGeneratorConfig = Pick<
34
+ export type MarkdownGeneratorConfig = Omit<
34
35
  UserDefinedMarkdownConfig,
35
- | 'targetDir'
36
- | 'scope'
37
- | 'namespace'
38
- | 'defaultGroupName'
39
- | 'transformReferenceGuide'
40
- | 'transformDocs'
41
- | 'transformDocPage'
42
- | 'transformReference'
43
- | 'linkingStrategy'
36
+ 'sourceDir' | 'targetGenerator' | 'includeMetadata'
44
37
  > & {
45
38
  referenceGuideTemplate: string;
46
- sortMembersAlphabetically: boolean;
47
39
  };
48
40
 
49
41
  export class HookError {
@@ -56,8 +48,13 @@ export function generateDocs(apexBundles: UnparsedSourceFile[], config: Markdown
56
48
  const filterOutOfScope = apply(filterScope, config.scope);
57
49
  const convertToReferences = apply(parsedFilesToReferenceGuide, config);
58
50
  const convertToRenderableBundle = apply(parsedFilesToRenderableBundle, config);
59
- const convertToDocumentationBundleForTemplate = apply(convertToDocumentationBundle, config.referenceGuideTemplate);
60
- const sortTypeMembers = apply(sortMembers, config.sortMembersAlphabetically);
51
+ const convertToDocumentationBundleForTemplate = apply(
52
+ convertToDocumentationBundle,
53
+ config.referenceGuideTitle,
54
+ config.referenceGuideTemplate,
55
+ );
56
+ const sort = apply(sortTypesAndMembers, config.sortAlphabetically);
57
+ const removeExcluded = apply(removeExcludedTags, config.excludeTags);
61
58
 
62
59
  return pipe(
63
60
  apexBundles,
@@ -65,7 +62,8 @@ export function generateDocs(apexBundles: UnparsedSourceFile[], config: Markdown
65
62
  TE.map(filterOutOfScope),
66
63
  TE.map(addInheritedMembersToTypes),
67
64
  TE.map(addInheritanceChainToTypes),
68
- TE.map(sortTypeMembers),
65
+ TE.map(sort),
66
+ TE.map(removeExcluded),
69
67
  TE.bindTo('parsedFiles'),
70
68
  TE.bind('references', ({ parsedFiles }) => TE.right(convertToReferences(parsedFiles))),
71
69
  TE.flatMap(({ parsedFiles, references }) => transformReferenceHook(config)({ references, parsedFiles })),
@@ -1,22 +1,6 @@
1
- import { ParsedFile } from '../../../shared/types';
2
- import { ClassMirror, EnumMirror, InterfaceMirror, reflect } from '@cparra/apex-reflection';
1
+ import { ClassMirror, EnumMirror, InterfaceMirror } from '@cparra/apex-reflection';
3
2
  import { filterScope } from '../filter-scope';
4
-
5
- function parsedFileFromRawString(raw: string): ParsedFile {
6
- const { error, typeMirror } = reflect(raw);
7
- if (error) {
8
- throw new Error(error.message);
9
- }
10
-
11
- return {
12
- source: {
13
- filePath: 'test.cls',
14
- name: typeMirror!.name,
15
- type: typeMirror!.type_name,
16
- },
17
- type: typeMirror!,
18
- };
19
- }
3
+ import { parsedFileFromRawString } from './helpers';
20
4
 
21
5
  describe('When filtering scope', () => {
22
6
  it('filters out files with the @ignore annotation', () => {
@@ -0,0 +1,18 @@
1
+ import { ParsedFile } from '../../../shared/types';
2
+ import { reflect } from '@cparra/apex-reflection';
3
+
4
+ export function parsedFileFromRawString(raw: string): ParsedFile {
5
+ const { error, typeMirror } = reflect(raw);
6
+ if (error) {
7
+ throw new Error(error.message);
8
+ }
9
+
10
+ return {
11
+ source: {
12
+ filePath: 'test.cls',
13
+ name: typeMirror!.name,
14
+ type: typeMirror!.type_name,
15
+ },
16
+ type: typeMirror!,
17
+ };
18
+ }
@@ -0,0 +1,200 @@
1
+ import { parsedFileFromRawString } from './helpers';
2
+ import { removeExcludedTags } from '../remove-excluded-tags';
3
+ import { ClassMirror, InterfaceMirror } from '@cparra/apex-reflection';
4
+
5
+ describe('when removing excluded tags', () => {
6
+ describe('from any type', () => {
7
+ it('removes annotations', () => {
8
+ const tagsToExclude = ['group'];
9
+ const content = `
10
+ /**
11
+ * @group MyGroup
12
+ * @custom myCustomTag
13
+ */
14
+ global class MyClass {}
15
+ `;
16
+ const parsedFile = parsedFileFromRawString(content);
17
+
18
+ const result = removeExcludedTags(tagsToExclude, [parsedFile]);
19
+
20
+ expect(result[0].type.docComment?.annotations).toHaveLength(1);
21
+ expect(result[0].type.docComment?.annotations[0].name).toBe('custom');
22
+ });
23
+
24
+ it('removes example annotations', () => {
25
+ const tagsToExclude = ['example'];
26
+ const content = `
27
+ /**
28
+ * @example
29
+ * This is my example
30
+ * public void myMethod() {}
31
+ */
32
+ global class MyClass {}
33
+ `;
34
+ const parsedFile = parsedFileFromRawString(content);
35
+
36
+ const result = removeExcludedTags(tagsToExclude, [parsedFile]);
37
+
38
+ expect(result[0].type.docComment?.exampleAnnotation).toBeNull();
39
+ });
40
+
41
+ it('removes params annotations', () => {
42
+ const tagsToExclude = ['param'];
43
+ const content = `
44
+ /**
45
+ * @param myParam
46
+ * public void myMethod() {}
47
+ */
48
+ global class MyClass {}
49
+ `;
50
+ const parsedFile = parsedFileFromRawString(content);
51
+
52
+ const result = removeExcludedTags(tagsToExclude, [parsedFile]);
53
+
54
+ expect(result[0].type.docComment?.paramAnnotations).toHaveLength(0);
55
+ });
56
+
57
+ it('removes the return annotation', () => {
58
+ const tagsToExclude = ['return'];
59
+ const content = `
60
+ /**
61
+ * @return myReturn
62
+ * public void myMethod() {}
63
+ */
64
+ global class MyClass {}
65
+ `;
66
+ const parsedFile = parsedFileFromRawString(content);
67
+
68
+ const result = removeExcludedTags(tagsToExclude, [parsedFile]);
69
+
70
+ expect(result[0].type.docComment?.returnAnnotation).toBeNull();
71
+ });
72
+
73
+ it('removes the throws annotations', () => {
74
+ const tagsToExclude = ['throws'];
75
+ const content = `
76
+ /**
77
+ * @throws MyException
78
+ * public void myMethod() {}
79
+ */
80
+ global class MyClass {}
81
+ `;
82
+ const parsedFile = parsedFileFromRawString(content);
83
+
84
+ const result = removeExcludedTags(tagsToExclude, [parsedFile]);
85
+
86
+ expect(result[0].type.docComment?.throwsAnnotations).toHaveLength(0);
87
+ });
88
+
89
+ it('removes the exception annotations', () => {
90
+ const tagsToExclude = ['exception'];
91
+ const content = `
92
+ /**
93
+ * @exception MyException
94
+ * public void myMethod() {}
95
+ */
96
+ global class MyClass {}
97
+ `;
98
+ const parsedFile = parsedFileFromRawString(content);
99
+
100
+ const result = removeExcludedTags(tagsToExclude, [parsedFile]);
101
+
102
+ expect(result[0].type.docComment?.throwsAnnotations).toHaveLength(0);
103
+ });
104
+
105
+ it('removes descriptions', () => {
106
+ const tagsToExclude = ['description'];
107
+ const content = `
108
+ /**
109
+ * @description This is my description
110
+ * public void myMethod() {}
111
+ */
112
+ global class MyClass {}
113
+ `;
114
+ const parsedFile = parsedFileFromRawString(content);
115
+
116
+ const result = removeExcludedTags(tagsToExclude, [parsedFile]);
117
+
118
+ expect(result[0].type.docComment?.description).toBe('');
119
+ expect(result[0].type.docComment?.descriptionLines).toHaveLength(0);
120
+ });
121
+ });
122
+
123
+ describe('from an interface', () => {
124
+ it('removes annotations from methods', () => {
125
+ const tagsToExclude = ['throws'];
126
+ const content = `
127
+ global interface MyInterface {
128
+ /**
129
+ * @throws MyException
130
+ */
131
+ void myMethod();
132
+ }
133
+ `;
134
+ const parsedFile = parsedFileFromRawString(content);
135
+
136
+ const result = removeExcludedTags(tagsToExclude, [parsedFile]);
137
+
138
+ expect((result[0].type as InterfaceMirror).methods[0].docComment?.throwsAnnotations).toHaveLength(0);
139
+ });
140
+ });
141
+
142
+ describe('from a class', () => {
143
+ it('removes annotations from members', () => {
144
+ const tagsToExclude = ['throws'];
145
+ const content = `
146
+ global class MyClass {
147
+ /**
148
+ * @throws MyException
149
+ */
150
+ String myProperty {get; set;}
151
+
152
+ /**
153
+ * @throws MyException
154
+ */
155
+ String myField;
156
+ /**
157
+ * @throws MyException
158
+ */
159
+ void myMethod() {}
160
+
161
+ /**
162
+ * @throws MyException
163
+ */
164
+ MyClass() {}
165
+
166
+ /**
167
+ * @throws MyException
168
+ */
169
+ public enum MyEnum {}
170
+
171
+ /**
172
+ * @throws MyException
173
+ */
174
+ interface MyInnerInterface {}
175
+
176
+ /**
177
+ * @throws MyException
178
+ */
179
+ class MyInnerClass {}
180
+ }
181
+ `;
182
+ const parsedFile = parsedFileFromRawString(content);
183
+
184
+ const result = removeExcludedTags(tagsToExclude, [parsedFile]);
185
+
186
+ const classMirror = result[0].type as ClassMirror;
187
+ expect(classMirror.methods[0].docComment?.throwsAnnotations).toHaveLength(0);
188
+ expect(classMirror.properties[0].docComment?.throwsAnnotations).toHaveLength(0);
189
+ expect(classMirror.fields[0].docComment?.throwsAnnotations).toHaveLength(0);
190
+ expect(classMirror.constructors[0].docComment?.throwsAnnotations).toHaveLength(0);
191
+ expect(classMirror.enums[0].docComment?.throwsAnnotations).toHaveLength(0);
192
+ expect(classMirror.interfaces[0].docComment?.throwsAnnotations).toHaveLength(0);
193
+ expect(classMirror.classes[0].docComment?.throwsAnnotations).toHaveLength(0);
194
+ });
195
+ });
196
+ });
197
+
198
+ // fields
199
+ // inner interfaces
200
+ // inner classes
@@ -0,0 +1,168 @@
1
+ import * as O from 'fp-ts/Option';
2
+ import { match } from 'fp-ts/boolean';
3
+ import { ParsedFile } from '../../shared/types';
4
+ import { ClassMirror, DocComment, InterfaceMirror, Type } from '@cparra/apex-reflection';
5
+ import { pipe } from 'fp-ts/function';
6
+ import { apply } from '#utils/fp';
7
+
8
+ type AppliedRemoveTagFn = (tagName: string, removeFn: RemoveTagFn) => DocComment;
9
+ type RemoveTagFn = (docComment: DocComment) => DocComment;
10
+ type Documentable = { docComment?: DocComment };
11
+
12
+ export const removeExcludedTags = (excludedTags: string[], parsedFiles: ParsedFile[]): ParsedFile[] => {
13
+ return parsedFiles.map((parsedFile) => {
14
+ return {
15
+ ...parsedFile,
16
+ type: removeExcludedTagsFromType(excludedTags, parsedFile.type),
17
+ };
18
+ });
19
+ };
20
+
21
+ const removeExcludedTagsFromType = <T extends Type>(excludedTags: string[], type: T): T => {
22
+ return {
23
+ ...handleType(excludedTags, type),
24
+ docComment: removeExcludedTagsFromDocComment(excludedTags, type.docComment),
25
+ } as T;
26
+ };
27
+
28
+ const handleType = (excludedTags: string[], type: Type): Type => {
29
+ switch (type.type_name) {
30
+ case 'class':
31
+ return handleClass(excludedTags, type as ClassMirror);
32
+ case 'interface':
33
+ return handleInterface(excludedTags, type as InterfaceMirror);
34
+ case 'enum':
35
+ return type;
36
+ }
37
+ };
38
+
39
+ const handleClass = (excludedTags: string[], classMirror: ClassMirror): ClassMirror => {
40
+ return {
41
+ ...classMirror,
42
+ methods: classMirror.methods.map((method) => removeExcludedTagsFromDocumentable(excludedTags, method)),
43
+ properties: classMirror.properties.map((property) => removeExcludedTagsFromDocumentable(excludedTags, property)),
44
+ fields: classMirror.fields.map((field) => removeExcludedTagsFromDocumentable(excludedTags, field)),
45
+ constructors: classMirror.constructors.map((constructor) =>
46
+ removeExcludedTagsFromDocumentable(excludedTags, constructor),
47
+ ),
48
+ enums: classMirror.enums.map((enumType) => removeExcludedTagsFromType(excludedTags, enumType)),
49
+ interfaces: classMirror.interfaces.map((interfaceType) => removeExcludedTagsFromType(excludedTags, interfaceType)),
50
+ classes: classMirror.classes.map((innerClass) => removeExcludedTagsFromType(excludedTags, innerClass)),
51
+ };
52
+ };
53
+
54
+ const handleInterface = (excludedTags: string[], interfaceMirror: InterfaceMirror): InterfaceMirror => {
55
+ return {
56
+ ...interfaceMirror,
57
+ methods: interfaceMirror.methods.map((method) => removeExcludedTagsFromDocumentable(excludedTags, method)),
58
+ };
59
+ };
60
+
61
+ const removeExcludedTagsFromDocumentable = <T extends Documentable>(excludedTags: string[], documentable: T): T => {
62
+ return {
63
+ ...documentable,
64
+ docComment: removeExcludedTagsFromDocComment(excludedTags, documentable.docComment),
65
+ };
66
+ };
67
+
68
+ const removeExcludedTagsFromDocComment = (
69
+ excludedTags: string[],
70
+ docComment: DocComment | undefined,
71
+ ): DocComment | undefined => {
72
+ const removerFn = apply(remove, excludedTags);
73
+
74
+ return pipe(
75
+ O.fromNullable(docComment),
76
+ O.map((docComment) => removeExcludedTagsFromAnnotations(excludedTags, docComment)),
77
+ O.map((docComment) => removeExampleTag(apply(removerFn, docComment))),
78
+ O.map((docComment) => removeParamTags(apply(removerFn, docComment))),
79
+ O.map((docComment) => removeReturnTag(apply(removerFn, docComment))),
80
+ O.map((docComment) => removeThrowsTag(apply(removerFn, docComment))),
81
+ O.map((docComment) => removeExceptionTag(apply(removerFn, docComment))),
82
+ O.map((docComment) => removeDescription(apply(removerFn, docComment))),
83
+ O.fold(
84
+ () => undefined,
85
+ (updatedDocComment) => updatedDocComment,
86
+ ),
87
+ );
88
+ };
89
+
90
+ const removeExcludedTagsFromAnnotations = (excludedTags: string[], docComment: DocComment): DocComment => {
91
+ return pipe(
92
+ O.some(docComment.annotations),
93
+ O.map((annotations) => annotations.filter((annotation) => !includesIgnoreCase(excludedTags, annotation.name))),
94
+ O.fold(
95
+ () => docComment,
96
+ (filteredAnnotations) => ({
97
+ ...docComment,
98
+ annotations: filteredAnnotations,
99
+ }),
100
+ ),
101
+ );
102
+ };
103
+
104
+ const removeExampleTag = (remover: AppliedRemoveTagFn): DocComment => {
105
+ return remover('example', (docComment) => {
106
+ return {
107
+ ...docComment,
108
+ exampleAnnotation: null,
109
+ };
110
+ });
111
+ };
112
+
113
+ const removeParamTags = (remover: AppliedRemoveTagFn): DocComment => {
114
+ return remover('param', (docComment) => {
115
+ return {
116
+ ...docComment,
117
+ paramAnnotations: [],
118
+ };
119
+ });
120
+ };
121
+
122
+ const removeReturnTag = (remover: AppliedRemoveTagFn): DocComment => {
123
+ return remover('return', (docComment) => {
124
+ return {
125
+ ...docComment,
126
+ returnAnnotation: null,
127
+ };
128
+ });
129
+ };
130
+
131
+ const removeThrowsTag = (remover: AppliedRemoveTagFn): DocComment => {
132
+ return remover('throws', (docComment) => {
133
+ return {
134
+ ...docComment,
135
+ throwsAnnotations: [],
136
+ };
137
+ });
138
+ };
139
+
140
+ const removeExceptionTag = (remover: AppliedRemoveTagFn): DocComment => {
141
+ return remover('exception', (docComment) => {
142
+ return {
143
+ ...docComment,
144
+ throwsAnnotations: [],
145
+ };
146
+ });
147
+ };
148
+
149
+ const removeDescription = (remover: AppliedRemoveTagFn): DocComment => {
150
+ return remover('description', (docComment) => {
151
+ return {
152
+ ...docComment,
153
+ description: '',
154
+ descriptionLines: [],
155
+ };
156
+ });
157
+ };
158
+
159
+ const remove = (excludedTags: string[], docComment: DocComment, tagName: string, removeFn: RemoveTagFn): DocComment => {
160
+ return match(
161
+ () => docComment,
162
+ () => removeFn(docComment!),
163
+ )(includesIgnoreCase(excludedTags, tagName) && !!docComment);
164
+ };
165
+
166
+ const includesIgnoreCase = (excluded: string[], value: string): boolean => {
167
+ return excluded.some((element) => element.toLowerCase() === value.toLowerCase());
168
+ };
@@ -3,11 +3,13 @@ import { ParsedFile } from '../../shared/types';
3
3
 
4
4
  type Named = { name: string };
5
5
 
6
- export function sortMembers(shouldSortMembers: boolean, parsedFiles: ParsedFile[]): ParsedFile[] {
7
- return parsedFiles.map((parsedFile) => ({
8
- ...parsedFile,
9
- type: sortTypeMember(parsedFile.type, shouldSortMembers),
10
- }));
6
+ export function sortTypesAndMembers(shouldSort: boolean, parsedFiles: ParsedFile[]): ParsedFile[] {
7
+ return parsedFiles
8
+ .map((parsedFile) => ({
9
+ ...parsedFile,
10
+ type: sortTypeMember(parsedFile.type, shouldSort),
11
+ }))
12
+ .sort((a, b) => sortByNames(shouldSort, a.type, b.type));
11
13
  }
12
14
 
13
15
  function sortByNames<T extends Named>(shouldSort: boolean, a: T, b: T): number {
@@ -1,7 +1,7 @@
1
1
  export const referenceGuideTemplate = `
2
- # Apex Reference Guide
2
+ # {{referenceGuideTitle}}
3
3
 
4
- {{#each this}}
4
+ {{#each references}}
5
5
  ## {{@key}}
6
6
 
7
7
  {{#each this}}
@@ -4,6 +4,9 @@ import { SettingsBuilder } from '../../../test-helpers/SettingsBuilder';
4
4
  import { DocCommentBuilder } from '../../../test-helpers/DocCommentBuilder';
5
5
  import { AnnotationBuilder } from '../../../test-helpers/AnnotationBuilder';
6
6
  import { ClassMirrorBuilder } from '../../../test-helpers/ClassMirrorBuilder';
7
+ import { NoLogger } from '../../../util/logger';
8
+
9
+ const noLogger = new NoLogger();
7
10
 
8
11
  beforeEach(() => {
9
12
  OpenApiSettings.build(new SettingsBuilder().build());
@@ -18,7 +21,7 @@ it('should add a path based on the @UrlResource annotation on the class', functi
18
21
  .addAnnotation(new AnnotationBuilder().addElementValue(annotationElementValue).build())
19
22
  .build();
20
23
 
21
- const processor = new OpenApiDocsProcessor();
24
+ const processor = new OpenApiDocsProcessor(noLogger);
22
25
  processor.onProcess(classMirror);
23
26
 
24
27
  expect(processor.openApiModel.paths).toHaveProperty('Account/');
@@ -33,7 +36,7 @@ it('should respect slashes', function () {
33
36
  .addAnnotation(new AnnotationBuilder().addElementValue(annotationElementValue).build())
34
37
  .build();
35
38
 
36
- const processor = new OpenApiDocsProcessor();
39
+ const processor = new OpenApiDocsProcessor(noLogger);
37
40
  processor.onProcess(classMirror);
38
41
 
39
42
  expect(processor.openApiModel.paths).toHaveProperty('v1/Account/');
@@ -49,7 +52,7 @@ it('should contain a path with a description when the class has an ApexDoc comme
49
52
  .withDocComment(new DocCommentBuilder().withDescription('My Description').build())
50
53
  .build();
51
54
 
52
- const processor = new OpenApiDocsProcessor();
55
+ const processor = new OpenApiDocsProcessor(noLogger);
53
56
  processor.onProcess(classMirror);
54
57
 
55
58
  expect(processor.openApiModel.paths['Account/'].description).toBe('My Description');
@@ -11,7 +11,7 @@ export class OpenApiDocsProcessor {
11
11
  protected readonly _fileContainer: FileContainer;
12
12
  openApiModel: OpenApi;
13
13
 
14
- constructor() {
14
+ constructor(private logger: Logger) {
15
15
  this._fileContainer = new FileContainer();
16
16
  const title = OpenApiSettings.getInstance().getOpenApiTitle();
17
17
  if (!title) {
@@ -29,7 +29,7 @@ export class OpenApiDocsProcessor {
29
29
  }
30
30
 
31
31
  onProcess(type: Type): void {
32
- Logger.logSingle(`Processing ${type.name}`, 'green');
32
+ this.logger.logSingle(`Processing ${type.name}`, 'green');
33
33
 
34
34
  const endpointPath = this.getEndpointPath(type);
35
35
  if (!endpointPath) {
@@ -80,7 +80,7 @@ export class OpenApiDocsProcessor {
80
80
  (element) => element.key.toLowerCase() === 'urlmapping',
81
81
  );
82
82
  if (!urlMapping) {
83
- Logger.error(`Type does not contain urlMapping annotation ${type.name}`);
83
+ this.logger.error(`Type does not contain urlMapping annotation ${type.name}`);
84
84
  return null;
85
85
  }
86
86
 
@@ -9,12 +9,15 @@ export interface TypeParser {
9
9
  type NameAware = { name: string };
10
10
 
11
11
  export class RawBodyParser implements TypeParser {
12
- constructor(public typeBundles: UnparsedSourceFile[]) {}
12
+ constructor(
13
+ private logger: Logger,
14
+ public typeBundles: UnparsedSourceFile[],
15
+ ) {}
13
16
 
14
17
  parse(reflect: (apexBundle: UnparsedSourceFile) => ReflectionResult): Type[] {
15
18
  const types = this.typeBundles
16
19
  .map((currentBundle) => {
17
- Logger.log(`Parsing file: ${currentBundle.filePath}`);
20
+ this.logger.log(`Parsing file: ${currentBundle.filePath}`);
18
21
  return reflect(currentBundle);
19
22
  })
20
23
  .filter((reflectionResult) => {
@@ -16,11 +16,13 @@ export type UserDefinedMarkdownConfig = {
16
16
  targetGenerator: 'markdown';
17
17
  targetDir: string;
18
18
  scope: string[];
19
- defaultGroupName: string;
20
19
  namespace?: string;
21
- sortMembersAlphabetically: boolean;
20
+ defaultGroupName: string;
21
+ sortAlphabetically: boolean;
22
22
  includeMetadata: boolean;
23
23
  linkingStrategy: LinkingStrategy;
24
+ excludeTags: string[];
25
+ referenceGuideTitle: string;
24
26
  } & Partial<ConfigurableHooks>;
25
27
 
26
28
  export type UserDefinedOpenApiConfig = {
package/src/defaults.ts CHANGED
@@ -1,9 +1,21 @@
1
- export const defaults = {
2
- targetGenerator: 'markdown' as const,
1
+ const commonDefaults = {
3
2
  targetDir: './docs/',
3
+ };
4
+
5
+ export const markdownDefaults = {
6
+ ...commonDefaults,
4
7
  scope: ['global'],
5
8
  defaultGroupName: 'Miscellaneous',
6
9
  includeMetadata: false,
7
- sortMembersAlphabetically: false,
10
+ sortAlphabetically: false,
8
11
  linkingStrategy: 'relative' as const,
12
+ referenceGuideTitle: 'Apex Reference Guide',
13
+ excludeTags: [],
14
+ };
15
+
16
+ export const openApiDefaults = {
17
+ ...commonDefaults,
18
+ fileName: 'openapi',
19
+ title: 'Apex REST API',
20
+ apiVersion: '1.0.0',
9
21
  };