@cparra/apexdocs 3.0.0-alpha.1 → 3.0.0-alpha.10

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 (51) hide show
  1. package/dist/cli/generate.js +511 -293
  2. package/dist/{defaults-jLXD2y8-.js → defaults-DGKfeZq-.js} +1 -1
  3. package/dist/index.d.ts +23 -7
  4. package/dist/index.js +1 -1
  5. package/examples/markdown/docs/miscellaneous/MultiInheritanceClass.md +1 -1
  6. package/examples/markdown/docs/miscellaneous/SampleInterface.md +12 -8
  7. package/examples/markdown/docs/miscellaneous/Url.md +3 -3
  8. package/examples/markdown/force-app/classes/SampleInterface.cls +4 -0
  9. package/examples/vitepress/apexdocs.config.ts +1 -1
  10. package/examples/vitepress/docs/index.md +10 -10
  11. package/examples/vitepress/docs/miscellaneous/BaseClass.md +1 -1
  12. package/examples/vitepress/docs/miscellaneous/MultiInheritanceClass.md +2 -2
  13. package/examples/vitepress/docs/miscellaneous/SampleException.md +1 -1
  14. package/examples/vitepress/docs/miscellaneous/SampleInterface.md +6 -6
  15. package/examples/vitepress/docs/miscellaneous/Url.md +3 -3
  16. package/examples/vitepress/docs/sample-enums/SampleEnum.md +3 -3
  17. package/examples/vitepress/docs/samplegroup/SampleClass.md +4 -4
  18. package/package.json +2 -3
  19. package/src/application/Apexdocs.ts +53 -10
  20. package/src/application/__tests__/apex-file-reader.spec.ts +25 -25
  21. package/src/application/apex-file-reader.ts +32 -19
  22. package/src/application/file-system.ts +46 -10
  23. package/src/application/file-writer.ts +37 -15
  24. package/src/application/generators/markdown.ts +18 -31
  25. package/src/application/generators/openapi.ts +12 -8
  26. package/src/cli/commands/markdown.ts +4 -3
  27. package/src/core/markdown/__test__/generating-class-docs.spec.ts +3 -5
  28. package/src/core/markdown/__test__/generating-enum-docs.spec.ts +3 -3
  29. package/src/core/markdown/__test__/generating-interface-docs.spec.ts +5 -5
  30. package/src/core/markdown/__test__/generating-reference-guide.spec.ts +3 -3
  31. package/src/core/markdown/__test__/test-helpers.ts +1 -1
  32. package/src/core/markdown/adapters/__tests__/interface-adapter.spec.ts +1 -1
  33. package/src/core/markdown/adapters/__tests__/link-generator.spec.ts +130 -0
  34. package/src/core/markdown/adapters/documentables.ts +0 -1
  35. package/src/core/markdown/adapters/generate-link.ts +82 -0
  36. package/src/core/markdown/adapters/reference-guide.ts +3 -1
  37. package/src/core/markdown/adapters/renderable-bundle.ts +5 -22
  38. package/src/core/markdown/adapters/renderable-to-page-data.ts +2 -2
  39. package/src/core/markdown/generate-docs.ts +9 -13
  40. package/src/core/markdown/reflection/reflect-source.ts +109 -31
  41. package/src/core/openapi/open-api-docs-processor.ts +1 -1
  42. package/src/core/openapi/openapi-type-file.ts +1 -1
  43. package/src/core/openapi/parser.ts +1 -15
  44. package/src/core/parse-apex-metadata.ts +21 -5
  45. package/src/core/shared/types.d.ts +22 -6
  46. package/src/defaults.ts +1 -1
  47. package/src/index.ts +1 -6
  48. package/src/util/logger.ts +8 -21
  49. package/dist/defaults-DUwru49Q.js +0 -12
  50. package/dist/defaults-SH0Rsi5E.js +0 -11
  51. package/src/core/markdown/reflection/error-handling.ts +0 -37
@@ -7,7 +7,7 @@ const defaults = {
7
7
  defaultGroupName: "Miscellaneous",
8
8
  includeMetadata: false,
9
9
  sortMembersAlphabetically: false,
10
- documentationRootDir: ""
10
+ linkingStrategy: "relative"
11
11
  };
12
12
 
13
13
  exports.defaults = defaults;
package/dist/index.d.ts CHANGED
@@ -10,6 +10,17 @@ type ConfigurableHooks = {
10
10
  transformReference: TransformReference;
11
11
  };
12
12
 
13
+ type LinkingStrategy =
14
+ // Links will be generated using relative paths.
15
+ | 'relative'
16
+ // No links will be generated.
17
+ // If the reference is found, the display name will be used.
18
+ // Otherwise, the name
19
+ // of the reference itself will be used.
20
+ | 'no-link'
21
+ // No logic will be applied, the reference path will be used as is.
22
+ | 'none';
23
+
13
24
  type UserDefinedMarkdownConfig = {
14
25
  targetGenerator: 'markdown';
15
26
  sourceDir: string;
@@ -19,7 +30,7 @@ type UserDefinedMarkdownConfig = {
19
30
  namespace?: string;
20
31
  sortMembersAlphabetically: boolean;
21
32
  includeMetadata: boolean;
22
- documentationRootDir: string;
33
+ linkingStrategy: LinkingStrategy;
23
34
  } & Partial<ConfigurableHooks>;
24
35
 
25
36
  type SourceFileMetadata = {
@@ -33,8 +44,13 @@ type DocPageReference = {
33
44
  // The name under which the type should be displayed in the documentation.
34
45
  // By default, this will match the source.name, but it can be configured by the user.
35
46
  displayName: string;
36
- // The location of the file relative to the root of the documentation.
37
- pathFromRoot: string;
47
+ // The location where the file will be written.
48
+ outputDocPath: string;
49
+ // The path to the file relative to the documentation root directory. This is used when linking to the file.
50
+ // Usually the value will be the same as outputDocPath. However, some site generators may have a different way of
51
+ // organizing the files, so this allows for the flexibility of having a path from linking that is different from
52
+ // the path where the file is written.
53
+ referencePath: string;
38
54
  };
39
55
 
40
56
  type Frontmatter = string | Record<string, unknown> | null;
@@ -42,13 +58,13 @@ type Frontmatter = string | Record<string, unknown> | null;
42
58
  type ReferenceGuidePageData = {
43
59
  frontmatter: Frontmatter;
44
60
  content: string;
45
- filePath: string;
61
+ outputDocPath: string;
46
62
  };
47
63
 
48
64
  type DocPageData = {
49
65
  source: SourceFileMetadata;
50
66
  group: string | null;
51
- filePath: string;
67
+ outputDocPath: string;
52
68
  frontmatter: Frontmatter;
53
69
  content: string;
54
70
  };
@@ -64,7 +80,7 @@ type Skip = {
64
80
 
65
81
  type ConfigurableDocPageReference = Omit<DocPageReference, 'source'>;
66
82
 
67
- type ConfigurableDocPageData = Omit<DocPageData, 'source' | 'filePath'>;
83
+ type ConfigurableDocPageData = Omit<DocPageData, 'source' | 'outputDocPath'>;
68
84
 
69
85
  /**
70
86
  * Allows changing where the files are written to.
@@ -94,7 +110,7 @@ type TransformDocPage = (
94
110
  doc: DocPageData,
95
111
  ) => Partial<ConfigurableDocPageData> | Promise<Partial<ConfigurableDocPageData>>;
96
112
 
97
- type ConfigurableMarkdownConfig = Omit<SetOptional<UserDefinedMarkdownConfig, 'targetDir' | 'scope' | 'defaultGroupName' | 'includeMetadata' | 'sortMembersAlphabetically' | 'documentationRootDir'>, 'targetGenerator'>;
113
+ type ConfigurableMarkdownConfig = Omit<SetOptional<UserDefinedMarkdownConfig, 'targetDir' | 'scope' | 'defaultGroupName' | 'includeMetadata' | 'sortMembersAlphabetically' | 'linkingStrategy'>, 'targetGenerator'>;
98
114
  declare function defineMarkdownConfig(config: ConfigurableMarkdownConfig): UserDefinedMarkdownConfig;
99
115
  declare function skip(): Skip;
100
116
 
package/dist/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- var defaults = require('./defaults-jLXD2y8-.js');
3
+ var defaults = require('./defaults-DGKfeZq-.js');
4
4
 
5
5
  var __defProp = Object.defineProperty;
6
6
  var __defProps = Object.defineProperties;
@@ -5,7 +5,7 @@ ns
5
5
 
6
6
  **Inheritance**
7
7
 
8
- [SampleClass](../samplegroup/SampleClass.md) < [BaseClass](../miscellaneous/BaseClass.md)
8
+ [SampleClass](../samplegroup/SampleClass.md) < [BaseClass](BaseClass.md)
9
9
 
10
10
  ## Fields
11
11
  ### `sampleEnumFromBase`
@@ -6,10 +6,12 @@ This is a sample interface
6
6
 
7
7
  **Mermaid**
8
8
 
9
- graph TD
10
- A[SampleInterface] --&gt;|extends| B[ParentInterface]
11
- B --&gt;|extends| C[GrandParentInterface]
12
- C --&gt;|extends| D[GreatGrandParentInterface]
9
+ ```mermaid
10
+ graph TD
11
+ A[SampleInterface] -->|extends| B[ParentInterface]
12
+ B -->|extends| C[GrandParentInterface]
13
+ C -->|extends| D[GreatGrandParentInterface]
14
+ ```
13
15
 
14
16
  **Author** John Doe
15
17
 
@@ -17,17 +19,19 @@ C --&gt;|extends| D[GreatGrandParentInterface]
17
19
 
18
20
  **See** [SampleEnum](../sample-enums/SampleEnum.md)
19
21
 
20
- **See** [ReferencedEnum](../miscellaneous/ReferencedEnum.md)
22
+ **See** [ReferencedEnum](ReferencedEnum.md)
21
23
 
22
24
  ## Namespace
23
25
  ns
24
26
 
25
27
  ## Example
26
- SampleInterface sampleInterface &#x3D; new SampleInterface();
28
+ ```apex
29
+ SampleInterface sampleInterface = new SampleInterface();
27
30
  sampleInterface.sampleMethod();
31
+ ```
28
32
 
29
33
  **Extends**
30
- [ParentInterface](../miscellaneous/ParentInterface.md)
34
+ [ParentInterface](ParentInterface.md)
31
35
 
32
36
  ## Methods
33
37
  ### `sampleMethod()`
@@ -62,7 +66,7 @@ public String sampleMethod()
62
66
  Some return value
63
67
 
64
68
  #### Throws
65
- [SampleException](../miscellaneous/SampleException.md): This is a sample exception
69
+ [SampleException](SampleException.md): This is a sample exception
66
70
 
67
71
  AnotherSampleException: This is another sample exception
68
72
 
@@ -115,7 +115,7 @@ global Url(Url context, String spec)
115
115
  #### Parameters
116
116
  | Name | Type | Description |
117
117
  |------|------|-------------|
118
- | context | [Url](../miscellaneous/Url.md) | The context in which to parse the specification. |
118
+ | context | [Url](Url.md) | The context in which to parse the specification. |
119
119
  | spec | String | The string to parse as a URL. |
120
120
 
121
121
  ---
@@ -186,7 +186,7 @@ global static Url getCurrentRequestUrl()
186
186
  ```
187
187
 
188
188
  #### Return Type
189
- **[Url](../miscellaneous/Url.md)**
189
+ **[Url](Url.md)**
190
190
 
191
191
  The URL of the entire request.
192
192
 
@@ -294,7 +294,7 @@ global static Url getOrgDomainUrl()
294
294
  ```
295
295
 
296
296
  #### Return Type
297
- **[Url](../miscellaneous/Url.md)**
297
+ **[Url](Url.md)**
298
298
 
299
299
  getOrgDomainUrl() always returns the login URL for your org, regardless of context. Use that URL when making API calls to your org.
300
300
 
@@ -5,13 +5,17 @@
5
5
  * @see SampleEnum
6
6
  * @see ReferencedEnum
7
7
  * @mermaid
8
+ * ```mermaid
8
9
  * graph TD
9
10
  * A[SampleInterface] -->|extends| B[ParentInterface]
10
11
  * B -->|extends| C[GrandParentInterface]
11
12
  * C -->|extends| D[GreatGrandParentInterface]
13
+ * ```
12
14
  * @example
15
+ * ```apex
13
16
  * SampleInterface sampleInterface = new SampleInterface();
14
17
  * sampleInterface.sampleMethod();
18
+ * ```
15
19
  */
16
20
  @NamespaceAccessible
17
21
  public interface SampleInterface extends ParentInterface {
@@ -86,7 +86,7 @@ export default defineMarkdownConfig({
86
86
  function toSidebarLink(doc: DocPageData) {
87
87
  return {
88
88
  text: doc.source.name,
89
- link: doc.filePath,
89
+ link: doc.outputDocPath,
90
90
  };
91
91
  }
92
92
 
@@ -19,38 +19,38 @@ hero:
19
19
 
20
20
  ## Miscellaneous
21
21
 
22
- ### [BaseClass](/miscellaneous/BaseClass.md)
22
+ ### [BaseClass](miscellaneous/BaseClass.md)
23
23
 
24
- ### [MultiInheritanceClass](/miscellaneous/MultiInheritanceClass.md)
24
+ ### [MultiInheritanceClass](miscellaneous/MultiInheritanceClass.md)
25
25
 
26
- ### [ParentInterface](/miscellaneous/ParentInterface.md)
26
+ ### [ParentInterface](miscellaneous/ParentInterface.md)
27
27
 
28
- ### [ReferencedEnum](/miscellaneous/ReferencedEnum.md)
28
+ ### [ReferencedEnum](miscellaneous/ReferencedEnum.md)
29
29
 
30
- ### [SampleException](/miscellaneous/SampleException.md)
30
+ ### [SampleException](miscellaneous/SampleException.md)
31
31
 
32
32
  This is a sample exception.
33
33
 
34
- ### [SampleInterface](/miscellaneous/SampleInterface.md)
34
+ ### [SampleInterface](miscellaneous/SampleInterface.md)
35
35
 
36
36
  This is a sample interface
37
37
 
38
- ### [Url](/miscellaneous/Url.md)
38
+ ### [Url](miscellaneous/Url.md)
39
39
 
40
40
  Represents a uniform resource locator (URL) and provides access to parts of the URL.
41
41
  Enables access to the base URL used to access your Salesforce org.
42
42
 
43
43
  ## Sample Enums
44
44
 
45
- ### [SampleEnum](/sample-enums/SampleEnum.md)
45
+ ### [SampleEnum](sample-enums/SampleEnum.md)
46
46
 
47
- This is a sample enum. This references [ReferencedEnum](/miscellaneous/ReferencedEnum.md) .
47
+ This is a sample enum. This references [ReferencedEnum](miscellaneous/ReferencedEnum.md) .
48
48
 
49
49
  This description has several lines
50
50
 
51
51
  ## SampleGroup
52
52
 
53
- ### [SampleClass](/samplegroup/SampleClass.md)
53
+ ### [SampleClass](samplegroup/SampleClass.md)
54
54
 
55
55
  aliquip ex sunt officia ullamco anim deserunt magna aliquip nisi eiusmod in sit officia veniam ex
56
56
  deserunt ea officia exercitation laboris enim in duis quis enim eiusmod eu amet cupidatat.
@@ -17,4 +17,4 @@ public sampleEnumFromBase
17
17
  ```
18
18
 
19
19
  #### Type
20
- [SampleEnum](/sample-enums/SampleEnum.md)
20
+ [SampleEnum](../sample-enums/SampleEnum.md)
@@ -9,7 +9,7 @@ apexdocs
9
9
 
10
10
  **Inheritance**
11
11
 
12
- [SampleClass](/samplegroup/SampleClass.md) < [BaseClass](/miscellaneous/BaseClass.md)
12
+ [SampleClass](../samplegroup/SampleClass.md) < [BaseClass](BaseClass.md)
13
13
 
14
14
  ## Fields
15
15
  ### `sampleEnumFromBase`
@@ -22,7 +22,7 @@ public sampleEnumFromBase
22
22
  ```
23
23
 
24
24
  #### Type
25
- [SampleEnum](/sample-enums/SampleEnum.md)
25
+ [SampleEnum](../sample-enums/SampleEnum.md)
26
26
 
27
27
  ## Properties
28
28
  ### Group Name
@@ -9,7 +9,7 @@ This is a sample exception.
9
9
  **Usage**
10
10
 
11
11
  You can use the exception the following way.
12
- You can also take a look at [SampleClass](/samplegroup/SampleClass.md) to see how it is used.
12
+ You can also take a look at [SampleClass](../samplegroup/SampleClass.md) to see how it is used.
13
13
  This is a dangerous HTML tag: &lt;script&gt;alert(&#x27;Hello&#x27;);&lt;/script&gt;
14
14
 
15
15
  ```apex
@@ -19,9 +19,9 @@ C --&gt;|extends| D[GreatGrandParentInterface]
19
19
 
20
20
  **Date** 2020-01-01
21
21
 
22
- **See** [SampleEnum](/sample-enums/SampleEnum.md)
22
+ **See** [SampleEnum](../sample-enums/SampleEnum.md)
23
23
 
24
- **See** [ReferencedEnum](/miscellaneous/ReferencedEnum.md)
24
+ **See** [ReferencedEnum](ReferencedEnum.md)
25
25
 
26
26
  ## Namespace
27
27
  apexdocs
@@ -31,7 +31,7 @@ SampleInterface sampleInterface &#x3D; new SampleInterface();
31
31
  sampleInterface.sampleMethod();
32
32
 
33
33
  **Extends**
34
- [ParentInterface](/miscellaneous/ParentInterface.md)
34
+ [ParentInterface](ParentInterface.md)
35
35
 
36
36
  ## Methods
37
37
  ### `sampleMethod()`
@@ -66,7 +66,7 @@ public String sampleMethod()
66
66
  Some return value
67
67
 
68
68
  #### Throws
69
- [SampleException](/miscellaneous/SampleException.md): This is a sample exception
69
+ [SampleException](SampleException.md): This is a sample exception
70
70
 
71
71
  AnotherSampleException: This is another sample exception
72
72
 
@@ -94,10 +94,10 @@ public SampleEnum sampleMethodWithParams(String param1, Integer param2, SampleEn
94
94
  |------|------|-------------|
95
95
  | param1 | String | This is the first parameter |
96
96
  | param2 | Integer | This is the second parameter |
97
- | theEnum | [SampleEnum](/sample-enums/SampleEnum.md) | This is an enum parameter |
97
+ | theEnum | [SampleEnum](../sample-enums/SampleEnum.md) | This is an enum parameter |
98
98
 
99
99
  #### Return Type
100
- **[SampleEnum](/sample-enums/SampleEnum.md)**
100
+ **[SampleEnum](../sample-enums/SampleEnum.md)**
101
101
 
102
102
  Some return value
103
103
 
@@ -120,7 +120,7 @@ global Url(Url context, String spec)
120
120
  #### Parameters
121
121
  | Name | Type | Description |
122
122
  |------|------|-------------|
123
- | context | [Url](/miscellaneous/Url.md) | The context in which to parse the specification. |
123
+ | context | [Url](Url.md) | The context in which to parse the specification. |
124
124
  | spec | String | The string to parse as a URL. |
125
125
 
126
126
  ---
@@ -191,7 +191,7 @@ global static Url getCurrentRequestUrl()
191
191
  ```
192
192
 
193
193
  #### Return Type
194
- **[Url](/miscellaneous/Url.md)**
194
+ **[Url](Url.md)**
195
195
 
196
196
  The URL of the entire request.
197
197
 
@@ -299,7 +299,7 @@ global static Url getOrgDomainUrl()
299
299
  ```
300
300
 
301
301
  #### Return Type
302
- **[Url](/miscellaneous/Url.md)**
302
+ **[Url](Url.md)**
303
303
 
304
304
  getOrgDomainUrl() always returns the login URL for your org, regardless of context. Use that URL when making API calls to your org.
305
305
 
@@ -6,13 +6,13 @@ title: SampleEnum
6
6
 
7
7
  `NAMESPACEACCESSIBLE`
8
8
 
9
- This is a sample enum. This references [ReferencedEnum](/miscellaneous/ReferencedEnum.md) .
9
+ This is a sample enum. This references [ReferencedEnum](../miscellaneous/ReferencedEnum.md) .
10
10
 
11
11
  This description has several lines
12
12
 
13
13
  **Some Custom**
14
14
 
15
- Test. I can also have a [ReferencedEnum](/miscellaneous/ReferencedEnum.md) here.
15
+ Test. I can also have a [ReferencedEnum](../miscellaneous/ReferencedEnum.md) here.
16
16
  And it can be multiline.
17
17
 
18
18
  **Mermaid**
@@ -27,7 +27,7 @@ B --&gt;|referenced by| A
27
27
 
28
28
  **Date** 2022-01-01
29
29
 
30
- **See** [ReferencedEnum](/miscellaneous/ReferencedEnum.md)
30
+ **See** [ReferencedEnum](../miscellaneous/ReferencedEnum.md)
31
31
 
32
32
  ## Namespace
33
33
  apexdocs
@@ -19,12 +19,12 @@ sample.doSomething();
19
19
 
20
20
  **Inheritance**
21
21
 
22
- [BaseClass](/miscellaneous/BaseClass.md)
22
+ [BaseClass](../miscellaneous/BaseClass.md)
23
23
 
24
24
  **Implements**
25
25
 
26
- [SampleInterface](/miscellaneous/SampleInterface.md),
27
- [ParentInterface](/miscellaneous/ParentInterface.md)
26
+ [SampleInterface](../miscellaneous/SampleInterface.md),
27
+ [ParentInterface](../miscellaneous/ParentInterface.md)
28
28
 
29
29
  ## Fields
30
30
  ### Group Name
@@ -51,7 +51,7 @@ public sampleEnumFromBase
51
51
  ```
52
52
 
53
53
  ##### Type
54
- [SampleEnum](/sample-enums/SampleEnum.md)
54
+ [SampleEnum](../sample-enums/SampleEnum.md)
55
55
 
56
56
  ## Properties
57
57
  ### Group Name
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cparra/apexdocs",
3
- "version": "3.0.0-alpha.1",
3
+ "version": "3.0.0-alpha.10",
4
4
  "description": "Library with CLI capabilities to generate documentation for Salesforce Apex classes.",
5
5
  "keywords": [
6
6
  "apex",
@@ -58,7 +58,7 @@
58
58
  ]
59
59
  },
60
60
  "dependencies": {
61
- "@cparra/apex-reflection": "2.11.3",
61
+ "@cparra/apex-reflection": "2.12.1",
62
62
  "@types/js-yaml": "^4.0.9",
63
63
  "@types/yargs": "^17.0.32",
64
64
  "chalk": "^4.1.2",
@@ -68,7 +68,6 @@
68
68
  "fp-ts": "^2.16.8",
69
69
  "handlebars": "^4.7.8",
70
70
  "js-yaml": "^4.1.0",
71
- "log-update": "4.0.0",
72
71
  "type-fest": "^4.23.0",
73
72
  "yargs": "^17.7.2"
74
73
  },
@@ -4,7 +4,10 @@ import openApi from './generators/openapi';
4
4
  import { ApexFileReader } from './apex-file-reader';
5
5
  import { DefaultFileSystem } from './file-system';
6
6
  import { Logger } from '#utils/logger';
7
- import { UserDefinedConfig } from '../core/shared/types';
7
+ import { UnparsedSourceFile, UserDefinedConfig, UserDefinedMarkdownConfig } from '../core/shared/types';
8
+ import { pipe } from 'fp-ts/function';
9
+ import * as TE from 'fp-ts/TaskEither';
10
+ import { ReflectionError } from '../core/markdown/reflection/reflect-source';
8
11
 
9
12
  /**
10
13
  * Application entry-point to generate documentation out of Apex source files.
@@ -14,17 +17,57 @@ export class Apexdocs {
14
17
  * Generates documentation out of Apex source files.
15
18
  */
16
19
  static async generate(config: UserDefinedConfig): Promise<void> {
17
- Logger.logSingle('Initializing...', false);
20
+ Logger.logSingle(`Generating ${config.targetGenerator} documentation...`);
18
21
 
19
- const fileBodies = ApexFileReader.processFiles(new DefaultFileSystem(), config.sourceDir, config.includeMetadata);
22
+ try {
23
+ const fileBodies = await ApexFileReader.processFiles(
24
+ new DefaultFileSystem(),
25
+ config.sourceDir,
26
+ config.includeMetadata,
27
+ );
20
28
 
21
- switch (config.targetGenerator) {
22
- case 'markdown':
23
- await markdown(fileBodies, config);
24
- break;
25
- case 'openapi':
26
- openApi(fileBodies, config);
27
- break;
29
+ switch (config.targetGenerator) {
30
+ case 'markdown':
31
+ await generateMarkdownDocumentation(fileBodies, config)();
32
+ break;
33
+ case 'openapi':
34
+ openApi(fileBodies, config);
35
+ Logger.logSingle('✔️ Documentation generated successfully!');
36
+ break;
37
+ }
38
+ } catch (error) {
39
+ Logger.logSingle(`❌ An error occurred while generating the documentation: ${error}`, 'red');
28
40
  }
29
41
  }
30
42
  }
43
+
44
+ function generateMarkdownDocumentation(fileBodies: UnparsedSourceFile[], config: UserDefinedMarkdownConfig) {
45
+ return pipe(
46
+ markdown(fileBodies, config),
47
+ TE.map(() => Logger.logSingle('✔️ Documentation generated successfully!')),
48
+ TE.mapLeft((error) => {
49
+ if (error._tag === 'HookError') {
50
+ Logger.error('Error(s) occurred while processing hooks. Please review the following issues:');
51
+ Logger.error(error.error);
52
+ return;
53
+ }
54
+
55
+ if (error._tag === 'FileWritingError') {
56
+ Logger.error(error.message);
57
+ Logger.error(error.error);
58
+ return;
59
+ }
60
+
61
+ const errorMessages = [
62
+ 'Error(s) occurred while parsing files. Please review the following issues:',
63
+ ...error.errors.map(formatReflectionError),
64
+ ].join('\n');
65
+
66
+ Logger.error(errorMessages);
67
+ }),
68
+ );
69
+ }
70
+
71
+ function formatReflectionError(error: ReflectionError) {
72
+ return `Source file: ${error.file}\n${error.message}\n`;
73
+ }
@@ -18,24 +18,24 @@ describe('File Reader', () => {
18
18
  } as SettingsConfig);
19
19
  });
20
20
 
21
- it('returns an empty list when there are no files in the directory', () => {
22
- const result = ApexFileReader.processFiles(
21
+ it('returns an empty list when there are no files in the directory', async () => {
22
+ const result = await ApexFileReader.processFiles(
23
23
  {
24
24
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
25
- isDirectory(_: string): boolean {
26
- return false;
25
+ isDirectory(_: string): Promise<boolean> {
26
+ return Promise.resolve(false);
27
27
  },
28
28
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
29
29
  joinPath(_: string): string {
30
30
  return '';
31
31
  },
32
32
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
33
- readDirectory(_: string): string[] {
34
- return [];
33
+ readDirectory(_: string): Promise<string[]> {
34
+ return Promise.resolve([]);
35
35
  },
36
36
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
37
- readFile(_: string): string {
38
- return '';
37
+ readFile(_: string): Promise<string> {
38
+ return Promise.resolve('');
39
39
  },
40
40
  exists(): boolean {
41
41
  return true;
@@ -47,20 +47,20 @@ describe('File Reader', () => {
47
47
  expect(result.length).toBe(0);
48
48
  });
49
49
 
50
- it('returns an empty list when there are no Apex files in the directory', () => {
51
- const result = ApexFileReader.processFiles(
50
+ it('returns an empty list when there are no Apex files in the directory', async () => {
51
+ const result = await ApexFileReader.processFiles(
52
52
  {
53
- isDirectory(): boolean {
54
- return false;
53
+ isDirectory(): Promise<boolean> {
54
+ return Promise.resolve(false);
55
55
  },
56
56
  joinPath(): string {
57
57
  return '';
58
58
  },
59
- readDirectory(): string[] {
60
- return ['SomeFile.md'];
59
+ readDirectory(): Promise<string[]> {
60
+ return Promise.resolve(['SomeFile.md']);
61
61
  },
62
- readFile(): string {
63
- return '';
62
+ readFile(): Promise<string> {
63
+ return Promise.resolve('');
64
64
  },
65
65
  exists(): boolean {
66
66
  return true;
@@ -72,24 +72,24 @@ describe('File Reader', () => {
72
72
  expect(result.length).toBe(0);
73
73
  });
74
74
 
75
- it('returns the file contents for an Apex file', () => {
76
- const result = ApexFileReader.processFiles(
75
+ it('returns the file contents for an Apex file', async () => {
76
+ const result = await ApexFileReader.processFiles(
77
77
  {
78
78
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
79
- isDirectory(_: string): boolean {
80
- return false;
79
+ isDirectory(_: string): Promise<boolean> {
80
+ return Promise.resolve(false);
81
81
  },
82
82
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
83
83
  joinPath(_: string): string {
84
- return '';
84
+ return 'SomeApexFile.cls';
85
85
  },
86
86
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
87
- readDirectory(_: string): string[] {
88
- return ['SomeApexFile.cls'];
87
+ readDirectory(_: string): Promise<string[]> {
88
+ return Promise.resolve(['SomeApexFile.cls']);
89
89
  },
90
90
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
91
- readFile(_: string): string {
92
- return 'public class MyClass{}';
91
+ readFile(_: string): Promise<string> {
92
+ return Promise.resolve('public class MyClass{}');
93
93
  },
94
94
  exists(): boolean {
95
95
  return true;