Skip to content

Commit 5ae01d7

Browse files
ST-DDTShinigami92
authored andcommitted
docs: show source link (faker-js#1780)
Co-authored-by: Shinigami92 <[email protected]>
1 parent 7d6787e commit 5ae01d7

File tree

9 files changed

+150
-12
lines changed

9 files changed

+150
-12
lines changed

docs/.vitepress/components/api-docs/method.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ export interface Method {
77
readonly examples: string; // HTML
88
readonly deprecated: boolean;
99
readonly since: string;
10+
readonly sourcePath: string; // URL-Suffix
1011
readonly seeAlsos: string[];
1112
}
1213

docs/.vitepress/components/api-docs/method.vue

Lines changed: 43 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
import type { Method } from './method';
33
import MethodParameters from './method-parameters.vue';
44
import { slugify } from '../../shared/utils/slugify';
5+
import { sourceBaseUrl } from '../../../api/source-base-url';
56
67
const props = defineProps<{ method: Method }>();
78
@@ -20,11 +21,9 @@ function seeAlsoToUrl(see: string): string {
2021

2122
<div v-html="props.method.description"></div>
2223

23-
<div v-if="props.method.since">
24-
<p>
25-
<em>Available since v<span v-html="props.method.since" /></em>
26-
</p>
27-
</div>
24+
<p v-if="props.method.since">
25+
<em>Available since v{{ props.method.since }}</em>
26+
</p>
2827

2928
<MethodParameters
3029
v-if="props.method.parameters.length > 0"
@@ -48,5 +47,44 @@ function seeAlsoToUrl(see: string): string {
4847
</li>
4948
</ul>
5049
</div>
50+
51+
<div v-if="props.method.sourcePath">
52+
<h3>Source</h3>
53+
<ul>
54+
<li>
55+
<a
56+
:href="sourceBaseUrl + props.method.sourcePath"
57+
target="_blank"
58+
class="source-link"
59+
>
60+
View Source
61+
<svg
62+
xmlns="http://www.w3.org/2000/svg"
63+
viewBox="0 0 24 24"
64+
fill="currentColor"
65+
width="1.2em"
66+
height="1.2em"
67+
class="source-link-icon"
68+
>
69+
<path
70+
d="M14,3V5H17.59L7.76,14.83L9.17,16.24L19,6.41V10H21V3M19,19H5V5H12V3H5C3.89,3 3,3.9 3,5V19A2,2 0 0,0 5,21H19A2,2 0 0,0 21,19V12H19V19Z"
71+
/>
72+
</svg>
73+
</a>
74+
</li>
75+
</ul>
76+
</div>
5177
</div>
5278
</template>
79+
80+
<style scoped>
81+
a.source-link {
82+
display: flex;
83+
align-items: center;
84+
}
85+
86+
svg.source-link-icon {
87+
display: inline;
88+
margin-left: 0.3em;
89+
}
90+
</style>

scripts/apidoc/apiDocsWriter.ts

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import type { APIGroup, APIItem } from '../../docs/api/api-types';
66
import { formatMarkdown, formatTypescript } from './format';
77
import {
88
extractModuleName,
9+
extractSourceBaseUrl,
910
selectApiMethods,
1011
selectApiModules,
1112
} from './typedoc';
@@ -120,10 +121,20 @@ export function writeApiPagesIndex(pages: PageIndex): void {
120121
writeFileSync(pathDocsApiPages, apiPagesContent);
121122
}
122123

124+
/**
125+
* Writes the api diff index to the correct location.
126+
*
127+
* @param diffIndex The diff index project to write.
128+
*/
123129
export function writeApiDiffIndex(diffIndex: DocsApiDiffIndex): void {
124130
writeFileSync(pathDocsDiffIndexFile, JSON.stringify(diffIndex));
125131
}
126132

133+
/**
134+
* Writes the api search index to the correct location.
135+
*
136+
* @param project The typedoc project.
137+
*/
127138
export function writeApiSearchIndex(project: ProjectReflection): void {
128139
const apiIndex: APIGroup[] = [];
129140

@@ -154,3 +165,22 @@ export function writeApiSearchIndex(project: ProjectReflection): void {
154165

155166
writeFileSync(pathDocsApiSearchIndex, JSON.stringify(apiIndex));
156167
}
168+
169+
/**
170+
* Writes the source base url to the correct location.
171+
*
172+
* @param project The typedoc project.
173+
*/
174+
export function writeSourceBaseUrl(project: ProjectReflection): void {
175+
const baseUrl = extractSourceBaseUrl(project);
176+
177+
let content = `
178+
// This file is automatically generated.
179+
// Run '${scriptCommand}' to update
180+
export const sourceBaseUrl = '${baseUrl}';
181+
`.replace(/\n +/, '\n');
182+
183+
content = formatTypescript(content);
184+
185+
writeFileSync(resolve(pathOutputDir, 'source-base-url.ts'), content);
186+
}

scripts/apidoc/generate.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import {
33
writeApiDiffIndex,
44
writeApiPagesIndex,
55
writeApiSearchIndex,
6+
writeSourceBaseUrl,
67
} from './apiDocsWriter';
78
import { processModuleMethods } from './moduleMethods';
89
import { loadProject } from './typedoc';
@@ -26,4 +27,5 @@ export async function generate(): Promise<void> {
2627
);
2728

2829
writeApiSearchIndex(project);
30+
writeSourceBaseUrl(project);
2931
}

scripts/apidoc/moduleMethods.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import {
99
selectApiModules,
1010
} from './typedoc';
1111
import type { PageAndDiffIndex } from './utils';
12-
import { diffHash } from './utils';
12+
import { diffHash, methodDiffHash } from './utils';
1313

1414
/**
1515
* Analyzes and writes the documentation for modules and their methods such as `faker.animal.cat()`.
@@ -62,7 +62,7 @@ function processModuleMethod(module: DeclarationReflection): PageAndDiffIndex {
6262
diff: methods.reduce(
6363
(data, method) => ({
6464
...data,
65-
[method.name]: diffHash(method),
65+
[method.name]: methodDiffHash(method),
6666
}),
6767
{
6868
moduleHash: diffHash({

scripts/apidoc/signature.ts

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -23,12 +23,15 @@ import {
2323
extractRawExamples,
2424
extractSeeAlsos,
2525
extractSince,
26+
extractSourcePath,
2627
isDeprecated,
2728
joinTagParts,
2829
} from './typedoc';
2930
import { pathOutputDir } from './utils';
3031

31-
export function prettifyMethodName(method: string): string {
32+
const code = '```';
33+
34+
function prettifyMethodName(method: string): string {
3235
return (
3336
// Capitalize and insert space before upper case characters
3437
method.substring(0, 1).toUpperCase() +
@@ -176,15 +179,13 @@ export function analyzeSignature(
176179
mdToHtml(seeAlso, true)
177180
);
178181

179-
const prettyMethodName = prettifyMethodName(methodName);
180-
const code = '```';
181-
182182
return {
183183
name: methodName,
184-
title: prettyMethodName,
184+
title: prettifyMethodName(methodName),
185185
description: mdToHtml(toBlock(signature.comment)),
186186
parameters: parameters,
187187
since: extractSince(signature),
188+
sourcePath: extractSourcePath(signature),
188189
returns: typeToText(signature.type),
189190
examples: mdToHtml(`${code}ts\n${examples}${code}`),
190191
deprecated: isDeprecated(signature),

scripts/apidoc/typedoc.ts

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import type {
33
CommentTag,
44
DeclarationReflection,
55
ProjectReflection,
6+
Reflection,
67
SignatureReflection,
78
TypeDocOptions,
89
} from 'typedoc';
@@ -144,6 +145,40 @@ export function extractModuleFieldName(module: DeclarationReflection): string {
144145
return moduleName.substring(0, 1).toLowerCase() + moduleName.substring(1);
145146
}
146147

148+
/**
149+
* Extracts the source url from the jsdocs.
150+
*
151+
* @param reflection The reflection instance to extract the source url from.
152+
*/
153+
function extractSourceUrl(reflection: Reflection): string {
154+
const source = reflection.sources?.[0];
155+
return source?.url ?? '';
156+
}
157+
158+
/**
159+
* Extracts the source base url from the jsdocs.
160+
*
161+
* @param reflection The reflection instance to extract the source base url from.
162+
*/
163+
export function extractSourceBaseUrl(reflection: Reflection): string {
164+
return extractSourceUrl(reflection).replace(
165+
/^(.*\/blob\/[0-9a-f]+\/)(.*)$/,
166+
'$1'
167+
);
168+
}
169+
170+
/**
171+
* Extracts the relative source path from the jsdocs.
172+
*
173+
* @param reflection The reflection instance to extract the source path from.
174+
*/
175+
export function extractSourcePath(reflection: Reflection): string {
176+
return extractSourceUrl(reflection).replace(
177+
/^(.*\/blob\/[0-9a-f]+\/)(.*)$/,
178+
'$2'
179+
);
180+
}
181+
147182
/**
148183
* Extracts the text (md) from a jsdoc tag.
149184
*

scripts/apidoc/utils.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { createHash } from 'node:crypto';
22
import { resolve } from 'node:path';
3+
import type { Method } from '../../docs/.vitepress/components/api-docs/method';
34

45
// Types
56

@@ -53,6 +54,18 @@ export function mapByName<T extends { name: string }, V>(
5354
);
5455
}
5556

57+
/**
58+
* Creates a diff hash for the given method by removing the line number from the source path.
59+
*
60+
* @param method The method to create a hash for.
61+
*/
62+
export function methodDiffHash(method: Method): string {
63+
return diffHash({
64+
...method,
65+
sourcePath: method.sourcePath.replace(/#.*/g, ''),
66+
});
67+
}
68+
5669
/**
5770
* Creates a diff hash for the given object.
5871
*

0 commit comments

Comments
 (0)