@cparra/apexdocs 3.0.0-alpha.3 → 3.0.0-alpha.5
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.
- package/dist/cli/generate.js +92 -63
- package/dist/defaults-DGKfeZq-.js +13 -0
- package/dist/index.d.ts +13 -2
- package/dist/index.js +1 -1
- package/examples/markdown/docs/miscellaneous/MultiInheritanceClass.md +1 -1
- package/examples/markdown/docs/miscellaneous/SampleInterface.md +12 -8
- package/examples/markdown/docs/miscellaneous/Url.md +3 -3
- package/examples/markdown/force-app/classes/SampleInterface.cls +4 -0
- package/examples/vitepress/docs/miscellaneous/BaseClass.md +1 -1
- package/package.json +2 -2
- package/src/application/Apexdocs.ts +15 -9
- package/src/application/generators/markdown.ts +3 -2
- package/src/application/generators/openapi.ts +3 -4
- package/src/cli/commands/markdown.ts +4 -4
- package/src/core/markdown/__test__/generating-class-docs.spec.ts +2 -4
- package/src/core/markdown/__test__/generating-enum-docs.spec.ts +2 -2
- package/src/core/markdown/__test__/generating-interface-docs.spec.ts +2 -4
- package/src/core/markdown/__test__/generating-reference-guide.spec.ts +3 -3
- package/src/core/markdown/__test__/test-helpers.ts +1 -1
- package/src/core/markdown/adapters/__tests__/interface-adapter.spec.ts +1 -1
- package/src/core/markdown/adapters/__tests__/link-generator.spec.ts +130 -0
- package/src/core/markdown/adapters/generate-link.ts +82 -0
- package/src/core/markdown/adapters/renderable-bundle.ts +3 -40
- package/src/core/markdown/generate-docs.ts +1 -1
- package/src/core/openapi/open-api-docs-processor.ts +1 -1
- package/src/core/shared/types.d.ts +12 -1
- package/src/defaults.ts +1 -1
- package/src/index.ts +1 -6
- package/src/util/logger.ts +19 -21
package/dist/cli/generate.js
CHANGED
|
@@ -10,10 +10,10 @@ var apexReflection = require('@cparra/apex-reflection');
|
|
|
10
10
|
var O = require('fp-ts/Option');
|
|
11
11
|
var fastXmlParser = require('fast-xml-parser');
|
|
12
12
|
var Handlebars = require('handlebars');
|
|
13
|
-
var defaults = require('../defaults-
|
|
13
|
+
var defaults = require('../defaults-DGKfeZq-.js');
|
|
14
14
|
var fs = require('fs');
|
|
15
15
|
var chalk = require('chalk');
|
|
16
|
-
var
|
|
16
|
+
var ora = require('ora');
|
|
17
17
|
var cosmiconfig = require('cosmiconfig');
|
|
18
18
|
var yargs = require('yargs');
|
|
19
19
|
var cosmiconfigTypescriptLoader = require('cosmiconfig-typescript-loader');
|
|
@@ -569,8 +569,59 @@ function singleGroup(headingLevel, groupName, adapter, members, linkGenerator) {
|
|
|
569
569
|
};
|
|
570
570
|
}
|
|
571
571
|
|
|
572
|
+
const generateLink = (strategy) => {
|
|
573
|
+
switch (strategy) {
|
|
574
|
+
case "relative":
|
|
575
|
+
return generateRelativeLink;
|
|
576
|
+
case "no-link":
|
|
577
|
+
return generateNoLink;
|
|
578
|
+
case "none":
|
|
579
|
+
return returnReferenceAsIs;
|
|
580
|
+
}
|
|
581
|
+
};
|
|
582
|
+
const generateRelativeLink = (references, from, referenceName) => {
|
|
583
|
+
function getRelativePath(fromPath, toPath) {
|
|
584
|
+
return path.relative(path.parse(path.join("/", fromPath)).dir, path.join("/", toPath));
|
|
585
|
+
}
|
|
586
|
+
const referenceTo = references[referenceName];
|
|
587
|
+
if (!referenceTo) {
|
|
588
|
+
return referenceName;
|
|
589
|
+
}
|
|
590
|
+
if (referenceTo && from === "__base__") {
|
|
591
|
+
return {
|
|
592
|
+
__type: "link",
|
|
593
|
+
title: referenceTo.displayName,
|
|
594
|
+
url: getRelativePath("", referenceTo.referencePath)
|
|
595
|
+
};
|
|
596
|
+
}
|
|
597
|
+
const referenceFrom = references[from];
|
|
598
|
+
if (!referenceFrom) {
|
|
599
|
+
return referenceTo.displayName;
|
|
600
|
+
}
|
|
601
|
+
return {
|
|
602
|
+
__type: "link",
|
|
603
|
+
title: referenceTo.displayName,
|
|
604
|
+
url: getRelativePath(referenceFrom.referencePath, referenceTo.referencePath)
|
|
605
|
+
};
|
|
606
|
+
};
|
|
607
|
+
const generateNoLink = (references, _from, referenceName) => {
|
|
608
|
+
const referenceTo = references[referenceName];
|
|
609
|
+
return referenceTo ? referenceTo.displayName : referenceName;
|
|
610
|
+
};
|
|
611
|
+
const returnReferenceAsIs = (references, _from, referenceName) => {
|
|
612
|
+
const referenceTo = references[referenceName];
|
|
613
|
+
if (!referenceTo) {
|
|
614
|
+
return referenceName;
|
|
615
|
+
}
|
|
616
|
+
return {
|
|
617
|
+
__type: "link",
|
|
618
|
+
title: referenceTo.displayName,
|
|
619
|
+
url: referenceTo.referencePath
|
|
620
|
+
};
|
|
621
|
+
};
|
|
622
|
+
|
|
572
623
|
function parsedFilesToRenderableBundle(config, parsedFiles, references) {
|
|
573
|
-
const referenceFinder = apply(
|
|
624
|
+
const referenceFinder = apply(generateLink(config.linkingStrategy), references);
|
|
574
625
|
function toReferenceGuide(parsedFiles2) {
|
|
575
626
|
return parsedFiles2.reduce(
|
|
576
627
|
addToReferenceGuide(apply(referenceFinder, "__base__"), config, references),
|
|
@@ -604,28 +655,6 @@ function addToReferenceGuide(findLinkFromHome, config, references) {
|
|
|
604
655
|
return acc;
|
|
605
656
|
};
|
|
606
657
|
}
|
|
607
|
-
const linkGenerator = (references, documentationRootDir, from, referenceName) => {
|
|
608
|
-
const referenceTo = references[referenceName];
|
|
609
|
-
if (referenceTo && from === "__base__") {
|
|
610
|
-
return {
|
|
611
|
-
__type: "link",
|
|
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
|
-
};
|
|
628
|
-
};
|
|
629
658
|
function getTypeGroup$1(type, config) {
|
|
630
659
|
var _a, _b;
|
|
631
660
|
const groupAnnotation = (_a = type.docComment) == null ? void 0 : _a.annotations.find((annotation) => annotation.name.toLowerCase() === "group");
|
|
@@ -1689,36 +1718,32 @@ class Logger {
|
|
|
1689
1718
|
* @param args Optional arguments.
|
|
1690
1719
|
*/
|
|
1691
1720
|
static error(message, ...args) {
|
|
1692
|
-
this.logSingle(message,
|
|
1721
|
+
this.logSingle(message, "red");
|
|
1693
1722
|
args.forEach(() => {
|
|
1694
|
-
this.logSingle(message,
|
|
1723
|
+
this.logSingle(message, "red");
|
|
1695
1724
|
});
|
|
1696
1725
|
}
|
|
1697
|
-
static logSingle(text,
|
|
1726
|
+
static logSingle(text, color = "green") {
|
|
1698
1727
|
if (this.currentFrame > 9) {
|
|
1699
1728
|
this.currentFrame = 0;
|
|
1700
1729
|
}
|
|
1701
|
-
const
|
|
1702
|
-
let logMessage;
|
|
1703
|
-
if (color === "green") {
|
|
1704
|
-
logMessage = `${chalk.green((/* @__PURE__ */ new Date()).toLocaleString() + ": ")}${text}
|
|
1730
|
+
const logMessage = `${this.getChalkFn(color)((/* @__PURE__ */ new Date()).toLocaleString() + ": ")}${text}
|
|
1705
1731
|
`;
|
|
1706
|
-
|
|
1707
|
-
|
|
1708
|
-
|
|
1709
|
-
|
|
1710
|
-
if (overrideConsole) {
|
|
1711
|
-
logUpdate(`${spinner} ${logMessage}`);
|
|
1712
|
-
} else {
|
|
1713
|
-
process.stdout.write(`${spinner} ${logMessage}`);
|
|
1714
|
-
}
|
|
1732
|
+
process.stdout.write(logMessage);
|
|
1733
|
+
}
|
|
1734
|
+
static getChalkFn(color) {
|
|
1735
|
+
return color === "green" ? chalk.green : chalk.red;
|
|
1715
1736
|
}
|
|
1716
|
-
static
|
|
1717
|
-
|
|
1737
|
+
static startSpinner(text) {
|
|
1738
|
+
this.spinner.text = text;
|
|
1739
|
+
this.spinner.start();
|
|
1740
|
+
}
|
|
1741
|
+
static succeedSpinner(text) {
|
|
1742
|
+
this.spinner.succeed(text);
|
|
1718
1743
|
}
|
|
1719
1744
|
}
|
|
1720
1745
|
Logger.currentFrame = 0;
|
|
1721
|
-
Logger.
|
|
1746
|
+
Logger.spinner = ora();
|
|
1722
1747
|
|
|
1723
1748
|
const referenceGuideTemplate = `
|
|
1724
1749
|
# Apex Reference Guide
|
|
@@ -1781,8 +1806,7 @@ function writeFilesToSystem(files, outputDir) {
|
|
|
1781
1806
|
FileWriter.write(
|
|
1782
1807
|
[files.referenceGuide, ...files.docs].filter((file) => !isSkip(file)),
|
|
1783
1808
|
outputDir,
|
|
1784
|
-
(
|
|
1785
|
-
Logger.logSingle(`${file.outputDocPath} processed.`, false, "green", false);
|
|
1809
|
+
() => {
|
|
1786
1810
|
}
|
|
1787
1811
|
);
|
|
1788
1812
|
}
|
|
@@ -2692,7 +2716,7 @@ class OpenApiDocsProcessor {
|
|
|
2692
2716
|
}
|
|
2693
2717
|
onProcess(type) {
|
|
2694
2718
|
var _a, _b;
|
|
2695
|
-
Logger.logSingle(`Processing ${type.name}`,
|
|
2719
|
+
Logger.logSingle(`Processing ${type.name}`, "green");
|
|
2696
2720
|
const endpointPath = this.getEndpointPath(type);
|
|
2697
2721
|
if (!endpointPath) {
|
|
2698
2722
|
return;
|
|
@@ -2740,7 +2764,7 @@ function openApi(fileBodies, config) {
|
|
|
2740
2764
|
Transpiler.generate(filteredTypes, processor);
|
|
2741
2765
|
const generatedFiles = processor.fileBuilder().files();
|
|
2742
2766
|
FileWriter.write(generatedFiles, config.targetDir, (file) => {
|
|
2743
|
-
Logger.logSingle(`${file.outputDocPath} processed.`,
|
|
2767
|
+
Logger.logSingle(`${file.outputDocPath} processed.`, "green");
|
|
2744
2768
|
});
|
|
2745
2769
|
ErrorLogger.logErrors(filteredTypes);
|
|
2746
2770
|
}
|
|
@@ -2762,9 +2786,8 @@ function filterByScopes(manifest) {
|
|
|
2762
2786
|
"httpput"
|
|
2763
2787
|
]);
|
|
2764
2788
|
const filteredLogMessage = `Filtered ${manifest.types.length - filteredTypes.length} file(s), only keeping classes annotated as @RestResource.`;
|
|
2765
|
-
Logger.
|
|
2766
|
-
Logger.logSingle(
|
|
2767
|
-
Logger.logSingle(`Creating documentation for ${filteredTypes.length} file(s)`, false, "green", false);
|
|
2789
|
+
Logger.logSingle(filteredLogMessage, "green");
|
|
2790
|
+
Logger.logSingle(`Creating documentation for ${filteredTypes.length} file(s)`, "green");
|
|
2768
2791
|
return filteredTypes;
|
|
2769
2792
|
}
|
|
2770
2793
|
|
|
@@ -2844,15 +2867,20 @@ class Apexdocs {
|
|
|
2844
2867
|
*/
|
|
2845
2868
|
static generate(config) {
|
|
2846
2869
|
return __async$1(this, null, function* () {
|
|
2847
|
-
Logger.logSingle("Initializing..."
|
|
2848
|
-
|
|
2849
|
-
|
|
2850
|
-
|
|
2851
|
-
|
|
2852
|
-
|
|
2853
|
-
|
|
2854
|
-
|
|
2855
|
-
|
|
2870
|
+
Logger.logSingle("Initializing...");
|
|
2871
|
+
Logger.startSpinner("Processing files...");
|
|
2872
|
+
try {
|
|
2873
|
+
const fileBodies = ApexFileReader.processFiles(new DefaultFileSystem(), config.sourceDir, config.includeMetadata);
|
|
2874
|
+
switch (config.targetGenerator) {
|
|
2875
|
+
case "markdown":
|
|
2876
|
+
yield generate(fileBodies, config);
|
|
2877
|
+
break;
|
|
2878
|
+
case "openapi":
|
|
2879
|
+
openApi(fileBodies, config);
|
|
2880
|
+
break;
|
|
2881
|
+
}
|
|
2882
|
+
} finally {
|
|
2883
|
+
Logger.succeedSpinner("Files processed.");
|
|
2856
2884
|
}
|
|
2857
2885
|
});
|
|
2858
2886
|
}
|
|
@@ -2897,10 +2925,11 @@ const markdownOptions = {
|
|
|
2897
2925
|
describe: "Whether to include the file's meta.xml information: Whether it is active and and the API version",
|
|
2898
2926
|
default: defaults.defaults.includeMetadata
|
|
2899
2927
|
},
|
|
2900
|
-
|
|
2928
|
+
linkingStrategy: {
|
|
2901
2929
|
type: "string",
|
|
2902
|
-
describe: "The
|
|
2903
|
-
|
|
2930
|
+
describe: "The strategy to use when linking to other documentation pages.",
|
|
2931
|
+
choices: ["relative", "no-link", "none"],
|
|
2932
|
+
default: defaults.defaults.linkingStrategy
|
|
2904
2933
|
}
|
|
2905
2934
|
};
|
|
2906
2935
|
|
|
@@ -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
|
+
linkingStrategy: "relative"
|
|
11
|
+
};
|
|
12
|
+
|
|
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
|
-
|
|
33
|
+
linkingStrategy: LinkingStrategy;
|
|
23
34
|
} & Partial<ConfigurableHooks>;
|
|
24
35
|
|
|
25
36
|
type SourceFileMetadata = {
|
|
@@ -99,7 +110,7 @@ type TransformDocPage = (
|
|
|
99
110
|
doc: DocPageData,
|
|
100
111
|
) => Partial<ConfigurableDocPageData> | Promise<Partial<ConfigurableDocPageData>>;
|
|
101
112
|
|
|
102
|
-
type ConfigurableMarkdownConfig = Omit<SetOptional<UserDefinedMarkdownConfig, 'targetDir' | 'scope' | 'defaultGroupName' | 'includeMetadata' | 'sortMembersAlphabetically' | '
|
|
113
|
+
type ConfigurableMarkdownConfig = Omit<SetOptional<UserDefinedMarkdownConfig, 'targetDir' | 'scope' | 'defaultGroupName' | 'includeMetadata' | 'sortMembersAlphabetically' | 'linkingStrategy'>, 'targetGenerator'>;
|
|
103
114
|
declare function defineMarkdownConfig(config: ConfigurableMarkdownConfig): UserDefinedMarkdownConfig;
|
|
104
115
|
declare function skip(): Skip;
|
|
105
116
|
|
package/dist/index.js
CHANGED
|
@@ -6,10 +6,12 @@ This is a sample interface
|
|
|
6
6
|
|
|
7
7
|
**Mermaid**
|
|
8
8
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
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 -->|extends| D[GreatGrandParentInterface]
|
|
|
17
19
|
|
|
18
20
|
**See** [SampleEnum](../sample-enums/SampleEnum.md)
|
|
19
21
|
|
|
20
|
-
**See** [ReferencedEnum](
|
|
22
|
+
**See** [ReferencedEnum](ReferencedEnum.md)
|
|
21
23
|
|
|
22
24
|
## Namespace
|
|
23
25
|
ns
|
|
24
26
|
|
|
25
27
|
## Example
|
|
26
|
-
|
|
28
|
+
```apex
|
|
29
|
+
SampleInterface sampleInterface = new SampleInterface();
|
|
27
30
|
sampleInterface.sampleMethod();
|
|
31
|
+
```
|
|
28
32
|
|
|
29
33
|
**Extends**
|
|
30
|
-
[ParentInterface](
|
|
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](
|
|
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](
|
|
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](
|
|
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](
|
|
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 {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cparra/apexdocs",
|
|
3
|
-
"version": "3.0.0-alpha.
|
|
3
|
+
"version": "3.0.0-alpha.5",
|
|
4
4
|
"description": "Library with CLI capabilities to generate documentation for Salesforce Apex classes.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"apex",
|
|
@@ -68,7 +68,7 @@
|
|
|
68
68
|
"fp-ts": "^2.16.8",
|
|
69
69
|
"handlebars": "^4.7.8",
|
|
70
70
|
"js-yaml": "^4.1.0",
|
|
71
|
-
"
|
|
71
|
+
"ora": "^5.4.1",
|
|
72
72
|
"type-fest": "^4.23.0",
|
|
73
73
|
"yargs": "^17.7.2"
|
|
74
74
|
},
|
|
@@ -14,17 +14,23 @@ export class Apexdocs {
|
|
|
14
14
|
* Generates documentation out of Apex source files.
|
|
15
15
|
*/
|
|
16
16
|
static async generate(config: UserDefinedConfig): Promise<void> {
|
|
17
|
-
Logger.logSingle('Initializing...'
|
|
17
|
+
Logger.logSingle('Initializing...');
|
|
18
|
+
Logger.startSpinner('Processing files...');
|
|
18
19
|
|
|
19
|
-
|
|
20
|
+
try {
|
|
21
|
+
const fileBodies = ApexFileReader.processFiles(new DefaultFileSystem(), config.sourceDir, config.includeMetadata);
|
|
20
22
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
23
|
+
switch (config.targetGenerator) {
|
|
24
|
+
case 'markdown':
|
|
25
|
+
await markdown(fileBodies, config);
|
|
26
|
+
break;
|
|
27
|
+
case 'openapi':
|
|
28
|
+
openApi(fileBodies, config);
|
|
29
|
+
break;
|
|
30
|
+
}
|
|
31
|
+
} finally {
|
|
32
|
+
// TODO: Allow for failures
|
|
33
|
+
Logger.succeedSpinner('Files processed.');
|
|
28
34
|
}
|
|
29
35
|
}
|
|
30
36
|
}
|
|
@@ -47,8 +47,9 @@ function writeFilesToSystem(files: PostHookDocumentationBundle, outputDir: strin
|
|
|
47
47
|
// Filter out any files that should be skipped
|
|
48
48
|
.filter((file) => !isSkip(file)) as PageData[],
|
|
49
49
|
outputDir,
|
|
50
|
-
(
|
|
51
|
-
|
|
50
|
+
() => {
|
|
51
|
+
// TODO: Don't do this here, send things back up.
|
|
52
|
+
//Logger.logSingle(`${file.outputDocPath} processed.`, 'green');
|
|
52
53
|
},
|
|
53
54
|
);
|
|
54
55
|
}
|
|
@@ -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.outputDocPath} processed.`,
|
|
22
|
+
Logger.logSingle(`${file.outputDocPath} processed.`, 'green');
|
|
23
23
|
});
|
|
24
24
|
|
|
25
25
|
// Error logging
|
|
@@ -48,9 +48,8 @@ function filterByScopes(manifest: Manifest) {
|
|
|
48
48
|
const filteredLogMessage = `Filtered ${
|
|
49
49
|
manifest.types.length - filteredTypes.length
|
|
50
50
|
} file(s), only keeping classes annotated as @RestResource.`;
|
|
51
|
-
Logger.clear();
|
|
52
51
|
|
|
53
|
-
Logger.logSingle(filteredLogMessage,
|
|
54
|
-
Logger.logSingle(`Creating documentation for ${filteredTypes.length} file(s)`,
|
|
52
|
+
Logger.logSingle(filteredLogMessage, 'green');
|
|
53
|
+
Logger.logSingle(`Creating documentation for ${filteredTypes.length} file(s)`, 'green');
|
|
55
54
|
return filteredTypes;
|
|
56
55
|
}
|
|
@@ -44,10 +44,10 @@ export const markdownOptions: { [key: string]: Options } = {
|
|
|
44
44
|
describe: "Whether to include the file's meta.xml information: Whether it is active and and the API version",
|
|
45
45
|
default: defaults.includeMetadata,
|
|
46
46
|
},
|
|
47
|
-
|
|
47
|
+
linkingStrategy: {
|
|
48
48
|
type: 'string',
|
|
49
|
-
describe:
|
|
50
|
-
|
|
51
|
-
default: defaults.
|
|
49
|
+
describe: 'The strategy to use when linking to other documentation pages.',
|
|
50
|
+
choices: ['relative', 'no-link', 'none'],
|
|
51
|
+
default: defaults.linkingStrategy,
|
|
52
52
|
},
|
|
53
53
|
};
|
|
@@ -268,9 +268,7 @@ describe('Generates interface documentation', () => {
|
|
|
268
268
|
const result = await generateDocs([apexBundleFromRawString(input1), apexBundleFromRawString(input2)])();
|
|
269
269
|
expect(result).documentationBundleHasLength(2);
|
|
270
270
|
assertEither(result, (data) =>
|
|
271
|
-
expect(data).firstDocContains(
|
|
272
|
-
'This is a description with a [ClassRef](/miscellaneous/ClassRef.md) reference',
|
|
273
|
-
),
|
|
271
|
+
expect(data).firstDocContains('This is a description with a [ClassRef](ClassRef.md) reference'),
|
|
274
272
|
);
|
|
275
273
|
});
|
|
276
274
|
|
|
@@ -304,7 +302,7 @@ describe('Generates interface documentation', () => {
|
|
|
304
302
|
const result = await generateDocs([apexBundleFromRawString(input1), apexBundleFromRawString(input2)])();
|
|
305
303
|
expect(result).documentationBundleHasLength(2);
|
|
306
304
|
assertEither(result, (data) => expect(data).firstDocContains('See'));
|
|
307
|
-
assertEither(result, (data) => expect(data).firstDocContains('[ClassRef](
|
|
305
|
+
assertEither(result, (data) => expect(data).firstDocContains('[ClassRef](ClassRef.md)'));
|
|
308
306
|
});
|
|
309
307
|
|
|
310
308
|
it('displays sees without links when the reference is not found', async () => {
|
|
@@ -211,7 +211,7 @@ describe('Generates enum documentation', () => {
|
|
|
211
211
|
expect(result).documentationBundleHasLength(2);
|
|
212
212
|
assertEither(result, (data) => expect(data).firstDocContains('Description'));
|
|
213
213
|
assertEither(result, (data) =>
|
|
214
|
-
expect(data).firstDocContains('This is a description with a [EnumRef](
|
|
214
|
+
expect(data).firstDocContains('This is a description with a [EnumRef](EnumRef.md) reference'),
|
|
215
215
|
);
|
|
216
216
|
});
|
|
217
217
|
|
|
@@ -245,7 +245,7 @@ describe('Generates enum documentation', () => {
|
|
|
245
245
|
const result = await generateDocs([apexBundleFromRawString(input1), apexBundleFromRawString(input2)])();
|
|
246
246
|
expect(result).documentationBundleHasLength(2);
|
|
247
247
|
assertEither(result, (data) => expect(data).firstDocContains('See'));
|
|
248
|
-
assertEither(result, (data) => expect(data).firstDocContains('[EnumRef](
|
|
248
|
+
assertEither(result, (data) => expect(data).firstDocContains('[EnumRef](EnumRef.md)'));
|
|
249
249
|
});
|
|
250
250
|
|
|
251
251
|
it('displays sees without links when the reference is not found', async () => {
|
|
@@ -189,9 +189,7 @@ describe('Generates interface documentation', () => {
|
|
|
189
189
|
const result = await generateDocs([apexBundleFromRawString(input1), apexBundleFromRawString(input2)])();
|
|
190
190
|
expect(result).documentationBundleHasLength(2);
|
|
191
191
|
assertEither(result, (data) =>
|
|
192
|
-
expect(data).firstDocContains(
|
|
193
|
-
'This is a description with a [InterfaceRef](/miscellaneous/InterfaceRef.md) reference',
|
|
194
|
-
),
|
|
192
|
+
expect(data).firstDocContains('This is a description with a [InterfaceRef](InterfaceRef.md) reference'),
|
|
195
193
|
);
|
|
196
194
|
});
|
|
197
195
|
|
|
@@ -225,7 +223,7 @@ describe('Generates interface documentation', () => {
|
|
|
225
223
|
const result = await generateDocs([apexBundleFromRawString(input1), apexBundleFromRawString(input2)])();
|
|
226
224
|
expect(result).documentationBundleHasLength(2);
|
|
227
225
|
assertEither(result, (data) => expect(data).firstDocContains('See'));
|
|
228
|
-
assertEither(result, (data) => expect(data).firstDocContains('[InterfaceRef](
|
|
226
|
+
assertEither(result, (data) => expect(data).firstDocContains('[InterfaceRef](InterfaceRef.md)'));
|
|
229
227
|
});
|
|
230
228
|
|
|
231
229
|
it('displays sees without links when the reference is not found', async () => {
|
|
@@ -25,10 +25,10 @@ describe('Generates a Reference Guide', () => {
|
|
|
25
25
|
expect(result).documentationBundleHasLength(2);
|
|
26
26
|
|
|
27
27
|
assertEither(result, (data) =>
|
|
28
|
-
expect((data.referenceGuide as ReferenceGuidePageData).content).toContain('[MyEnum](
|
|
28
|
+
expect((data.referenceGuide as ReferenceGuidePageData).content).toContain('[MyEnum](miscellaneous/MyEnum.md)'),
|
|
29
29
|
);
|
|
30
30
|
assertEither(result, (data) =>
|
|
31
|
-
expect((data.referenceGuide as ReferenceGuidePageData).content).toContain('[MyClass](
|
|
31
|
+
expect((data.referenceGuide as ReferenceGuidePageData).content).toContain('[MyClass](miscellaneous/MyClass.md)'),
|
|
32
32
|
);
|
|
33
33
|
});
|
|
34
34
|
|
|
@@ -174,7 +174,7 @@ describe('Generates a Reference Guide', () => {
|
|
|
174
174
|
const result = await generateDocs([apexBundleFromRawString(input1), apexBundleFromRawString(input2)])();
|
|
175
175
|
expect(result).documentationBundleHasLength(2);
|
|
176
176
|
assertEither(result, (data) =>
|
|
177
|
-
expect((data.referenceGuide as ReferenceGuidePageData).content).toContain('with a [MyClass](
|
|
177
|
+
expect((data.referenceGuide as ReferenceGuidePageData).content).toContain('with a [MyClass](group2/MyClass.md)'),
|
|
178
178
|
);
|
|
179
179
|
});
|
|
180
180
|
});
|
|
@@ -17,7 +17,7 @@ export function generateDocs(apexBundles: UnparsedSourceFile[], config?: Partial
|
|
|
17
17
|
defaultGroupName: 'Miscellaneous',
|
|
18
18
|
sortMembersAlphabetically: true,
|
|
19
19
|
referenceGuideTemplate: referenceGuideTemplate,
|
|
20
|
+
linkingStrategy: 'relative',
|
|
20
21
|
...config,
|
|
21
|
-
documentationRootDir: '',
|
|
22
22
|
});
|
|
23
23
|
}
|
|
@@ -15,7 +15,7 @@ const defaultMarkdownGeneratorConfig: MarkdownGeneratorConfig = {
|
|
|
15
15
|
defaultGroupName: 'Miscellaneous',
|
|
16
16
|
referenceGuideTemplate: '',
|
|
17
17
|
sortMembersAlphabetically: false,
|
|
18
|
-
|
|
18
|
+
linkingStrategy: 'relative',
|
|
19
19
|
};
|
|
20
20
|
|
|
21
21
|
describe('Conversion from InterfaceMirror to InterfaceSource understandable by the templating engine', () => {
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
import { generateLink } from '../generate-link';
|
|
2
|
+
|
|
3
|
+
describe('Generates links', () => {
|
|
4
|
+
describe('relative', () => {
|
|
5
|
+
it('generates relative links from the base when found', () => {
|
|
6
|
+
const references = {
|
|
7
|
+
referenceName: {
|
|
8
|
+
referencePath: 'referencePath',
|
|
9
|
+
displayName: 'displayName',
|
|
10
|
+
},
|
|
11
|
+
};
|
|
12
|
+
const from = '__base__';
|
|
13
|
+
const referenceName = 'referenceName';
|
|
14
|
+
|
|
15
|
+
const result = generateLink('relative')(references, from, referenceName);
|
|
16
|
+
|
|
17
|
+
expect(result).toEqual({
|
|
18
|
+
__type: 'link',
|
|
19
|
+
title: 'displayName',
|
|
20
|
+
url: 'referencePath',
|
|
21
|
+
});
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
it('returns the name of the reference when not found', () => {
|
|
25
|
+
const references = {};
|
|
26
|
+
const from = '__base__';
|
|
27
|
+
const referenceName = 'referenceName';
|
|
28
|
+
|
|
29
|
+
const result = generateLink('relative')(references, from, referenceName);
|
|
30
|
+
|
|
31
|
+
expect(result).toEqual('referenceName');
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
it('returns a relative path when linking from a file', () => {
|
|
35
|
+
const references = {
|
|
36
|
+
referenceName: {
|
|
37
|
+
referencePath: 'a/referencePath',
|
|
38
|
+
displayName: 'displayName',
|
|
39
|
+
},
|
|
40
|
+
from: {
|
|
41
|
+
referencePath: 'b/fromPath',
|
|
42
|
+
displayName: 'fromName',
|
|
43
|
+
},
|
|
44
|
+
};
|
|
45
|
+
const from = 'from';
|
|
46
|
+
const referenceName = 'referenceName';
|
|
47
|
+
|
|
48
|
+
const result = generateLink('relative')(references, from, referenceName);
|
|
49
|
+
|
|
50
|
+
expect(result).toEqual({
|
|
51
|
+
__type: 'link',
|
|
52
|
+
title: 'displayName',
|
|
53
|
+
url: '../a/referencePath',
|
|
54
|
+
});
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
it('returns the display name when the from reference is not found', () => {
|
|
58
|
+
const references = {
|
|
59
|
+
referenceName: {
|
|
60
|
+
referencePath: 'a/referencePath',
|
|
61
|
+
displayName: 'displayName',
|
|
62
|
+
},
|
|
63
|
+
};
|
|
64
|
+
const from = 'from';
|
|
65
|
+
const referenceName = 'referenceName';
|
|
66
|
+
|
|
67
|
+
const result = generateLink('relative')(references, from, referenceName);
|
|
68
|
+
|
|
69
|
+
expect(result).toEqual('displayName');
|
|
70
|
+
});
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
describe('no-link', () => {
|
|
74
|
+
it('returns the name of the reference when the reference is not found', () => {
|
|
75
|
+
const references = {};
|
|
76
|
+
const from = '__base__';
|
|
77
|
+
const referenceName = 'referenceName';
|
|
78
|
+
|
|
79
|
+
const result = generateLink('no-link')(references, from, referenceName);
|
|
80
|
+
|
|
81
|
+
expect(result).toEqual('referenceName');
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
it('returns the display name of the reference when the reference is found', () => {
|
|
85
|
+
const references = {
|
|
86
|
+
referenceName: {
|
|
87
|
+
referencePath: 'referencePath',
|
|
88
|
+
displayName: 'displayName',
|
|
89
|
+
},
|
|
90
|
+
};
|
|
91
|
+
const from = '__base__';
|
|
92
|
+
const referenceName = 'referenceName';
|
|
93
|
+
|
|
94
|
+
const result = generateLink('no-link')(references, from, referenceName);
|
|
95
|
+
|
|
96
|
+
expect(result).toEqual('displayName');
|
|
97
|
+
});
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
describe('none', () => {
|
|
101
|
+
it('returns the path as is when the reference is found', () => {
|
|
102
|
+
const references = {
|
|
103
|
+
referenceName: {
|
|
104
|
+
referencePath: 'referencePath',
|
|
105
|
+
displayName: 'displayName',
|
|
106
|
+
},
|
|
107
|
+
};
|
|
108
|
+
const from = '__base__';
|
|
109
|
+
const referenceName = 'referenceName';
|
|
110
|
+
|
|
111
|
+
const result = generateLink('none')(references, from, referenceName);
|
|
112
|
+
|
|
113
|
+
expect(result).toEqual({
|
|
114
|
+
__type: 'link',
|
|
115
|
+
title: 'displayName',
|
|
116
|
+
url: 'referencePath',
|
|
117
|
+
});
|
|
118
|
+
});
|
|
119
|
+
|
|
120
|
+
it('returns the name of the reference when the reference is not found', () => {
|
|
121
|
+
const references = {};
|
|
122
|
+
const from = '__base__';
|
|
123
|
+
const referenceName = 'referenceName';
|
|
124
|
+
|
|
125
|
+
const result = generateLink('none')(references, from, referenceName);
|
|
126
|
+
|
|
127
|
+
expect(result).toEqual('referenceName');
|
|
128
|
+
});
|
|
129
|
+
});
|
|
130
|
+
});
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import { StringOrLink } from './types';
|
|
2
|
+
import path from 'path';
|
|
3
|
+
import { LinkingStrategy } from '../../shared/types';
|
|
4
|
+
|
|
5
|
+
export type LinkingStrategyFn = (
|
|
6
|
+
references: Record<string, { referencePath: string; displayName: string } | undefined>,
|
|
7
|
+
from: string,
|
|
8
|
+
referenceName: string,
|
|
9
|
+
) => StringOrLink;
|
|
10
|
+
|
|
11
|
+
export const generateLink = (strategy: LinkingStrategy): LinkingStrategyFn => {
|
|
12
|
+
switch (strategy) {
|
|
13
|
+
case 'relative':
|
|
14
|
+
return generateRelativeLink;
|
|
15
|
+
case 'no-link':
|
|
16
|
+
return generateNoLink;
|
|
17
|
+
case 'none':
|
|
18
|
+
return returnReferenceAsIs;
|
|
19
|
+
}
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
const generateRelativeLink = (
|
|
23
|
+
references: Record<string, { referencePath: string; displayName: string } | undefined>,
|
|
24
|
+
from: string, // The name of the file for which the reference is being generated
|
|
25
|
+
referenceName: string,
|
|
26
|
+
): StringOrLink => {
|
|
27
|
+
function getRelativePath(fromPath: string, toPath: string) {
|
|
28
|
+
return path.relative(path.parse(path.join('/', fromPath)).dir, path.join('/', toPath));
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
const referenceTo = references[referenceName];
|
|
32
|
+
if (!referenceTo) {
|
|
33
|
+
return referenceName;
|
|
34
|
+
}
|
|
35
|
+
// When linking from the base path (e.g. the reference guide/index page), the reference path is the same as the output
|
|
36
|
+
// path.
|
|
37
|
+
if (referenceTo && from === '__base__') {
|
|
38
|
+
return {
|
|
39
|
+
__type: 'link',
|
|
40
|
+
title: referenceTo.displayName,
|
|
41
|
+
url: getRelativePath('', referenceTo.referencePath),
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
const referenceFrom = references[from];
|
|
46
|
+
|
|
47
|
+
if (!referenceFrom) {
|
|
48
|
+
return referenceTo.displayName;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
return {
|
|
52
|
+
__type: 'link',
|
|
53
|
+
title: referenceTo.displayName,
|
|
54
|
+
url: getRelativePath(referenceFrom.referencePath, referenceTo.referencePath),
|
|
55
|
+
};
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
const generateNoLink = (
|
|
59
|
+
references: Record<string, { referencePath: string; displayName: string } | undefined>,
|
|
60
|
+
_from: string,
|
|
61
|
+
referenceName: string,
|
|
62
|
+
): StringOrLink => {
|
|
63
|
+
const referenceTo = references[referenceName];
|
|
64
|
+
return referenceTo ? referenceTo.displayName : referenceName;
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
const returnReferenceAsIs = (
|
|
68
|
+
references: Record<string, { referencePath: string; displayName: string } | undefined>,
|
|
69
|
+
_from: string,
|
|
70
|
+
referenceName: string,
|
|
71
|
+
): StringOrLink => {
|
|
72
|
+
const referenceTo = references[referenceName];
|
|
73
|
+
if (!referenceTo) {
|
|
74
|
+
return referenceName;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
return {
|
|
78
|
+
__type: 'link',
|
|
79
|
+
title: referenceTo.displayName,
|
|
80
|
+
url: referenceTo.referencePath,
|
|
81
|
+
};
|
|
82
|
+
};
|
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
import { DocPageReference, ParsedFile } from '../../shared/types';
|
|
2
|
-
import { Link, ReferenceGuideReference, Renderable, RenderableBundle
|
|
2
|
+
import { Link, ReferenceGuideReference, Renderable, RenderableBundle } from './types';
|
|
3
3
|
import { typeToRenderable } from './apex-types';
|
|
4
4
|
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
|
|
8
|
+
import { generateLink } from './generate-link';
|
|
9
9
|
|
|
10
10
|
export function parsedFilesToRenderableBundle(
|
|
11
11
|
config: MarkdownGeneratorConfig,
|
|
12
12
|
parsedFiles: ParsedFile[],
|
|
13
13
|
references: Record<string, DocPageReference>,
|
|
14
14
|
): RenderableBundle {
|
|
15
|
-
const referenceFinder = apply(
|
|
15
|
+
const referenceFinder = apply(generateLink(config.linkingStrategy), references);
|
|
16
16
|
|
|
17
17
|
function toReferenceGuide(parsedFiles: ParsedFile[]): Record<string, ReferenceGuideReference[]> {
|
|
18
18
|
return parsedFiles.reduce<Record<string, ReferenceGuideReference[]>>(
|
|
@@ -55,43 +55,6 @@ function addToReferenceGuide(
|
|
|
55
55
|
};
|
|
56
56
|
}
|
|
57
57
|
|
|
58
|
-
const linkGenerator = (
|
|
59
|
-
references: Record<string, DocPageReference>,
|
|
60
|
-
documentationRootDir: string,
|
|
61
|
-
from: string, // The name of the file for which the reference is being generated
|
|
62
|
-
referenceName: string,
|
|
63
|
-
): StringOrLink => {
|
|
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
|
-
}
|
|
80
|
-
|
|
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
|
-
};
|
|
93
|
-
};
|
|
94
|
-
|
|
95
58
|
function getTypeGroup(type: Type, config: MarkdownGeneratorConfig): string {
|
|
96
59
|
const groupAnnotation = type.docComment?.annotations.find((annotation) => annotation.name.toLowerCase() === 'group');
|
|
97
60
|
return groupAnnotation?.body ?? config.defaultGroupName;
|
|
@@ -25,7 +25,7 @@ export class OpenApiDocsProcessor {
|
|
|
25
25
|
}
|
|
26
26
|
|
|
27
27
|
onProcess(type: Type): void {
|
|
28
|
-
Logger.logSingle(`Processing ${type.name}`,
|
|
28
|
+
Logger.logSingle(`Processing ${type.name}`, 'green');
|
|
29
29
|
|
|
30
30
|
const endpointPath = this.getEndpointPath(type);
|
|
31
31
|
if (!endpointPath) {
|
|
@@ -12,6 +12,17 @@ export type ConfigurableHooks = {
|
|
|
12
12
|
transformReference: TransformReference;
|
|
13
13
|
};
|
|
14
14
|
|
|
15
|
+
type LinkingStrategy =
|
|
16
|
+
// Links will be generated using relative paths.
|
|
17
|
+
| 'relative'
|
|
18
|
+
// No links will be generated.
|
|
19
|
+
// If the reference is found, the display name will be used.
|
|
20
|
+
// Otherwise, the name
|
|
21
|
+
// of the reference itself will be used.
|
|
22
|
+
| 'no-link'
|
|
23
|
+
// No logic will be applied, the reference path will be used as is.
|
|
24
|
+
| 'none';
|
|
25
|
+
|
|
15
26
|
export type UserDefinedMarkdownConfig = {
|
|
16
27
|
targetGenerator: 'markdown';
|
|
17
28
|
sourceDir: string;
|
|
@@ -21,7 +32,7 @@ export type UserDefinedMarkdownConfig = {
|
|
|
21
32
|
namespace?: string;
|
|
22
33
|
sortMembersAlphabetically: boolean;
|
|
23
34
|
includeMetadata: boolean;
|
|
24
|
-
|
|
35
|
+
linkingStrategy: LinkingStrategy;
|
|
25
36
|
} & Partial<ConfigurableHooks>;
|
|
26
37
|
|
|
27
38
|
export type UserDefinedOpenApiConfig = {
|
package/src/defaults.ts
CHANGED
package/src/index.ts
CHANGED
|
@@ -12,12 +12,7 @@ import { defaults } from './defaults';
|
|
|
12
12
|
type ConfigurableMarkdownConfig = Omit<
|
|
13
13
|
SetOptional<
|
|
14
14
|
UserDefinedMarkdownConfig,
|
|
15
|
-
| '
|
|
16
|
-
| 'scope'
|
|
17
|
-
| 'defaultGroupName'
|
|
18
|
-
| 'includeMetadata'
|
|
19
|
-
| 'sortMembersAlphabetically'
|
|
20
|
-
| 'documentationRootDir'
|
|
15
|
+
'targetDir' | 'scope' | 'defaultGroupName' | 'includeMetadata' | 'sortMembersAlphabetically' | 'linkingStrategy'
|
|
21
16
|
>,
|
|
22
17
|
'targetGenerator'
|
|
23
18
|
>;
|
package/src/util/logger.ts
CHANGED
|
@@ -1,13 +1,11 @@
|
|
|
1
1
|
import chalk from 'chalk';
|
|
2
|
-
import
|
|
3
|
-
|
|
2
|
+
import ora from 'ora';
|
|
4
3
|
/**
|
|
5
4
|
* Logs messages to the console.
|
|
6
5
|
*/
|
|
7
6
|
export class Logger {
|
|
8
7
|
static currentFrame = 0;
|
|
9
|
-
|
|
10
|
-
static frames = ['⠋', '⠙', '⠹', '⠸', '⠼', '⠴', '⠦', '⠧', '⠇', '⠏'];
|
|
8
|
+
static spinner = ora();
|
|
11
9
|
|
|
12
10
|
/**
|
|
13
11
|
* Logs a message with optional arguments.
|
|
@@ -27,31 +25,31 @@ export class Logger {
|
|
|
27
25
|
* @param args Optional arguments.
|
|
28
26
|
*/
|
|
29
27
|
public static error(message: unknown, ...args: string[]) {
|
|
30
|
-
this.logSingle(message,
|
|
28
|
+
this.logSingle(message, 'red');
|
|
31
29
|
args.forEach(() => {
|
|
32
|
-
this.logSingle(message,
|
|
30
|
+
this.logSingle(message, 'red');
|
|
33
31
|
});
|
|
34
32
|
}
|
|
35
33
|
|
|
36
|
-
public static logSingle(text: unknown,
|
|
34
|
+
public static logSingle(text: unknown, color: 'green' | 'red' = 'green') {
|
|
37
35
|
if (this.currentFrame > 9) {
|
|
38
36
|
this.currentFrame = 0;
|
|
39
37
|
}
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
38
|
+
|
|
39
|
+
const logMessage = `${this.getChalkFn(color)(new Date().toLocaleString() + ': ')}${text}\n`;
|
|
40
|
+
process.stdout.write(logMessage);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
private static getChalkFn(color: 'green' | 'red') {
|
|
44
|
+
return color === 'green' ? chalk.green : chalk.red;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
public static startSpinner(text: string) {
|
|
48
|
+
this.spinner.text = text;
|
|
49
|
+
this.spinner.start();
|
|
52
50
|
}
|
|
53
51
|
|
|
54
|
-
public static
|
|
55
|
-
|
|
52
|
+
public static succeedSpinner(text: string) {
|
|
53
|
+
this.spinner.succeed(text);
|
|
56
54
|
}
|
|
57
55
|
}
|