@cparra/apexdocs 2.25.0-alpha.9 → 3.0.0-alpha.2

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 (49) hide show
  1. package/dist/cli/generate.js +30 -29
  2. package/dist/defaults-jLXD2y8-.js +13 -0
  3. package/dist/index.d.ts +12 -6
  4. package/dist/index.js +1 -1
  5. package/examples/vitepress/apexdocs.config.ts +1 -1
  6. package/package.json +1 -1
  7. package/src/application/file-writer.ts +4 -4
  8. package/src/application/generators/markdown.ts +1 -1
  9. package/src/application/generators/openapi.ts +1 -1
  10. package/src/cli/args.ts +1 -1
  11. package/src/cli/commands/markdown.ts +6 -12
  12. package/src/cli/generate.ts +3 -3
  13. package/src/core/markdown/__test__/generating-class-docs.spec.ts +1 -1
  14. package/src/core/markdown/__test__/generating-enum-docs.spec.ts +1 -1
  15. package/src/core/markdown/__test__/generating-interface-docs.spec.ts +3 -1
  16. package/src/core/markdown/__test__/test-helpers.ts +1 -0
  17. package/src/core/markdown/adapters/__tests__/interface-adapter.spec.ts +1 -0
  18. package/src/core/markdown/adapters/reference-guide.ts +3 -1
  19. package/src/core/markdown/adapters/renderable-bundle.ts +13 -3
  20. package/src/core/markdown/adapters/renderable-to-page-data.ts +2 -2
  21. package/src/core/markdown/generate-docs.ts +1 -0
  22. package/src/core/openapi/openapi-type-file.ts +1 -1
  23. package/src/core/shared/types.d.ts +11 -5
  24. package/src/defaults.ts +1 -0
  25. package/src/index.ts +6 -1
  26. /package/examples/{plain-markdown → markdown}/.forceignore +0 -0
  27. /package/examples/{plain-markdown → markdown}/config/project-scratch-def.json +0 -0
  28. /package/examples/{plain-markdown → markdown}/docs/index.md +0 -0
  29. /package/examples/{plain-markdown → markdown}/docs/miscellaneous/BaseClass.md +0 -0
  30. /package/examples/{plain-markdown → markdown}/docs/miscellaneous/MultiInheritanceClass.md +0 -0
  31. /package/examples/{plain-markdown → markdown}/docs/miscellaneous/ParentInterface.md +0 -0
  32. /package/examples/{plain-markdown → markdown}/docs/miscellaneous/ReferencedEnum.md +0 -0
  33. /package/examples/{plain-markdown → markdown}/docs/miscellaneous/SampleException.md +0 -0
  34. /package/examples/{plain-markdown → markdown}/docs/miscellaneous/SampleInterface.md +0 -0
  35. /package/examples/{plain-markdown → markdown}/docs/miscellaneous/Url.md +0 -0
  36. /package/examples/{plain-markdown → markdown}/docs/sample-enums/SampleEnum.md +0 -0
  37. /package/examples/{plain-markdown → markdown}/docs/samplegroup/SampleClass.md +0 -0
  38. /package/examples/{plain-markdown → markdown}/force-app/classes/BaseClass.cls +0 -0
  39. /package/examples/{plain-markdown → markdown}/force-app/classes/MultiInheritanceClass.cls +0 -0
  40. /package/examples/{plain-markdown → markdown}/force-app/classes/ParentInterface.cls +0 -0
  41. /package/examples/{plain-markdown → markdown}/force-app/classes/ReferencedEnum.cls +0 -0
  42. /package/examples/{plain-markdown → markdown}/force-app/classes/SampleClass.cls +0 -0
  43. /package/examples/{plain-markdown → markdown}/force-app/classes/SampleEnum.cls +0 -0
  44. /package/examples/{plain-markdown → markdown}/force-app/classes/SampleException.cls +0 -0
  45. /package/examples/{plain-markdown → markdown}/force-app/classes/SampleInterface.cls +0 -0
  46. /package/examples/{plain-markdown → markdown}/force-app/classes/Url.cls +0 -0
  47. /package/examples/{plain-markdown → markdown}/package-lock.json +0 -0
  48. /package/examples/{plain-markdown → markdown}/package.json +0 -0
  49. /package/examples/{plain-markdown → markdown}/sfdx-project.json +0 -0
@@ -5,13 +5,13 @@ var _function = require('fp-ts/function');
5
5
  var E = require('fp-ts/Either');
6
6
  var TE = require('fp-ts/TaskEither');
7
7
  var yaml = require('js-yaml');
8
+ var path = require('path');
8
9
  var apexReflection = require('@cparra/apex-reflection');
9
10
  var O = require('fp-ts/Option');
10
11
  var fastXmlParser = require('fast-xml-parser');
11
12
  var Handlebars = require('handlebars');
12
- var defaults = require('../defaults-DUwru49Q.js');
13
+ var defaults = require('../defaults-jLXD2y8-.js');
13
14
  var fs = require('fs');
14
- var path = require('path');
15
15
  var chalk = require('chalk');
16
16
  var logUpdate = require('log-update');
17
17
  var cosmiconfig = require('cosmiconfig');
@@ -38,9 +38,9 @@ function _interopNamespaceDefault(e) {
38
38
  var E__namespace = /*#__PURE__*/_interopNamespaceDefault(E);
39
39
  var TE__namespace = /*#__PURE__*/_interopNamespaceDefault(TE);
40
40
  var yaml__namespace = /*#__PURE__*/_interopNamespaceDefault(yaml);
41
+ var path__namespace = /*#__PURE__*/_interopNamespaceDefault(path);
41
42
  var O__namespace = /*#__PURE__*/_interopNamespaceDefault(O);
42
43
  var fs__namespace = /*#__PURE__*/_interopNamespaceDefault(fs);
43
- var path__namespace = /*#__PURE__*/_interopNamespaceDefault(path);
44
44
  var yargs__namespace = /*#__PURE__*/_interopNamespaceDefault(yargs);
45
45
 
46
46
  function apply(fn, ...front) {
@@ -570,7 +570,7 @@ function singleGroup(headingLevel, groupName, adapter, members, linkGenerator) {
570
570
  }
571
571
 
572
572
  function parsedFilesToRenderableBundle(config, parsedFiles, references) {
573
- const referenceFinder = apply(linkGenerator, references);
573
+ const referenceFinder = apply(linkGenerator, references, config.documentationRootDir);
574
574
  function toReferenceGuide(parsedFiles2) {
575
575
  return parsedFiles2.reduce(
576
576
  addToReferenceGuide(referenceFinder, config, references),
@@ -604,11 +604,15 @@ function addToReferenceGuide(findLinkFromHome, config, references) {
604
604
  return acc;
605
605
  };
606
606
  }
607
- const linkGenerator = (references, referenceName) => {
607
+ const linkGenerator = (references, documentationRootDir, referenceName) => {
608
608
  const reference = references[referenceName];
609
609
  return reference ? (
610
610
  // Starting the path with a "/" will ensure the link will always be relative to the root of the site.
611
- { __type: "link", title: reference.displayName, url: `/${reference.pathFromRoot}` }
611
+ {
612
+ __type: "link",
613
+ title: reference.displayName,
614
+ url: path__namespace.join("/", documentationRootDir, reference.referencePath)
615
+ }
612
616
  ) : referenceName;
613
617
  };
614
618
  function getTypeGroup$1(type, config) {
@@ -1194,7 +1198,7 @@ const convertToDocumentationBundle = (referenceGuideTemplate, { referencesByGrou
1194
1198
  referenceGuide: {
1195
1199
  frontmatter: null,
1196
1200
  content: referencesToReferenceGuideContent(referencesByGroup, referenceGuideTemplate),
1197
- filePath: "index.md"
1201
+ outputDocPath: "index.md"
1198
1202
  },
1199
1203
  docs: renderables.map(
1200
1204
  (renderable) => renderableToPageData(Object.values(referencesByGroup).flat(), renderable)
@@ -1228,7 +1232,7 @@ function renderableToPageData(referenceGuideReference, renderable) {
1228
1232
  name: renderable2.name,
1229
1233
  type: renderable2.type
1230
1234
  },
1231
- filePath: reference.reference.pathFromRoot,
1235
+ outputDocPath: reference.reference.outputDocPath,
1232
1236
  frontmatter: null,
1233
1237
  content: docContents,
1234
1238
  group: (_a = renderable2.doc.group) != null ? _a : defaults.defaults.defaultGroupName
@@ -1446,10 +1450,12 @@ function parsedFilesToReferenceGuide(config, parsedFiles) {
1446
1450
  }, {});
1447
1451
  }
1448
1452
  function parsedFileToDocPageReference(config, parsedFile) {
1453
+ const path = `${slugify(getTypeGroup(parsedFile.type, config))}/${parsedFile.type.name}.md`;
1449
1454
  return {
1450
1455
  source: parsedFile.source,
1451
1456
  displayName: parsedFile.type.name,
1452
- pathFromRoot: `${slugify(getTypeGroup(parsedFile.type, config))}/${parsedFile.type.name}.md`
1457
+ outputDocPath: path,
1458
+ referencePath: path
1453
1459
  };
1454
1460
  }
1455
1461
  function getTypeGroup(type, config) {
@@ -1641,15 +1647,15 @@ var __spreadProps$6 = (a, b) => __defProps$6(a, __getOwnPropDescs$6(b));
1641
1647
  class FileWriter {
1642
1648
  static write(files, outputDir, onWriteCallback) {
1643
1649
  files.forEach((file) => {
1644
- const { filePath, content } = this.getTargetLocation(file, outputDir);
1645
- fs__namespace.mkdirSync(path__namespace.dirname(filePath), { recursive: true });
1646
- fs__namespace.writeFileSync(filePath, content, "utf8");
1650
+ const { outputDocPath, content } = this.getTargetLocation(file, outputDir);
1651
+ fs__namespace.mkdirSync(path__namespace.dirname(outputDocPath), { recursive: true });
1652
+ fs__namespace.writeFileSync(outputDocPath, content, "utf8");
1647
1653
  onWriteCallback(file);
1648
1654
  });
1649
1655
  }
1650
1656
  static getTargetLocation(file, outputDir) {
1651
1657
  return __spreadProps$6(__spreadValues$6({}, file), {
1652
- filePath: path__namespace.join(outputDir, file.filePath)
1658
+ outputDocPath: path__namespace.join(outputDir, file.outputDocPath)
1653
1659
  });
1654
1660
  }
1655
1661
  }
@@ -1765,7 +1771,7 @@ function writeFilesToSystem(files, outputDir) {
1765
1771
  [files.referenceGuide, ...files.docs].filter((file) => !isSkip(file)),
1766
1772
  outputDir,
1767
1773
  (file) => {
1768
- Logger.logSingle(`${file.filePath} processed.`, false, "green", false);
1774
+ Logger.logSingle(`${file.outputDocPath} processed.`, false, "green", false);
1769
1775
  }
1770
1776
  );
1771
1777
  }
@@ -2650,7 +2656,7 @@ var __spreadProps$1 = (a, b) => __defProps$1(a, __getOwnPropDescs$1(b));
2650
2656
  function createOpenApiFile(fileName, openApiModel) {
2651
2657
  const content = JSON.stringify(__spreadProps$1(__spreadValues$1({}, openApiModel), { namespace: void 0 }), null, 2);
2652
2658
  return {
2653
- filePath: "",
2659
+ outputDocPath: "",
2654
2660
  content,
2655
2661
  frontmatter: null,
2656
2662
  group: null
@@ -2723,7 +2729,7 @@ function openApi(fileBodies, config) {
2723
2729
  Transpiler.generate(filteredTypes, processor);
2724
2730
  const generatedFiles = processor.fileBuilder().files();
2725
2731
  FileWriter.write(generatedFiles, config.targetDir, (file) => {
2726
- Logger.logSingle(`${file.filePath} processed.`, false, "green", false);
2732
+ Logger.logSingle(`${file.outputDocPath} processed.`, false, "green", false);
2727
2733
  });
2728
2734
  ErrorLogger.logErrors(filteredTypes);
2729
2735
  }
@@ -2859,27 +2865,17 @@ const markdownOptions = {
2859
2865
  array: true,
2860
2866
  alias: "p",
2861
2867
  default: defaults.defaults.scope,
2862
- describe: "A list of scopes to document. Values should be separated by a space, e.g --scope global public namespaceaccessible. Annotations are supported and should be passed lowercased and without the @ symbol, e.g. namespaceaccessible auraenabled. Note that this setting is ignored if generating an OpenApi REST specification since that looks for classes annotated with @RestResource."
2868
+ describe: "A list of scopes to document. Values should be separated by a space, e.g --scope global public namespaceaccessible. Annotations are supported and should be passed lowercased and without the @ symbol, e.g. namespaceaccessible auraenabled."
2863
2869
  },
2864
2870
  defaultGroupName: {
2865
2871
  type: "string",
2866
2872
  default: defaults.defaults.defaultGroupName,
2867
2873
  describe: "Defines the @group name to be used when a file does not specify it."
2868
2874
  },
2869
- openApiTitle: {
2870
- type: "string",
2871
- default: "Apex REST Api",
2872
- describe: 'If using "openapi" as the target generator, this allows you to specify the OpenApi title value.'
2873
- },
2874
2875
  namespace: {
2875
2876
  type: "string",
2876
2877
  describe: "The package namespace, if any. If this value is provided the namespace will be added as a prefix to all of the parsed files. If generating an OpenApi definition, it will be added to the file's Server Url."
2877
2878
  },
2878
- openApiFileName: {
2879
- type: "string",
2880
- describe: 'If using "openapi" as the target generator, this allows you to specify the name of the output file.',
2881
- default: "openapi"
2882
- },
2883
2879
  sortMembersAlphabetically: {
2884
2880
  type: "boolean",
2885
2881
  describe: "Whether to sort members alphabetically.",
@@ -2889,6 +2885,11 @@ const markdownOptions = {
2889
2885
  type: "boolean",
2890
2886
  describe: "Whether to include the file's meta.xml information: Whether it is active and and the API version",
2891
2887
  default: defaults.defaults.includeMetadata
2888
+ },
2889
+ documentationRootDir: {
2890
+ type: "string",
2891
+ describe: "The root directory of the documentation. This is used to generate the correct relative paths.",
2892
+ default: defaults.defaults.documentationRootDir
2892
2893
  }
2893
2894
  };
2894
2895
 
@@ -2955,10 +2956,10 @@ function extractArgs() {
2955
2956
  }
2956
2957
 
2957
2958
  function main() {
2958
- function cathError(error) {
2959
+ function catchError(error) {
2959
2960
  console.error(error);
2960
2961
  process.exit(1);
2961
2962
  }
2962
- extractArgs().then((config) => Apexdocs.generate(config).catch(cathError)).catch(cathError);
2963
+ extractArgs().then((config) => Apexdocs.generate(config).catch(catchError)).catch(catchError);
2963
2964
  }
2964
2965
  main();
@@ -0,0 +1,13 @@
1
+ 'use strict';
2
+
3
+ const defaults = {
4
+ targetGenerator: "markdown",
5
+ targetDir: "./docs/",
6
+ scope: ["global"],
7
+ defaultGroupName: "Miscellaneous",
8
+ includeMetadata: false,
9
+ sortMembersAlphabetically: false,
10
+ documentationRootDir: ""
11
+ };
12
+
13
+ exports.defaults = defaults;
package/dist/index.d.ts CHANGED
@@ -19,6 +19,7 @@ type UserDefinedMarkdownConfig = {
19
19
  namespace?: string;
20
20
  sortMembersAlphabetically: boolean;
21
21
  includeMetadata: boolean;
22
+ documentationRootDir: string;
22
23
  } & Partial<ConfigurableHooks>;
23
24
 
24
25
  type SourceFileMetadata = {
@@ -32,8 +33,13 @@ type DocPageReference = {
32
33
  // The name under which the type should be displayed in the documentation.
33
34
  // By default, this will match the source.name, but it can be configured by the user.
34
35
  displayName: string;
35
- // The location of the file relative to the root of the documentation.
36
- pathFromRoot: string;
36
+ // The location where the file will be written.
37
+ outputDocPath: string;
38
+ // The path to the file relative to the documentation root directory. This is used when linking to the file.
39
+ // Usually the value will be the same as outputDocPath. However, some site generators may have a different way of
40
+ // organizing the files, so this allows for the flexibility of having a path from linking that is different from
41
+ // the path where the file is written.
42
+ referencePath: string;
37
43
  };
38
44
 
39
45
  type Frontmatter = string | Record<string, unknown> | null;
@@ -41,13 +47,13 @@ type Frontmatter = string | Record<string, unknown> | null;
41
47
  type ReferenceGuidePageData = {
42
48
  frontmatter: Frontmatter;
43
49
  content: string;
44
- filePath: string;
50
+ outputDocPath: string;
45
51
  };
46
52
 
47
53
  type DocPageData = {
48
54
  source: SourceFileMetadata;
49
55
  group: string | null;
50
- filePath: string;
56
+ outputDocPath: string;
51
57
  frontmatter: Frontmatter;
52
58
  content: string;
53
59
  };
@@ -63,7 +69,7 @@ type Skip = {
63
69
 
64
70
  type ConfigurableDocPageReference = Omit<DocPageReference, 'source'>;
65
71
 
66
- type ConfigurableDocPageData = Omit<DocPageData, 'source' | 'filePath'>;
72
+ type ConfigurableDocPageData = Omit<DocPageData, 'source' | 'outputDocPath'>;
67
73
 
68
74
  /**
69
75
  * Allows changing where the files are written to.
@@ -93,7 +99,7 @@ type TransformDocPage = (
93
99
  doc: DocPageData,
94
100
  ) => Partial<ConfigurableDocPageData> | Promise<Partial<ConfigurableDocPageData>>;
95
101
 
96
- type ConfigurableMarkdownConfig = Omit<SetOptional<UserDefinedMarkdownConfig, 'targetDir' | 'scope' | 'defaultGroupName' | 'includeMetadata' | 'sortMembersAlphabetically'>, 'targetGenerator'>;
102
+ type ConfigurableMarkdownConfig = Omit<SetOptional<UserDefinedMarkdownConfig, 'targetDir' | 'scope' | 'defaultGroupName' | 'includeMetadata' | 'sortMembersAlphabetically' | 'documentationRootDir'>, 'targetGenerator'>;
97
103
  declare function defineMarkdownConfig(config: ConfigurableMarkdownConfig): UserDefinedMarkdownConfig;
98
104
  declare function skip(): Skip;
99
105
 
package/dist/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- var defaults = require('./defaults-DUwru49Q.js');
3
+ var defaults = require('./defaults-jLXD2y8-.js');
4
4
 
5
5
  var __defProp = Object.defineProperty;
6
6
  var __defProps = Object.defineProperties;
@@ -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
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cparra/apexdocs",
3
- "version": "2.25.0-alpha.9",
3
+ "version": "3.0.0-alpha.2",
4
4
  "description": "Library with CLI capabilities to generate documentation for Salesforce Apex classes.",
5
5
  "keywords": [
6
6
  "apex",
@@ -5,9 +5,9 @@ import { PageData } from '../core/shared/types';
5
5
  export class FileWriter {
6
6
  static write(files: PageData[], outputDir: string, onWriteCallback: (file: PageData) => void) {
7
7
  files.forEach((file) => {
8
- const { filePath, content } = this.getTargetLocation(file, outputDir);
9
- fs.mkdirSync(path.dirname(filePath), { recursive: true });
10
- fs.writeFileSync(filePath, content, 'utf8');
8
+ const { outputDocPath, content } = this.getTargetLocation(file, outputDir);
9
+ fs.mkdirSync(path.dirname(outputDocPath), { recursive: true });
10
+ fs.writeFileSync(outputDocPath, content, 'utf8');
11
11
  onWriteCallback(file);
12
12
  });
13
13
  }
@@ -15,7 +15,7 @@ export class FileWriter {
15
15
  private static getTargetLocation(file: PageData, outputDir: string): PageData {
16
16
  return {
17
17
  ...file,
18
- filePath: path.join(outputDir, file.filePath),
18
+ outputDocPath: path.join(outputDir, file.outputDocPath),
19
19
  };
20
20
  }
21
21
  }
@@ -48,7 +48,7 @@ function writeFilesToSystem(files: PostHookDocumentationBundle, outputDir: strin
48
48
  .filter((file) => !isSkip(file)) as PageData[],
49
49
  outputDir,
50
50
  (file: PageData) => {
51
- Logger.logSingle(`${file.filePath} processed.`, false, 'green', false);
51
+ Logger.logSingle(`${file.outputDocPath} processed.`, false, 'green', false);
52
52
  },
53
53
  );
54
54
  }
@@ -19,7 +19,7 @@ export default function openApi(fileBodies: UnparsedSourceFile[], config: UserDe
19
19
  const generatedFiles = processor.fileBuilder().files();
20
20
 
21
21
  FileWriter.write(generatedFiles, config.targetDir, (file: PageData) => {
22
- Logger.logSingle(`${file.filePath} processed.`, false, 'green', false);
22
+ Logger.logSingle(`${file.outputDocPath} processed.`, false, 'green', false);
23
23
  });
24
24
 
25
25
  // Error logging
package/src/cli/args.ts CHANGED
@@ -26,7 +26,7 @@ function _extractYargs(config?: CosmiconfigResult) {
26
26
  .command('markdown', 'Generate documentation from Apex classes as a Markdown site.', (yargs) =>
27
27
  yargs.options(markdownOptions),
28
28
  )
29
- .command('openapi', 'Generate an OpenApi REST specification from Apex classes.')
29
+ .command('openapi', 'Generate an OpenApi REST specification from Apex classes.') // TODO: Add OpenApi specific options
30
30
  .demandCommand()
31
31
  .parseSync();
32
32
  }
@@ -21,30 +21,19 @@ export const markdownOptions: { [key: string]: Options } = {
21
21
  default: defaults.scope,
22
22
  describe:
23
23
  'A list of scopes to document. Values should be separated by a space, e.g --scope global public namespaceaccessible. ' +
24
- 'Annotations are supported and should be passed lowercased and without the @ symbol, e.g. namespaceaccessible auraenabled. ' +
25
- 'Note that this setting is ignored if generating an OpenApi REST specification since that looks for classes annotated with @RestResource.',
24
+ 'Annotations are supported and should be passed lowercased and without the @ symbol, e.g. namespaceaccessible auraenabled.',
26
25
  },
27
26
  defaultGroupName: {
28
27
  type: 'string',
29
28
  default: defaults.defaultGroupName,
30
29
  describe: 'Defines the @group name to be used when a file does not specify it.',
31
30
  },
32
- openApiTitle: {
33
- type: 'string',
34
- default: 'Apex REST Api',
35
- describe: 'If using "openapi" as the target generator, this allows you to specify the OpenApi title value.',
36
- },
37
31
  namespace: {
38
32
  type: 'string',
39
33
  describe:
40
34
  'The package namespace, if any. If this value is provided the namespace will be added as a prefix to all of the parsed files. ' +
41
35
  "If generating an OpenApi definition, it will be added to the file's Server Url.",
42
36
  },
43
- openApiFileName: {
44
- type: 'string',
45
- describe: 'If using "openapi" as the target generator, this allows you to specify the name of the output file.',
46
- default: 'openapi',
47
- },
48
37
  sortMembersAlphabetically: {
49
38
  type: 'boolean',
50
39
  describe: 'Whether to sort members alphabetically.',
@@ -55,4 +44,9 @@ export const markdownOptions: { [key: string]: Options } = {
55
44
  describe: "Whether to include the file's meta.xml information: Whether it is active and and the API version",
56
45
  default: defaults.includeMetadata,
57
46
  },
47
+ documentationRootDir: {
48
+ type: 'string',
49
+ describe: 'The root directory of the documentation. This is used to generate the correct relative paths.',
50
+ default: defaults.documentationRootDir,
51
+ },
58
52
  };
@@ -3,14 +3,14 @@ import { Apexdocs } from '../application/Apexdocs';
3
3
  import { extractArgs } from './args';
4
4
 
5
5
  function main() {
6
- function cathError(error: Error) {
6
+ function catchError(error: Error) {
7
7
  console.error(error);
8
8
  process.exit(1);
9
9
  }
10
10
 
11
11
  extractArgs()
12
- .then((config) => Apexdocs.generate(config).catch(cathError))
13
- .catch(cathError);
12
+ .then((config) => Apexdocs.generate(config).catch(catchError))
13
+ .catch(catchError);
14
14
  }
15
15
 
16
16
  main();
@@ -12,7 +12,7 @@ describe('Generates interface documentation', () => {
12
12
 
13
13
  const result = await generateDocs([apexBundleFromRawString(input)])();
14
14
  expect(result).documentationBundleHasLength(1);
15
- assertEither(result, (data) => expect(data.docs[0].filePath).toContain('MyClass'));
15
+ assertEither(result, (data) => expect(data.docs[0].outputDocPath).toContain('MyClass'));
16
16
  });
17
17
 
18
18
  it('returns the type as class', async () => {
@@ -17,7 +17,7 @@ describe('Generates enum documentation', () => {
17
17
 
18
18
  const result = await generateDocs([apexBundleFromRawString(input)])();
19
19
  expect(result).documentationBundleHasLength(1);
20
- assertEither(result, (data) => expect(data.docs[0].filePath).toContain('MyEnum'));
20
+ assertEither(result, (data) => expect(data.docs[0].outputDocPath).toContain('MyEnum'));
21
21
  });
22
22
 
23
23
  it('returns the type as enum', async () => {
@@ -453,7 +453,9 @@ describe('Generates interface documentation', () => {
453
453
  const result = await generateDocs([apexBundleFromRawString(input1), apexBundleFromRawString(input2)])();
454
454
  expect(result).documentationBundleHasLength(2);
455
455
  assertEither(result, (data) =>
456
- expect(data.docs.find((doc) => doc.filePath.includes('AnotherInterface'))?.content).toContain('Inherited'),
456
+ expect(data.docs.find((doc) => doc.outputDocPath.includes('AnotherInterface'))?.content).toContain(
457
+ 'Inherited',
458
+ ),
457
459
  );
458
460
  });
459
461
  });
@@ -18,5 +18,6 @@ export function generateDocs(apexBundles: UnparsedSourceFile[], config?: Partial
18
18
  sortMembersAlphabetically: true,
19
19
  referenceGuideTemplate: referenceGuideTemplate,
20
20
  ...config,
21
+ documentationRootDir: '',
21
22
  });
22
23
  }
@@ -15,6 +15,7 @@ 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', () => {
@@ -13,10 +13,12 @@ export function parsedFilesToReferenceGuide(
13
13
  }
14
14
 
15
15
  function parsedFileToDocPageReference(config: MarkdownGeneratorConfig, parsedFile: ParsedFile): DocPageReference {
16
+ const path = `${slugify(getTypeGroup(parsedFile.type, config))}/${parsedFile.type.name}.md`;
16
17
  return {
17
18
  source: parsedFile.source,
18
19
  displayName: parsedFile.type.name,
19
- pathFromRoot: `${slugify(getTypeGroup(parsedFile.type, config))}/${parsedFile.type.name}.md`,
20
+ outputDocPath: path,
21
+ referencePath: path,
20
22
  };
21
23
  }
22
24
 
@@ -5,13 +5,14 @@ import { adaptDescribable } from './documentables';
5
5
  import { MarkdownGeneratorConfig } from '../generate-docs';
6
6
  import { apply } from '#utils/fp';
7
7
  import { Type } from '@cparra/apex-reflection';
8
+ import * as path from 'path';
8
9
 
9
10
  export function parsedFilesToRenderableBundle(
10
11
  config: MarkdownGeneratorConfig,
11
12
  parsedFiles: ParsedFile[],
12
13
  references: Record<string, DocPageReference>,
13
14
  ): RenderableBundle {
14
- const referenceFinder = apply(linkGenerator, references);
15
+ const referenceFinder = apply(linkGenerator, references, config.documentationRootDir);
15
16
 
16
17
  function toReferenceGuide(parsedFiles: ParsedFile[]): Record<string, ReferenceGuideReference[]> {
17
18
  return parsedFiles.reduce<Record<string, ReferenceGuideReference[]>>(
@@ -54,11 +55,20 @@ function addToReferenceGuide(
54
55
  };
55
56
  }
56
57
 
57
- const linkGenerator = (references: Record<string, DocPageReference>, referenceName: string): StringOrLink => {
58
+ const linkGenerator = (
59
+ references: Record<string, DocPageReference>,
60
+ documentationRootDir: string,
61
+ referenceName: string,
62
+ ): StringOrLink => {
58
63
  const reference: DocPageReference | undefined = references[referenceName];
64
+
59
65
  return reference
60
66
  ? // Starting the path with a "/" will ensure the link will always be relative to the root of the site.
61
- { __type: 'link', title: reference.displayName, url: `/${reference.pathFromRoot}` }
67
+ {
68
+ __type: 'link',
69
+ title: reference.displayName,
70
+ url: path.join('/', documentationRootDir, reference.referencePath),
71
+ }
62
72
  : referenceName;
63
73
  };
64
74
 
@@ -14,7 +14,7 @@ export const convertToDocumentationBundle = (
14
14
  referenceGuide: {
15
15
  frontmatter: null,
16
16
  content: referencesToReferenceGuideContent(referencesByGroup, referenceGuideTemplate),
17
- filePath: 'index.md',
17
+ outputDocPath: 'index.md',
18
18
  },
19
19
  docs: renderables.map((renderable: Renderable) =>
20
20
  renderableToPageData(Object.values(referencesByGroup).flat(), renderable),
@@ -56,7 +56,7 @@ function renderableToPageData(referenceGuideReference: ReferenceGuideReference[]
56
56
  name: renderable.name,
57
57
  type: renderable.type,
58
58
  },
59
- filePath: reference!.reference.pathFromRoot,
59
+ outputDocPath: reference!.reference.outputDocPath,
60
60
  frontmatter: null,
61
61
  content: docContents,
62
62
  group: renderable.doc.group ?? defaults.defaultGroupName,
@@ -42,6 +42,7 @@ export type MarkdownGeneratorConfig = Pick<
42
42
  | 'transformDocs'
43
43
  | 'transformDocPage'
44
44
  | 'transformReference'
45
+ | 'documentationRootDir'
45
46
  > & {
46
47
  referenceGuideTemplate: string;
47
48
  sortMembersAlphabetically: boolean;
@@ -4,7 +4,7 @@ import { OpenApiPageData } from '../shared/types';
4
4
  export function createOpenApiFile(fileName: string, openApiModel: OpenApi): OpenApiPageData {
5
5
  const content = JSON.stringify({ ...openApiModel, namespace: undefined }, null, 2);
6
6
  return {
7
- filePath: '',
7
+ outputDocPath: '',
8
8
  content,
9
9
  frontmatter: null,
10
10
  group: null,
@@ -21,6 +21,7 @@ export type UserDefinedMarkdownConfig = {
21
21
  namespace?: string;
22
22
  sortMembersAlphabetically: boolean;
23
23
  includeMetadata: boolean;
24
+ documentationRootDir: string;
24
25
  } & Partial<ConfigurableHooks>;
25
26
 
26
27
  export type UserDefinedOpenApiConfig = {
@@ -54,8 +55,13 @@ export type DocPageReference = {
54
55
  // The name under which the type should be displayed in the documentation.
55
56
  // By default, this will match the source.name, but it can be configured by the user.
56
57
  displayName: string;
57
- // The location of the file relative to the root of the documentation.
58
- pathFromRoot: string;
58
+ // The location where the file will be written.
59
+ outputDocPath: string;
60
+ // The path to the file relative to the documentation root directory. This is used when linking to the file.
61
+ // Usually the value will be the same as outputDocPath. However, some site generators may have a different way of
62
+ // organizing the files, so this allows for the flexibility of having a path from linking that is different from
63
+ // the path where the file is written.
64
+ referencePath: string;
59
65
  };
60
66
 
61
67
  type Frontmatter = string | Record<string, unknown> | null;
@@ -63,13 +69,13 @@ type Frontmatter = string | Record<string, unknown> | null;
63
69
  export type ReferenceGuidePageData = {
64
70
  frontmatter: Frontmatter;
65
71
  content: string;
66
- filePath: string;
72
+ outputDocPath: string;
67
73
  };
68
74
 
69
75
  export type DocPageData = {
70
76
  source: SourceFileMetadata;
71
77
  group: string | null;
72
- filePath: string;
78
+ outputDocPath: string;
73
79
  frontmatter: Frontmatter;
74
80
  content: string;
75
81
  };
@@ -99,7 +105,7 @@ export type PostHookDocumentationBundle = {
99
105
 
100
106
  type ConfigurableDocPageReference = Omit<DocPageReference, 'source'>;
101
107
 
102
- type ConfigurableDocPageData = Omit<DocPageData, 'source' | 'filePath'>;
108
+ type ConfigurableDocPageData = Omit<DocPageData, 'source' | 'outputDocPath'>;
103
109
 
104
110
  /**
105
111
  * Allows changing where the files are written to.
package/src/defaults.ts CHANGED
@@ -5,4 +5,5 @@ export const defaults = {
5
5
  defaultGroupName: 'Miscellaneous',
6
6
  includeMetadata: false,
7
7
  sortMembersAlphabetically: false,
8
+ documentationRootDir: '',
8
9
  };
package/src/index.ts CHANGED
@@ -12,7 +12,12 @@ import { defaults } from './defaults';
12
12
  type ConfigurableMarkdownConfig = Omit<
13
13
  SetOptional<
14
14
  UserDefinedMarkdownConfig,
15
- 'targetDir' | 'scope' | 'defaultGroupName' | 'includeMetadata' | 'sortMembersAlphabetically'
15
+ | 'targetDir'
16
+ | 'scope'
17
+ | 'defaultGroupName'
18
+ | 'includeMetadata'
19
+ | 'sortMembersAlphabetically'
20
+ | 'documentationRootDir'
16
21
  >,
17
22
  'targetGenerator'
18
23
  >;