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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (189) hide show
  1. package/dist/cli/generate.js +2745 -39
  2. package/dist/defaults-DUwru49Q.js +12 -0
  3. package/dist/defaults-SH0Rsi5E.js +11 -0
  4. package/dist/index.d.ts +62 -2
  5. package/dist/index.js +36 -1
  6. package/examples/plain-markdown/docs/Miscellaneous/ns.BaseClass.md +1 -1
  7. package/examples/plain-markdown/docs/Miscellaneous/ns.MultiInheritanceClass.md +1 -1
  8. package/examples/plain-markdown/docs/Miscellaneous/ns.ParentInterface.md +1 -1
  9. package/examples/plain-markdown/docs/Miscellaneous/ns.ReferencedEnum.md +1 -1
  10. package/examples/plain-markdown/docs/Miscellaneous/ns.SampleException.md +1 -1
  11. package/examples/plain-markdown/docs/Miscellaneous/ns.SampleInterface.md +1 -1
  12. package/examples/plain-markdown/docs/Miscellaneous/ns.Url.md +1 -1
  13. package/examples/plain-markdown/docs/Sample-Enums/ns.SampleEnum.md +1 -1
  14. package/examples/plain-markdown/docs/SampleGroup/ns.SampleClass.md +1 -1
  15. package/examples/plain-markdown/docs/index.md +1 -1
  16. package/examples/plain-markdown/package.json +3 -4
  17. package/examples/vitepress/.forceignore +12 -0
  18. package/examples/vitepress/apexdocs.config.ts +108 -0
  19. package/examples/vitepress/config/project-scratch-def.json +13 -0
  20. package/examples/vitepress/docs/.vitepress/cache/deps/@theme_index.js +259 -0
  21. package/examples/vitepress/docs/.vitepress/cache/deps/@theme_index.js.map +7 -0
  22. package/examples/vitepress/docs/.vitepress/cache/deps/_metadata.json +40 -0
  23. package/examples/vitepress/docs/.vitepress/cache/deps/chunk-574YRH25.js +11474 -0
  24. package/examples/vitepress/docs/.vitepress/cache/deps/chunk-574YRH25.js.map +7 -0
  25. package/examples/vitepress/docs/.vitepress/cache/deps/chunk-E5DZZB2I.js +9172 -0
  26. package/examples/vitepress/docs/.vitepress/cache/deps/chunk-E5DZZB2I.js.map +7 -0
  27. package/examples/vitepress/docs/.vitepress/cache/deps/package.json +3 -0
  28. package/examples/vitepress/docs/.vitepress/cache/deps/vitepress___@vue_devtools-api.js +4339 -0
  29. package/examples/vitepress/docs/.vitepress/cache/deps/vitepress___@vue_devtools-api.js.map +7 -0
  30. package/examples/vitepress/docs/.vitepress/cache/deps/vitepress___@vueuse_core.js +567 -0
  31. package/examples/vitepress/docs/.vitepress/cache/deps/vitepress___@vueuse_core.js.map +7 -0
  32. package/examples/vitepress/docs/.vitepress/cache/deps/vue.js +323 -0
  33. package/examples/vitepress/docs/.vitepress/cache/deps/vue.js.map +7 -0
  34. package/examples/vitepress/docs/.vitepress/config.mts +21 -0
  35. package/examples/vitepress/docs/.vitepress/sidebar.json +119 -0
  36. package/examples/vitepress/docs/Miscellaneous/apexdocs.BaseClass.md +20 -0
  37. package/examples/vitepress/docs/Miscellaneous/apexdocs.MultiInheritanceClass.md +78 -0
  38. package/examples/vitepress/docs/Miscellaneous/apexdocs.ParentInterface.md +19 -0
  39. package/examples/vitepress/docs/Miscellaneous/apexdocs.ReferencedEnum.md +15 -0
  40. package/examples/vitepress/docs/Miscellaneous/apexdocs.SampleException.md +28 -0
  41. package/examples/vitepress/docs/Miscellaneous/apexdocs.SampleInterface.md +122 -0
  42. package/examples/vitepress/docs/Miscellaneous/apexdocs.Url.md +318 -0
  43. package/examples/vitepress/docs/Sample-Enums/apexdocs.SampleEnum.md +41 -0
  44. package/examples/vitepress/docs/SampleGroup/apexdocs.SampleClass.md +178 -0
  45. package/examples/vitepress/docs/api-examples.md +49 -0
  46. package/examples/vitepress/docs/index-frontmatter.md +16 -0
  47. package/examples/vitepress/docs/index.md +127 -0
  48. package/examples/vitepress/docs/markdown-examples.md +85 -0
  49. package/examples/vitepress/force-app/main/default/classes/BaseClass.cls +3 -0
  50. package/examples/vitepress/force-app/main/default/classes/MultiInheritanceClass.cls +1 -0
  51. package/examples/vitepress/force-app/main/default/classes/ParentInterface.cls +3 -0
  52. package/examples/vitepress/force-app/main/default/classes/ReferencedEnum.cls +5 -0
  53. package/examples/vitepress/force-app/main/default/classes/SampleClass.cls +72 -0
  54. package/examples/vitepress/force-app/main/default/classes/SampleEnum.cls +30 -0
  55. package/examples/vitepress/force-app/main/default/classes/SampleException.cls +17 -0
  56. package/examples/vitepress/force-app/main/default/classes/SampleInterface.cls +46 -0
  57. package/examples/vitepress/force-app/main/default/classes/Url.cls +195 -0
  58. package/examples/vitepress/package-lock.json +2574 -0
  59. package/examples/vitepress/package.json +18 -0
  60. package/examples/vitepress/sfdx-project.json +12 -0
  61. package/jest.config.js +1 -0
  62. package/package.json +11 -10
  63. package/src/application/Apexdocs.ts +16 -104
  64. package/src/application/__tests__/apex-file-reader.spec.ts +104 -0
  65. package/src/application/apex-file-reader.ts +42 -0
  66. package/src/application/file-writer.ts +25 -0
  67. package/src/application/generators/markdown.ts +53 -0
  68. package/src/application/generators/openapi.ts +56 -0
  69. package/src/cli/args.ts +17 -112
  70. package/src/cli/commands/markdown.ts +58 -0
  71. package/src/cli/generate.ts +7 -5
  72. package/src/{model/__tests__ → core/__test__}/manifest.spec.ts +1 -1
  73. package/src/core/manifest.ts +57 -51
  74. package/src/{__spec__/core → core/markdown/__test__}/expect-extensions.ts +5 -5
  75. package/src/core/markdown/__test__/generating-class-docs.spec.ts +727 -0
  76. package/src/{__spec__/core → core/markdown/__test__}/generating-enum-docs.spec.ts +82 -59
  77. package/src/{__spec__/core → core/markdown/__test__}/generating-interface-docs.spec.ts +94 -75
  78. package/src/core/markdown/__test__/generating-reference-guide.spec.ts +184 -0
  79. package/src/core/{__test__ → markdown/__test__}/inheritance-chain.test.ts +2 -2
  80. package/src/core/markdown/__test__/test-helpers.ts +22 -0
  81. package/src/core/{adapters → markdown/adapters}/__tests__/interface-adapter.spec.ts +38 -8
  82. package/src/core/{adapters → markdown/adapters}/apex-types.ts +7 -4
  83. package/src/core/{adapters → markdown/adapters}/inline.ts +1 -1
  84. package/src/core/markdown/adapters/renderable-bundle.ts +144 -0
  85. package/src/core/markdown/adapters/renderable-to-page-data.ts +92 -0
  86. package/src/core/{adapters → markdown/adapters}/types.d.ts +16 -2
  87. package/src/core/markdown/generate-docs.ts +158 -0
  88. package/src/core/markdown/reflection/error-handling.ts +37 -0
  89. package/src/core/markdown/reflection/filter-scope.ts +13 -0
  90. package/src/core/markdown/reflection/inheritance-chain-expanion.ts +22 -0
  91. package/src/core/markdown/reflection/inherited-member-expansion.ts +105 -0
  92. package/src/core/markdown/reflection/reflect-source.ts +41 -0
  93. package/src/core/markdown/reflection/sort-members.ts +59 -0
  94. package/src/{transpiler/markdown/plain-markdown → core/markdown/templates}/class-template.ts +2 -0
  95. package/src/core/markdown/templates/hookable.ts +7 -0
  96. package/src/core/{template.ts → markdown/templates/template.ts} +12 -12
  97. package/src/core/markdown/utils.ts +3 -0
  98. package/src/{transpiler → core}/openapi/__tests__/open-api-docs-processor.spec.ts +1 -1
  99. package/src/{model → core/openapi}/apex-type-wrappers/__tests__/ClassMirrorWrapper.spec.ts +3 -3
  100. package/src/core/openapi/file-container.ts +13 -0
  101. package/src/{service → core/openapi}/manifest-factory.ts +3 -3
  102. package/src/{transpiler → core}/openapi/open-api-docs-processor.ts +9 -10
  103. package/src/core/openapi/openapi-type-file.ts +14 -0
  104. package/src/{service → core/openapi}/parser.ts +8 -8
  105. package/src/{transpiler → core}/openapi/parsers/Builder.ts +2 -2
  106. package/src/{transpiler → core}/openapi/parsers/MethodParser.ts +5 -5
  107. package/src/{transpiler → core}/openapi/parsers/ParameterObjectBuilder.ts +2 -2
  108. package/src/{transpiler → core}/openapi/parsers/ReferenceBuilder.ts +3 -3
  109. package/src/{transpiler → core}/openapi/parsers/RequestBodyBuilder.ts +2 -2
  110. package/src/{transpiler → core}/openapi/parsers/ResponsesBuilder.ts +2 -2
  111. package/src/{transpiler → core}/openapi/parsers/__tests__/MethodParser.spec.ts +1 -1
  112. package/src/{transpiler → core}/openapi/parsers/__tests__/ParameterObjectBuilder.spec.ts +2 -2
  113. package/src/{transpiler → core}/openapi/parsers/__tests__/ReferenceBuilder.spec.ts +2 -2
  114. package/src/{transpiler → core}/openapi/parsers/__tests__/RequestBodyBuilder.spec.ts +2 -2
  115. package/src/{transpiler → core}/openapi/parsers/__tests__/ResponsesBuilder.spec.ts +1 -1
  116. package/src/{transpiler → core/openapi}/transpiler.ts +2 -6
  117. package/src/{model → core/openapi}/types-repository.ts +0 -9
  118. package/src/core/parse-apex-metadata.ts +14 -0
  119. package/src/core/settings.ts +56 -0
  120. package/src/core/shared/types.d.ts +92 -0
  121. package/src/core/shared/utils.ts +5 -0
  122. package/src/defaults.ts +8 -0
  123. package/src/index.ts +34 -2
  124. package/src/test-helpers/InterfaceMirrorBuilder.ts +0 -5
  125. package/src/test-helpers/SettingsBuilder.ts +1 -3
  126. package/src/util/logger.ts +2 -2
  127. package/src/util/string-utils.ts +0 -4
  128. package/tsconfig.json +5 -1
  129. package/apexdocs.config.ts +0 -13
  130. package/examples/plain-markdown/template.md +0 -3
  131. package/src/__spec__/core/generating-class-docs.spec.ts +0 -531
  132. package/src/__spec__/core/generating-reference-guide.spec.ts +0 -164
  133. package/src/__spec__/core/test-helpers.ts +0 -9
  134. package/src/application/generators/generate-markdown-files.ts +0 -53
  135. package/src/core/apex-bundle.ts +0 -3
  136. package/src/core/generate-docs.ts +0 -432
  137. package/src/model/markdown-file.ts +0 -122
  138. package/src/model/markdown-generation-util/doc-comment-annotation-util.ts +0 -50
  139. package/src/model/markdown-generation-util/field-declaration-util.ts +0 -71
  140. package/src/model/markdown-generation-util/index.ts +0 -3
  141. package/src/model/markdown-generation-util/method-declaration-util.ts +0 -166
  142. package/src/model/markdown-generation-util/type-declaration-util.ts +0 -91
  143. package/src/model/markdown-home-file.ts +0 -58
  144. package/src/model/markdown-type-file.ts +0 -169
  145. package/src/model/openapi/openapi-type-file.ts +0 -14
  146. package/src/model/outputFile.ts +0 -20
  147. package/src/service/__tests__/apex-file-reader.spec.ts +0 -93
  148. package/src/service/apex-file-reader.ts +0 -47
  149. package/src/service/file-writer.ts +0 -34
  150. package/src/service/metadata-processor.ts +0 -16
  151. package/src/service/state.ts +0 -24
  152. package/src/service/walkers/class-walker.ts +0 -30
  153. package/src/service/walkers/enum-walker.ts +0 -7
  154. package/src/service/walkers/interface-walker.ts +0 -12
  155. package/src/service/walkers/walker-factory.ts +0 -19
  156. package/src/service/walkers/walker.ts +0 -42
  157. package/src/settings.ts +0 -143
  158. package/src/transpiler/factory.ts +0 -31
  159. package/src/transpiler/file-container.ts +0 -13
  160. package/src/transpiler/generator-choices.ts +0 -1
  161. package/src/transpiler/markdown/class-file-generatorHelper.ts +0 -61
  162. package/src/transpiler/markdown/docsify/docsify-docs-processor.ts +0 -12
  163. package/src/transpiler/markdown/jekyll/jekyll-docsProcessor.ts +0 -50
  164. package/src/transpiler/markdown/markdown-transpiler-base.ts +0 -28
  165. package/src/transpiler/processor-type-transpiler.ts +0 -18
  166. /package/src/{service → application}/file-system.ts +0 -0
  167. /package/src/core/{adapters → markdown/adapters}/__tests__/documentables.spec.ts +0 -0
  168. /package/src/core/{adapters → markdown/adapters}/__tests__/references.spec.ts +0 -0
  169. /package/src/core/{adapters → markdown/adapters}/documentables.ts +0 -0
  170. /package/src/core/{adapters → markdown/adapters}/fields-and-properties.ts +0 -0
  171. /package/src/core/{adapters → markdown/adapters}/methods-and-constructors.ts +0 -0
  172. /package/src/core/{adapters → markdown/adapters}/type-utils.ts +0 -0
  173. /package/src/core/{inheritance-chain.ts → markdown/reflection/inheritance-chain.ts} +0 -0
  174. /package/src/{transpiler/markdown/plain-markdown → core/markdown/templates}/constructors-partial-template.ts +0 -0
  175. /package/src/{transpiler/markdown/plain-markdown → core/markdown/templates}/documentable-partial-template.ts +0 -0
  176. /package/src/{transpiler/markdown/plain-markdown → core/markdown/templates}/enum-template.ts +0 -0
  177. /package/src/{transpiler/markdown/plain-markdown → core/markdown/templates}/fieldsPartialTemplate.ts +0 -0
  178. /package/src/{transpiler/markdown/plain-markdown → core/markdown/templates}/grouped-members-partial-template.ts +0 -0
  179. /package/src/{transpiler/markdown/plain-markdown → core/markdown/templates}/interface-template.ts +0 -0
  180. /package/src/{transpiler/markdown/plain-markdown → core/markdown/templates}/methods-partial-template.ts +0 -0
  181. /package/src/core/{templates → markdown/templates}/reference-guide.ts +0 -0
  182. /package/src/{transpiler/markdown/plain-markdown → core/markdown/templates}/type-doc-partial.ts +0 -0
  183. /package/src/{service → core/openapi}/__tests__/manifest-factory.spec.ts +0 -0
  184. /package/src/{model → core}/openapi/__tests__/open-api.spec.ts +0 -0
  185. /package/src/{model → core}/openapi/apex-doc-types.ts +0 -0
  186. /package/src/{model → core/openapi}/apex-type-wrappers/ClassMirrorWrapper.ts +0 -0
  187. /package/src/{model → core/openapi}/apex-type-wrappers/MethodMirrorWrapper.ts +0 -0
  188. /package/src/{model → core}/openapi/open-api-types.ts +0 -0
  189. /package/src/{model → core}/openapi/open-api.ts +0 -0
@@ -0,0 +1,18 @@
1
+ {
2
+ "name": "vitepress-example",
3
+ "scripts": {
4
+ "docs:clean": "rimraf --glob 'docs/!(.vitepress|index-frontmatter.md|api-examples.md|markdown-examples.md)'",
5
+ "apexdocs:build": "npm run docs:clean && ts-node ../../src/cli/generate.ts markdown",
6
+ "docs:build": "vitepress build docs",
7
+ "docs:gen": "npm run docs:clean && npm run docs:build",
8
+ "docs:dev": "vitepress dev docs",
9
+ "docs:preview": "vitepress preview docs"
10
+ },
11
+ "devDependencies": {
12
+ "ts-node": "^10.9.2",
13
+ "vitepress": "^1.3.1"
14
+ },
15
+ "dependencies": {
16
+ "rimraf": "^5.0.7"
17
+ }
18
+ }
@@ -0,0 +1,12 @@
1
+ {
2
+ "packageDirectories": [
3
+ {
4
+ "path": "force-app",
5
+ "default": true
6
+ }
7
+ ],
8
+ "name": "vitepress",
9
+ "namespace": "",
10
+ "sfdcLoginUrl": "https://login.salesforce.com",
11
+ "sourceApiVersion": "61.0"
12
+ }
package/jest.config.js CHANGED
@@ -5,5 +5,6 @@ module.exports = {
5
5
  moduleNameMapper: {
6
6
  '^chalk$': '<rootDir>/__mocks__/chalk.js',
7
7
  '^log-update$': '<rootDir>/__mocks__/log-update.js',
8
+ '#utils/(.*)$': '<rootDir>/src/util/$1',
8
9
  },
9
10
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cparra/apexdocs",
3
- "version": "2.25.0-alpha.4",
3
+ "version": "2.25.0-alpha.6",
4
4
  "description": "Library with CLI capabilities to generate documentation for Salesforce Apex classes.",
5
5
  "keywords": [
6
6
  "apex",
@@ -13,17 +13,15 @@
13
13
  "exports": "./dist/index.js",
14
14
  "types": "./dist/index.d.ts",
15
15
  "bin": {
16
- "apexdocs-generate": "./dist/cli/generate.js"
16
+ "apexdocs": "./dist/cli/generate.js"
17
17
  },
18
18
  "scripts": {
19
19
  "test": "npm run build && jest",
20
- "build": "rimraf ./lib && npm run lint && pkgroll --minify",
20
+ "build": "rimraf ./lib && npm run lint && tsc --noEmit && pkgroll",
21
21
  "lint": "eslint \"./src/**/*.{js,ts}\" --quiet --fix",
22
22
  "prepare": "npm run build",
23
23
  "version": "npm run format && git add -A src",
24
- "postversion": "git push && git push --tags",
25
- "docs:init": "docsify init docs",
26
- "docs:serve": "docsify serve docs"
24
+ "postversion": "git push && git push --tags"
27
25
  },
28
26
  "author": "Cesar Parra",
29
27
  "license": "MIT",
@@ -34,17 +32,15 @@
34
32
  "devDependencies": {
35
33
  "@eslint/js": "^9.6.0",
36
34
  "@types/eslint__js": "^8.42.3",
37
- "@types/html-entities": "^1.3.4",
38
35
  "@types/jest": "^29.5.12",
39
36
  "@types/node": "^20.14.10",
40
37
  "@types/shelljs": "^0.8.15",
41
- "docsify": "^4.13.1",
42
38
  "eslint": "^8.57.0",
43
39
  "eslint-config-prettier": "^9.1.0",
44
40
  "husky": "^9.0.11",
45
41
  "jest": "^29.7.0",
46
42
  "lint-staged": "^15.2.7",
47
- "pkgroll": "^2.1.1",
43
+ "pkgroll": "^2.4.2",
48
44
  "prettier": "^3.3.2",
49
45
  "rimraf": "^6.0.0",
50
46
  "ts-jest": "^29.2.0",
@@ -62,16 +58,21 @@
62
58
  ]
63
59
  },
64
60
  "dependencies": {
65
- "@cparra/apex-reflection": "2.9.5",
61
+ "@cparra/apex-reflection": "2.11.3",
66
62
  "@types/js-yaml": "^4.0.9",
67
63
  "@types/yargs": "^17.0.32",
68
64
  "chalk": "^4.1.2",
69
65
  "cosmiconfig": "^9.0.0",
66
+ "cosmiconfig-typescript-loader": "^5.0.0",
70
67
  "fast-xml-parser": "^4.4.0",
71
68
  "fp-ts": "^2.16.8",
72
69
  "handlebars": "^4.7.8",
73
70
  "js-yaml": "^4.1.0",
74
71
  "log-update": "4.0.0",
72
+ "type-fest": "^4.23.0",
75
73
  "yargs": "^17.7.2"
74
+ },
75
+ "imports": {
76
+ "#utils/*": "./src/util/*.ts"
76
77
  }
77
78
  }
@@ -1,20 +1,10 @@
1
- import { ApexFileReader } from '../service/apex-file-reader';
2
- import { DefaultFileSystem } from '../service/file-system';
3
- import { ReflectionResult, reflect, Type } from '@cparra/apex-reflection';
4
- import { Logger } from '../util/logger';
5
- import { createManifest } from '../service/manifest-factory';
6
- import { RawBodyParser } from '../service/parser';
7
- import { Settings, TargetFile } from '../settings';
8
- import Transpiler from '../transpiler/transpiler';
9
- import { FileWriter } from '../service/file-writer';
10
- import ErrorLogger from '../util/error-logger';
11
- import ApexBundle from '../core/apex-bundle';
12
- import Manifest from '../core/manifest';
13
- import { TypesRepository } from '../model/types-repository';
14
- import { TypeTranspilerFactory } from '../transpiler/factory';
15
- import { generateMarkdownFiles } from './generators/generate-markdown-files';
16
- import { AllConfigurableOptions } from '../cli/args';
17
- import { GeneratorChoices } from '../transpiler/generator-choices';
1
+ import markdown from './generators/markdown';
2
+ import openApi from './generators/openapi';
3
+
4
+ import { ApexFileReader } from './apex-file-reader';
5
+ import { DefaultFileSystem } from './file-system';
6
+ import { Logger } from '#utils/logger';
7
+ import { UserDefinedConfig } from '../core/shared/types';
18
8
 
19
9
  /**
20
10
  * Application entry-point to generate documentation out of Apex source files.
@@ -23,96 +13,18 @@ export class Apexdocs {
23
13
  /**
24
14
  * Generates documentation out of Apex source files.
25
15
  */
26
- static generate(config: AllConfigurableOptions): void {
16
+ static async generate(config: UserDefinedConfig): Promise<void> {
27
17
  Logger.logSingle('Initializing...', false);
28
- this.initializeSettings(config);
29
- const fileBodies = ApexFileReader.processFiles(new DefaultFileSystem());
30
-
31
- if (Settings.getInstance().targetGenerator === 'plain-markdown') {
32
- generateMarkdownFiles(fileBodies);
33
- } else {
34
- const manifest = createManifest(new RawBodyParser(fileBodies), this._reflectionWithLogger);
35
- TypesRepository.getInstance().populateAll(manifest.types);
36
- const filteredTypes = this.filterByScopes(manifest);
37
- TypesRepository.getInstance().populateScoped(filteredTypes);
38
- const processor = TypeTranspilerFactory.get(Settings.getInstance().targetGenerator);
39
- Transpiler.generate(filteredTypes, processor);
40
- const generatedFiles = processor.fileBuilder().files();
41
-
42
- const files: TargetFile[] = [];
43
- FileWriter.write(generatedFiles, (file: TargetFile) => {
44
- Logger.logSingle(`${file.name} processed.`, false, 'green', false);
45
- files.push(file);
46
- });
47
18
 
48
- Settings.getInstance().onAfterProcess(files);
19
+ const fileBodies = ApexFileReader.processFiles(new DefaultFileSystem(), config.sourceDir, config.includeMetadata);
49
20
 
50
- // Error logging
51
- ErrorLogger.logErrors(filteredTypes);
21
+ switch (config.targetGenerator) {
22
+ case 'markdown':
23
+ await markdown(fileBodies, config);
24
+ break;
25
+ case 'openapi':
26
+ openApi(fileBodies, config);
27
+ break;
52
28
  }
53
29
  }
54
-
55
- private static initializeSettings(argv: AllConfigurableOptions) {
56
- const targetGenerator = argv.targetGenerator as GeneratorChoices;
57
- Settings.build({
58
- sourceDirectory: argv.sourceDir,
59
- scope: argv.scope,
60
- outputDir: argv.targetDir,
61
- targetGenerator: targetGenerator,
62
- indexOnly: argv.indexOnly,
63
- defaultGroupName: argv.defaultGroupName,
64
- openApiTitle: argv.openApiTitle,
65
- title: argv.title,
66
- namespace: argv.namespace,
67
- openApiFileName: argv.openApiFileName,
68
- sortMembersAlphabetically: argv.sortMembersAlphabetically,
69
- includeMetadata: argv.includeMetadata,
70
- rootDir: argv.documentationRootDir,
71
- onAfterProcess: argv.onAfterProcess,
72
- onBeforeFileWrite: argv.onBeforeFileWrite,
73
- frontMatterHeader: argv.frontMatterHeader,
74
- linkingStrategy:
75
- targetGenerator === 'plain-markdown'
76
- ? 'path-relative'
77
- : TypeTranspilerFactory.get(targetGenerator).getLinkingStrategy(),
78
- });
79
- }
80
-
81
- private static filterByScopes(manifest: Manifest) {
82
- let filteredTypes: Type[];
83
- let filteredLogMessage;
84
- if (Settings.getInstance().config.targetGenerator !== 'openapi') {
85
- filteredTypes = manifest.filteredByAccessModifierAndAnnotations(Settings.getInstance().scope);
86
- filteredLogMessage = `Filtered ${manifest.types.length - filteredTypes.length} file(s) based on scope: ${
87
- Settings.getInstance().scope
88
- }`;
89
- } else {
90
- // If we are dealing with an OpenApi generator, we ignore the passed in access modifiers, and instead
91
- // we only keep classes annotated as @RestResource
92
- filteredTypes = manifest.filteredByAccessModifierAndAnnotations([
93
- 'restresource',
94
- 'httpdelete',
95
- 'httpget',
96
- 'httppatch',
97
- 'httppost',
98
- 'httpput',
99
- ]);
100
- filteredLogMessage = `Filtered ${
101
- manifest.types.length - filteredTypes.length
102
- } file(s), only keeping classes annotated as @RestResource.`;
103
- }
104
- Logger.clear();
105
-
106
- Logger.logSingle(filteredLogMessage, false, 'green', false);
107
- Logger.logSingle(`Creating documentation for ${filteredTypes.length} file(s)`, false, 'green', false);
108
- return filteredTypes;
109
- }
110
-
111
- static _reflectionWithLogger = (apexBundle: ApexBundle): ReflectionResult => {
112
- const result = reflect(apexBundle.rawTypeContent);
113
- if (result.error) {
114
- Logger.error(`${apexBundle.filePath} - Parsing error ${result.error?.message}`);
115
- }
116
- return result;
117
- };
118
30
  }
@@ -0,0 +1,104 @@
1
+ import { Settings, SettingsConfig } from '../../core/settings';
2
+ import { ApexFileReader } from '../apex-file-reader';
3
+
4
+ describe('File Reader', () => {
5
+ beforeEach(() => {
6
+ Settings.build({
7
+ sourceDirectory: '',
8
+ recursive: true,
9
+ scope: [],
10
+ outputDir: '',
11
+ targetGenerator: 'markdown',
12
+ indexOnly: false,
13
+ defaultGroupName: 'Misc',
14
+ sanitizeHtml: true,
15
+ openApiFileName: 'openapi',
16
+ title: 'Classes',
17
+ includeMetadata: false,
18
+ } as SettingsConfig);
19
+ });
20
+
21
+ it('returns an empty list when there are no files in the directory', () => {
22
+ const result = ApexFileReader.processFiles(
23
+ {
24
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
25
+ isDirectory(_: string): boolean {
26
+ return false;
27
+ },
28
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
29
+ joinPath(_: string): string {
30
+ return '';
31
+ },
32
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
33
+ readDirectory(_: string): string[] {
34
+ return [];
35
+ },
36
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
37
+ readFile(_: string): string {
38
+ return '';
39
+ },
40
+ exists(): boolean {
41
+ return true;
42
+ },
43
+ },
44
+ '',
45
+ false,
46
+ );
47
+ expect(result.length).toBe(0);
48
+ });
49
+
50
+ it('returns an empty list when there are no Apex files in the directory', () => {
51
+ const result = ApexFileReader.processFiles(
52
+ {
53
+ isDirectory(): boolean {
54
+ return false;
55
+ },
56
+ joinPath(): string {
57
+ return '';
58
+ },
59
+ readDirectory(): string[] {
60
+ return ['SomeFile.md'];
61
+ },
62
+ readFile(): string {
63
+ return '';
64
+ },
65
+ exists(): boolean {
66
+ return true;
67
+ },
68
+ },
69
+ '',
70
+ false,
71
+ );
72
+ expect(result.length).toBe(0);
73
+ });
74
+
75
+ it('returns the file contents for an Apex file', () => {
76
+ const result = ApexFileReader.processFiles(
77
+ {
78
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
79
+ isDirectory(_: string): boolean {
80
+ return false;
81
+ },
82
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
83
+ joinPath(_: string): string {
84
+ return '';
85
+ },
86
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
87
+ readDirectory(_: string): string[] {
88
+ return ['SomeApexFile.cls'];
89
+ },
90
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
91
+ readFile(_: string): string {
92
+ return 'public class MyClass{}';
93
+ },
94
+ exists(): boolean {
95
+ return true;
96
+ },
97
+ },
98
+ '',
99
+ false,
100
+ );
101
+ expect(result.length).toBe(1);
102
+ expect(result[0].content).toBe('public class MyClass{}');
103
+ });
104
+ });
@@ -0,0 +1,42 @@
1
+ import { FileSystem } from './file-system';
2
+ import { SourceFile } from '../core/shared/types';
3
+
4
+ const APEX_FILE_EXTENSION = '.cls';
5
+
6
+ /**
7
+ * Reads from .cls files and returns their raw body.
8
+ */
9
+ export class ApexFileReader {
10
+ /**
11
+ * Reads from .cls files and returns their raw body.
12
+ */
13
+ static processFiles(fileSystem: FileSystem, rootPath: string, includeMetadata: boolean): SourceFile[] {
14
+ let bundles: SourceFile[] = [];
15
+
16
+ const directoryContents = fileSystem.readDirectory(rootPath);
17
+ directoryContents.forEach((filePath) => {
18
+ const currentPath = fileSystem.joinPath(rootPath, filePath);
19
+ if (fileSystem.isDirectory(currentPath)) {
20
+ bundles = bundles.concat(this.processFiles(fileSystem, currentPath, includeMetadata));
21
+ }
22
+
23
+ if (!this.isApexFile(filePath)) {
24
+ return;
25
+ }
26
+
27
+ const rawTypeContent = fileSystem.readFile(currentPath);
28
+ const metadataPath = fileSystem.joinPath(rootPath, `${filePath}-meta.xml`);
29
+ let rawMetadataContent = null;
30
+ if (includeMetadata) {
31
+ rawMetadataContent = fileSystem.exists(metadataPath) ? fileSystem.readFile(metadataPath) : null;
32
+ }
33
+
34
+ bundles.push({ filePath: currentPath, content: rawTypeContent, metadataContent: rawMetadataContent });
35
+ });
36
+ return bundles;
37
+ }
38
+
39
+ private static isApexFile(currentFile: string): boolean {
40
+ return currentFile.endsWith(APEX_FILE_EXTENSION);
41
+ }
42
+ }
@@ -0,0 +1,25 @@
1
+ import * as fs from 'fs';
2
+ import * as path from 'path';
3
+ import { PageData } from '../core/shared/types';
4
+
5
+ export class FileWriter {
6
+ static write(files: PageData[], outputDir: string, onWriteCallback: (file: PageData) => void) {
7
+ files.forEach((file) => {
8
+ const resolvedFile = this.getTargetLocation(file, outputDir);
9
+ if (!fs.existsSync(resolvedFile.directory)) {
10
+ fs.mkdirSync(resolvedFile.directory, { recursive: true });
11
+ }
12
+
13
+ const filePath = path.join(resolvedFile.directory, `${resolvedFile.fileName}.${resolvedFile.fileExtension}`);
14
+ fs.writeFileSync(filePath, resolvedFile.content, 'utf8');
15
+ onWriteCallback(resolvedFile);
16
+ });
17
+ }
18
+
19
+ private static getTargetLocation(file: PageData, outputDir: string): PageData {
20
+ return {
21
+ ...file,
22
+ directory: path.join(outputDir, file.directory),
23
+ };
24
+ }
25
+ }
@@ -0,0 +1,53 @@
1
+ import { generateDocs } from '../../core/markdown/generate-docs';
2
+ import { FileWriter } from '../file-writer';
3
+ import { Logger } from '#utils/logger';
4
+ import { pipe } from 'fp-ts/function';
5
+ import { PageData, PostHookDocumentationBundle, SourceFile, UserDefinedMarkdownConfig } from '../../core/shared/types';
6
+ import { ReflectionError } from '../../core/markdown/reflection/error-handling';
7
+ import { referenceGuideTemplate } from '../../core/markdown/templates/reference-guide';
8
+ import * as TE from 'fp-ts/TaskEither';
9
+ import { isSkip } from '../../core/shared/utils';
10
+
11
+ export default function generate(bundles: SourceFile[], config: UserDefinedMarkdownConfig) {
12
+ return pipe(
13
+ generateDocumentationBundle(bundles, config),
14
+ TE.map((files) => writeFilesToSystem(files, config.targetDir)),
15
+ TE.mapLeft((error) => {
16
+ if (error._tag === 'HookError') {
17
+ Logger.error('Error(s) occurred while processing hooks. Please review the following issues:');
18
+ Logger.error(error.error);
19
+ return;
20
+ }
21
+
22
+ const errorMessages = [
23
+ 'Error(s) occurred while parsing files. Please review the following issues:',
24
+ ...error.errors.map(formatReflectionError),
25
+ ].join('\n');
26
+
27
+ Logger.error(errorMessages);
28
+ }),
29
+ )();
30
+ }
31
+
32
+ function generateDocumentationBundle(bundles: SourceFile[], config: UserDefinedMarkdownConfig) {
33
+ return generateDocs(bundles, {
34
+ ...config,
35
+ referenceGuideTemplate: referenceGuideTemplate,
36
+ });
37
+ }
38
+
39
+ function writeFilesToSystem(files: PostHookDocumentationBundle, outputDir: string) {
40
+ FileWriter.write(
41
+ [files.referenceGuide, ...files.docs]
42
+ // Filter out any files that should be skipped
43
+ .filter((file) => !isSkip(file)) as PageData[],
44
+ outputDir,
45
+ (file: PageData) => {
46
+ Logger.logSingle(`${file.fileName} processed.`, false, 'green', false);
47
+ },
48
+ );
49
+ }
50
+
51
+ function formatReflectionError(error: ReflectionError) {
52
+ return `Source file: ${error.file}\n${error.message}\n`;
53
+ }
@@ -0,0 +1,56 @@
1
+ import { createManifest } from '../../core/openapi/manifest-factory';
2
+ import { RawBodyParser } from '../../core/openapi/parser';
3
+ import { TypesRepository } from '../../core/openapi/types-repository';
4
+ import Transpiler from '../../core/openapi/transpiler';
5
+ import { FileWriter } from '../file-writer';
6
+ import { Logger } from '#utils/logger';
7
+ import ErrorLogger from '#utils/error-logger';
8
+ import { reflect, ReflectionResult } from '@cparra/apex-reflection';
9
+ import Manifest from '../../core/manifest';
10
+ import { PageData, SourceFile, UserDefinedOpenApiConfig } from '../../core/shared/types';
11
+ import { OpenApiDocsProcessor } from '../../core/openapi/open-api-docs-processor';
12
+
13
+ export default function openApi(fileBodies: SourceFile[], config: UserDefinedOpenApiConfig) {
14
+ const manifest = createManifest(new RawBodyParser(fileBodies), reflectionWithLogger);
15
+ TypesRepository.getInstance().populateAll(manifest.types);
16
+ const filteredTypes = filterByScopes(manifest);
17
+ const processor = new OpenApiDocsProcessor();
18
+ Transpiler.generate(filteredTypes, processor);
19
+ const generatedFiles = processor.fileBuilder().files();
20
+
21
+ FileWriter.write(generatedFiles, config.targetDir, (file: PageData) => {
22
+ Logger.logSingle(`${file.fileName} processed.`, false, 'green', false);
23
+ });
24
+
25
+ // Error logging
26
+ ErrorLogger.logErrors(filteredTypes);
27
+ }
28
+
29
+ function reflectionWithLogger(apexBundle: SourceFile): ReflectionResult {
30
+ const result = reflect(apexBundle.content);
31
+ if (result.error) {
32
+ Logger.error(`${apexBundle.filePath} - Parsing error ${result.error?.message}`);
33
+ }
34
+ return result;
35
+ }
36
+
37
+ function filterByScopes(manifest: Manifest) {
38
+ // If we are dealing with an OpenApi generator, we ignore the passed in access modifiers, and instead
39
+ // we only keep classes annotated as @RestResource
40
+ const filteredTypes = manifest.filteredByAccessModifierAndAnnotations([
41
+ 'restresource',
42
+ 'httpdelete',
43
+ 'httpget',
44
+ 'httppatch',
45
+ 'httppost',
46
+ 'httpput',
47
+ ]);
48
+ const filteredLogMessage = `Filtered ${
49
+ manifest.types.length - filteredTypes.length
50
+ } file(s), only keeping classes annotated as @RestResource.`;
51
+ Logger.clear();
52
+
53
+ Logger.logSingle(filteredLogMessage, false, 'green', false);
54
+ Logger.logSingle(`Creating documentation for ${filteredTypes.length} file(s)`, false, 'green', false);
55
+ return filteredTypes;
56
+ }