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

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.
@@ -573,13 +573,13 @@ function parsedFilesToRenderableBundle(config, parsedFiles, references) {
573
573
  const referenceFinder = apply(linkGenerator, references, config.documentationRootDir);
574
574
  function toReferenceGuide(parsedFiles2) {
575
575
  return parsedFiles2.reduce(
576
- addToReferenceGuide(referenceFinder, config, references),
576
+ addToReferenceGuide(apply(referenceFinder, "__base__"), config, references),
577
577
  {}
578
578
  );
579
579
  }
580
580
  function toRenderables(parsedFiles2) {
581
581
  return parsedFiles2.reduce((acc, parsedFile) => {
582
- const renderable = typeToRenderable(parsedFile, referenceFinder, config);
582
+ const renderable = typeToRenderable(parsedFile, apply(referenceFinder, parsedFile.source.name), config);
583
583
  acc.push(renderable);
584
584
  return acc;
585
585
  }, []);
@@ -604,16 +604,27 @@ function addToReferenceGuide(findLinkFromHome, config, references) {
604
604
  return acc;
605
605
  };
606
606
  }
607
- const linkGenerator = (references, documentationRootDir, referenceName) => {
608
- const reference = references[referenceName];
609
- return reference ? (
610
- // Starting the path with a "/" will ensure the link will always be relative to the root of the site.
611
- {
607
+ const linkGenerator = (references, documentationRootDir, from, referenceName) => {
608
+ const referenceTo = references[referenceName];
609
+ if (referenceTo && from === "__base__") {
610
+ return {
612
611
  __type: "link",
613
- title: reference.displayName,
614
- url: path__namespace.join("/", documentationRootDir, reference.pathFromRoot)
615
- }
616
- ) : referenceName;
612
+ title: referenceTo.displayName,
613
+ url: path__namespace.join(documentationRootDir, referenceTo.referencePath)
614
+ };
615
+ }
616
+ const referenceFrom = references[from];
617
+ if (!referenceFrom || !referenceTo) {
618
+ return referenceName;
619
+ }
620
+ const fromPath = path__namespace.parse(path__namespace.join("/", documentationRootDir, referenceFrom.referencePath)).dir;
621
+ const toPath = path__namespace.join("/", documentationRootDir, referenceTo.referencePath);
622
+ const relativePath = path__namespace.relative(fromPath, toPath);
623
+ return {
624
+ __type: "link",
625
+ title: referenceTo.displayName,
626
+ url: relativePath
627
+ };
617
628
  };
618
629
  function getTypeGroup$1(type, config) {
619
630
  var _a, _b;
@@ -1198,7 +1209,7 @@ const convertToDocumentationBundle = (referenceGuideTemplate, { referencesByGrou
1198
1209
  referenceGuide: {
1199
1210
  frontmatter: null,
1200
1211
  content: referencesToReferenceGuideContent(referencesByGroup, referenceGuideTemplate),
1201
- filePath: "index.md"
1212
+ outputDocPath: "index.md"
1202
1213
  },
1203
1214
  docs: renderables.map(
1204
1215
  (renderable) => renderableToPageData(Object.values(referencesByGroup).flat(), renderable)
@@ -1232,7 +1243,7 @@ function renderableToPageData(referenceGuideReference, renderable) {
1232
1243
  name: renderable2.name,
1233
1244
  type: renderable2.type
1234
1245
  },
1235
- filePath: reference.reference.pathFromRoot,
1246
+ outputDocPath: reference.reference.outputDocPath,
1236
1247
  frontmatter: null,
1237
1248
  content: docContents,
1238
1249
  group: (_a = renderable2.doc.group) != null ? _a : defaults.defaults.defaultGroupName
@@ -1450,10 +1461,12 @@ function parsedFilesToReferenceGuide(config, parsedFiles) {
1450
1461
  }, {});
1451
1462
  }
1452
1463
  function parsedFileToDocPageReference(config, parsedFile) {
1464
+ const path = `${slugify(getTypeGroup(parsedFile.type, config))}/${parsedFile.type.name}.md`;
1453
1465
  return {
1454
1466
  source: parsedFile.source,
1455
1467
  displayName: parsedFile.type.name,
1456
- pathFromRoot: `${slugify(getTypeGroup(parsedFile.type, config))}/${parsedFile.type.name}.md`
1468
+ outputDocPath: path,
1469
+ referencePath: path
1457
1470
  };
1458
1471
  }
1459
1472
  function getTypeGroup(type, config) {
@@ -1645,15 +1658,15 @@ var __spreadProps$6 = (a, b) => __defProps$6(a, __getOwnPropDescs$6(b));
1645
1658
  class FileWriter {
1646
1659
  static write(files, outputDir, onWriteCallback) {
1647
1660
  files.forEach((file) => {
1648
- const { filePath, content } = this.getTargetLocation(file, outputDir);
1649
- fs__namespace.mkdirSync(path__namespace.dirname(filePath), { recursive: true });
1650
- fs__namespace.writeFileSync(filePath, content, "utf8");
1661
+ const { outputDocPath, content } = this.getTargetLocation(file, outputDir);
1662
+ fs__namespace.mkdirSync(path__namespace.dirname(outputDocPath), { recursive: true });
1663
+ fs__namespace.writeFileSync(outputDocPath, content, "utf8");
1651
1664
  onWriteCallback(file);
1652
1665
  });
1653
1666
  }
1654
1667
  static getTargetLocation(file, outputDir) {
1655
1668
  return __spreadProps$6(__spreadValues$6({}, file), {
1656
- filePath: path__namespace.join(outputDir, file.filePath)
1669
+ outputDocPath: path__namespace.join(outputDir, file.outputDocPath)
1657
1670
  });
1658
1671
  }
1659
1672
  }
@@ -1769,7 +1782,7 @@ function writeFilesToSystem(files, outputDir) {
1769
1782
  [files.referenceGuide, ...files.docs].filter((file) => !isSkip(file)),
1770
1783
  outputDir,
1771
1784
  (file) => {
1772
- Logger.logSingle(`${file.filePath} processed.`, false, "green", false);
1785
+ Logger.logSingle(`${file.outputDocPath} processed.`, false, "green", false);
1773
1786
  }
1774
1787
  );
1775
1788
  }
@@ -2654,7 +2667,7 @@ var __spreadProps$1 = (a, b) => __defProps$1(a, __getOwnPropDescs$1(b));
2654
2667
  function createOpenApiFile(fileName, openApiModel) {
2655
2668
  const content = JSON.stringify(__spreadProps$1(__spreadValues$1({}, openApiModel), { namespace: void 0 }), null, 2);
2656
2669
  return {
2657
- filePath: "",
2670
+ outputDocPath: "",
2658
2671
  content,
2659
2672
  frontmatter: null,
2660
2673
  group: null
@@ -2727,7 +2740,7 @@ function openApi(fileBodies, config) {
2727
2740
  Transpiler.generate(filteredTypes, processor);
2728
2741
  const generatedFiles = processor.fileBuilder().files();
2729
2742
  FileWriter.write(generatedFiles, config.targetDir, (file) => {
2730
- Logger.logSingle(`${file.filePath} processed.`, false, "green", false);
2743
+ Logger.logSingle(`${file.outputDocPath} processed.`, false, "green", false);
2731
2744
  });
2732
2745
  ErrorLogger.logErrors(filteredTypes);
2733
2746
  }
@@ -2886,7 +2899,7 @@ const markdownOptions = {
2886
2899
  },
2887
2900
  documentationRootDir: {
2888
2901
  type: "string",
2889
- describe: "The root directory of the documentation. This is used to generate the correct relative paths.",
2902
+ describe: "The root directory of the documentation. This is used to create the correct relative paths when generating links between documents.",
2890
2903
  default: defaults.defaults.documentationRootDir
2891
2904
  }
2892
2905
  };
package/dist/index.d.ts CHANGED
@@ -33,8 +33,13 @@ type DocPageReference = {
33
33
  // The name under which the type should be displayed in the documentation.
34
34
  // By default, this will match the source.name, but it can be configured by the user.
35
35
  displayName: string;
36
- // The location of the file relative to the root of the documentation.
37
- 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;
38
43
  };
39
44
 
40
45
  type Frontmatter = string | Record<string, unknown> | null;
@@ -42,13 +47,13 @@ type Frontmatter = string | Record<string, unknown> | null;
42
47
  type ReferenceGuidePageData = {
43
48
  frontmatter: Frontmatter;
44
49
  content: string;
45
- filePath: string;
50
+ outputDocPath: string;
46
51
  };
47
52
 
48
53
  type DocPageData = {
49
54
  source: SourceFileMetadata;
50
55
  group: string | null;
51
- filePath: string;
56
+ outputDocPath: string;
52
57
  frontmatter: Frontmatter;
53
58
  content: string;
54
59
  };
@@ -64,7 +69,7 @@ type Skip = {
64
69
 
65
70
  type ConfigurableDocPageReference = Omit<DocPageReference, 'source'>;
66
71
 
67
- type ConfigurableDocPageData = Omit<DocPageData, 'source' | 'filePath'>;
72
+ type ConfigurableDocPageData = Omit<DocPageData, 'source' | 'outputDocPath'>;
68
73
 
69
74
  /**
70
75
  * Allows changing where the files are written to.
@@ -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.3",
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
@@ -46,7 +46,8 @@ export const markdownOptions: { [key: string]: Options } = {
46
46
  },
47
47
  documentationRootDir: {
48
48
  type: 'string',
49
- describe: 'The root directory of the documentation. This is used to generate the correct relative paths.',
49
+ describe:
50
+ 'The root directory of the documentation. This is used to create the correct relative paths when generating links between documents.',
50
51
  default: defaults.documentationRootDir,
51
52
  },
52
53
  };
@@ -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
  });
@@ -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
 
@@ -16,14 +16,14 @@ export function parsedFilesToRenderableBundle(
16
16
 
17
17
  function toReferenceGuide(parsedFiles: ParsedFile[]): Record<string, ReferenceGuideReference[]> {
18
18
  return parsedFiles.reduce<Record<string, ReferenceGuideReference[]>>(
19
- addToReferenceGuide(referenceFinder, config, references),
19
+ addToReferenceGuide(apply(referenceFinder, '__base__'), config, references),
20
20
  {},
21
21
  );
22
22
  }
23
23
 
24
24
  function toRenderables(parsedFiles: ParsedFile[]): Renderable[] {
25
25
  return parsedFiles.reduce<Renderable[]>((acc, parsedFile) => {
26
- const renderable = typeToRenderable(parsedFile, referenceFinder, config);
26
+ const renderable = typeToRenderable(parsedFile, apply(referenceFinder, parsedFile.source.name), config);
27
27
  acc.push(renderable);
28
28
  return acc;
29
29
  }, []);
@@ -58,18 +58,38 @@ function addToReferenceGuide(
58
58
  const linkGenerator = (
59
59
  references: Record<string, DocPageReference>,
60
60
  documentationRootDir: string,
61
+ from: string, // The name of the file for which the reference is being generated
61
62
  referenceName: string,
62
63
  ): StringOrLink => {
63
- const reference: DocPageReference | undefined = references[referenceName];
64
+ const referenceTo: DocPageReference | undefined = references[referenceName];
65
+ // When linking from the base path (e.g. the reference guide/index page), the reference path is the same as the output
66
+ // path.
67
+ if (referenceTo && from === '__base__') {
68
+ return {
69
+ __type: 'link',
70
+ title: referenceTo.displayName,
71
+ url: path.join(documentationRootDir, referenceTo.referencePath),
72
+ };
73
+ }
74
+
75
+ const referenceFrom: DocPageReference | undefined = references[from];
76
+
77
+ if (!referenceFrom || !referenceTo) {
78
+ return referenceName;
79
+ }
64
80
 
65
- return reference
66
- ? // Starting the path with a "/" will ensure the link will always be relative to the root of the site.
67
- {
68
- __type: 'link',
69
- title: reference.displayName,
70
- url: path.join('/', documentationRootDir, reference.pathFromRoot),
71
- }
72
- : referenceName;
81
+ // Gets the directory of the file that is being linked from.
82
+ // This is used to calculate the relative path to the file
83
+ // being linked to.
84
+ const fromPath = path.parse(path.join('/', documentationRootDir, referenceFrom.referencePath)).dir;
85
+ const toPath = path.join('/', documentationRootDir, referenceTo.referencePath);
86
+ const relativePath = path.relative(fromPath, toPath);
87
+
88
+ return {
89
+ __type: 'link',
90
+ title: referenceTo.displayName,
91
+ url: relativePath,
92
+ };
73
93
  };
74
94
 
75
95
  function getTypeGroup(type: Type, config: MarkdownGeneratorConfig): string {
@@ -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,
@@ -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,
@@ -55,8 +55,13 @@ export type DocPageReference = {
55
55
  // The name under which the type should be displayed in the documentation.
56
56
  // By default, this will match the source.name, but it can be configured by the user.
57
57
  displayName: string;
58
- // The location of the file relative to the root of the documentation.
59
- 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;
60
65
  };
61
66
 
62
67
  type Frontmatter = string | Record<string, unknown> | null;
@@ -64,13 +69,13 @@ type Frontmatter = string | Record<string, unknown> | null;
64
69
  export type ReferenceGuidePageData = {
65
70
  frontmatter: Frontmatter;
66
71
  content: string;
67
- filePath: string;
72
+ outputDocPath: string;
68
73
  };
69
74
 
70
75
  export type DocPageData = {
71
76
  source: SourceFileMetadata;
72
77
  group: string | null;
73
- filePath: string;
78
+ outputDocPath: string;
74
79
  frontmatter: Frontmatter;
75
80
  content: string;
76
81
  };
@@ -100,7 +105,7 @@ export type PostHookDocumentationBundle = {
100
105
 
101
106
  type ConfigurableDocPageReference = Omit<DocPageReference, 'source'>;
102
107
 
103
- type ConfigurableDocPageData = Omit<DocPageData, 'source' | 'filePath'>;
108
+ type ConfigurableDocPageData = Omit<DocPageData, 'source' | 'outputDocPath'>;
104
109
 
105
110
  /**
106
111
  * Allows changing where the files are written to.