From 3cfeb3814703d12a9e95ed684fc2c8f94d1f2c72 Mon Sep 17 00:00:00 2001 From: ST-DDT Date: Fri, 28 Apr 2023 15:23:50 +0200 Subject: [PATCH] docs: fix full url to absolute conversion (#2101) --- scripts/apidoc/fakerClass.ts | 8 +++--- scripts/apidoc/markdown.ts | 4 +-- scripts/apidoc/moduleMethods.ts | 22 ++++++++++++--- scripts/apidoc/utils.ts | 4 +++ .../apidoc/__snapshots__/module.spec.ts.snap | 24 +++++++++++++++++ test/scripts/apidoc/module.example.ts | 11 ++++++++ test/scripts/apidoc/module.spec.ts | 27 +++++++++++++++++++ test/scripts/apidoc/tsconfig.json | 2 +- test/scripts/apidoc/utils.ts | 20 ++++++++++++++ 9 files changed, 112 insertions(+), 10 deletions(-) create mode 100644 test/scripts/apidoc/__snapshots__/module.spec.ts.snap create mode 100644 test/scripts/apidoc/module.example.ts create mode 100644 test/scripts/apidoc/module.spec.ts diff --git a/scripts/apidoc/fakerClass.ts b/scripts/apidoc/fakerClass.ts index c3a5287d620..f8de8653af3 100644 --- a/scripts/apidoc/fakerClass.ts +++ b/scripts/apidoc/fakerClass.ts @@ -2,9 +2,9 @@ import type { DeclarationReflection, ProjectReflection } from 'typedoc'; import { ReflectionKind } from 'typedoc'; import type { Method } from '../../docs/.vitepress/components/api-docs/method'; import { writeApiDocsModule } from './apiDocsWriter'; -import { processModuleMethods } from './moduleMethods'; +import { analyzeModule, processModuleMethods } from './moduleMethods'; import { analyzeSignature } from './signature'; -import { extractDescription, selectApiSignature } from './typedoc'; +import { selectApiSignature } from './typedoc'; import type { ModuleSummary } from './utils'; export function processFakerClass(project: ProjectReflection): ModuleSummary { @@ -21,7 +21,7 @@ export function processFakerClass(project: ProjectReflection): ModuleSummary { function processClass(fakerClass: DeclarationReflection): ModuleSummary { console.log(`Processing Faker class`); - const comment = extractDescription(fakerClass); + const { comment, deprecated } = analyzeModule(fakerClass); const methods: Method[] = []; console.debug(`- constructor`); @@ -29,7 +29,7 @@ function processClass(fakerClass: DeclarationReflection): ModuleSummary { methods.push(...processModuleMethods(fakerClass, 'faker.')); - return writeApiDocsModule('Faker', 'faker', comment, undefined, methods); + return writeApiDocsModule('Faker', 'faker', comment, deprecated, methods); } function processConstructor(fakerClass: DeclarationReflection): Method { diff --git a/scripts/apidoc/markdown.ts b/scripts/apidoc/markdown.ts index 8505b51d715..1ddd433e6ff 100644 --- a/scripts/apidoc/markdown.ts +++ b/scripts/apidoc/markdown.ts @@ -2,7 +2,7 @@ import sanitizeHtml from 'sanitize-html'; import type { MarkdownRenderer } from 'vitepress'; import { createMarkdownRenderer } from 'vitepress'; import vitepressConfig from '../../docs/.vitepress/config'; -import { pathOutputDir } from './utils'; +import { adjustUrls, pathOutputDir } from './utils'; let markdown: MarkdownRenderer; @@ -57,7 +57,7 @@ export function mdToHtml(md: string, inline: boolean = false): string { const safeHtml: string = sanitizeHtml(rawHtml, htmlSanitizeOptions); // Revert some escaped characters for comparison. if (comparableSanitizedHtml(rawHtml) === comparableSanitizedHtml(safeHtml)) { - return safeHtml.replace(/https:\/\/(next.)?fakerjs.dev\//g, '/'); + return adjustUrls(safeHtml); } console.debug('Rejected unsafe md:', md); diff --git a/scripts/apidoc/moduleMethods.ts b/scripts/apidoc/moduleMethods.ts index 55b1869f798..65a62528676 100644 --- a/scripts/apidoc/moduleMethods.ts +++ b/scripts/apidoc/moduleMethods.ts @@ -15,6 +15,7 @@ import { selectApiModules, } from './typedoc'; import type { ModuleSummary } from './utils'; +import { adjustUrls } from './utils'; /** * Analyzes and writes the documentation for modules and their methods such as `faker.animal.cat()`. @@ -34,10 +35,9 @@ export function processModules(project: ProjectReflection): ModuleSummary[] { */ function processModule(module: DeclarationReflection): ModuleSummary { const moduleName = extractModuleName(module); - const moduleFieldName = extractModuleFieldName(module); console.log(`Processing Module ${moduleName}`); - const comment = extractDescription(module); - const deprecated = extractDeprecated(module); + const moduleFieldName = extractModuleFieldName(module); + const { comment, deprecated } = analyzeModule(module); const methods = processModuleMethods(module, `faker.${moduleFieldName}.`); return writeApiDocsModule( @@ -49,6 +49,22 @@ function processModule(module: DeclarationReflection): ModuleSummary { ); } +/** + * Analyzes the documentation for a class. + * + * @param module The class to process. + * @returns The class information. + */ +export function analyzeModule(module: DeclarationReflection): { + comment: string; + deprecated: string | undefined; +} { + return { + comment: adjustUrls(extractDescription(module)), + deprecated: extractDeprecated(module), + }; +} + /** * Processes all api methods of the given class. This does not include the constructor. * diff --git a/scripts/apidoc/utils.ts b/scripts/apidoc/utils.ts index 79e475070d7..8a002f49335 100644 --- a/scripts/apidoc/utils.ts +++ b/scripts/apidoc/utils.ts @@ -43,6 +43,10 @@ export const pathOutputDir = resolve(pathDocsDir, 'api'); // Functions +export function adjustUrls(description: string): string { + return description.replace(/https:\/\/(next.)?fakerjs.dev\//g, '/'); +} + export function mapByName( input: T[], valueExtractor: (item: T) => V diff --git a/test/scripts/apidoc/__snapshots__/module.spec.ts.snap b/test/scripts/apidoc/__snapshots__/module.spec.ts.snap new file mode 100644 index 00000000000..b3584e13aef --- /dev/null +++ b/test/scripts/apidoc/__snapshots__/module.spec.ts.snap @@ -0,0 +1,24 @@ +// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html + +exports[`module > analyzeModule() > ModuleFakerJsLinkTest 1`] = ` +{ + "comment": "Description with a link to our [website](/) +and [api docs](/api/).", + "deprecated": undefined, +} +`; + +exports[`module > analyzeModule() > ModuleNextFakerJsLinkTest 1`] = ` +{ + "comment": "Description with a link to our [website](/) +and [api docs](/api/).", + "deprecated": undefined, +} +`; + +exports[`module > analyzeModule() > expected and actual modules are equal 1`] = ` +[ + "ModuleFakerJsLinkTest", + "ModuleNextFakerJsLinkTest", +] +`; diff --git a/test/scripts/apidoc/module.example.ts b/test/scripts/apidoc/module.example.ts new file mode 100644 index 00000000000..ef646659004 --- /dev/null +++ b/test/scripts/apidoc/module.example.ts @@ -0,0 +1,11 @@ +/** + * Description with a link to our [website](https://fakerjs.dev/) + * and [api docs](https://fakerjs.dev/api/). + */ +export class ModuleFakerJsLinkTest {} + +/** + * Description with a link to our [website](https://next.fakerjs.dev/) + * and [api docs](https://next.fakerjs.dev/api/). + */ +export class ModuleNextFakerJsLinkTest {} diff --git a/test/scripts/apidoc/module.spec.ts b/test/scripts/apidoc/module.spec.ts new file mode 100644 index 00000000000..11a957aa849 --- /dev/null +++ b/test/scripts/apidoc/module.spec.ts @@ -0,0 +1,27 @@ +import { beforeAll, describe, expect, it } from 'vitest'; +import { initMarkdownRenderer } from '../../../scripts/apidoc/markdown'; +import { analyzeModule } from '../../../scripts/apidoc/moduleMethods'; +import * as ModuleTests from './module.example'; +import { loadExampleModules } from './utils'; + +describe('module', () => { + describe('analyzeModule()', () => { + const modules = loadExampleModules(); + + beforeAll(initMarkdownRenderer); + + it('dummy dependency to rerun the test if the example changes', () => { + expect(Object.keys(ModuleTests)).not.toEqual([]); + }); + + it('expected and actual modules are equal', () => { + expect(Object.keys(modules).sort()).toMatchSnapshot(); + }); + + it.each(Object.entries(modules))('%s', (_, module) => { + const actual = analyzeModule(module); + + expect(actual).toMatchSnapshot(); + }); + }); +}); diff --git a/test/scripts/apidoc/tsconfig.json b/test/scripts/apidoc/tsconfig.json index 0f7afc342e6..dafe3a14371 100644 --- a/test/scripts/apidoc/tsconfig.json +++ b/test/scripts/apidoc/tsconfig.json @@ -2,5 +2,5 @@ "compilerOptions": { "target": "ES5" }, - "include": ["signature.example.ts"] + "include": ["signature.example.ts", "module.example.ts"] } diff --git a/test/scripts/apidoc/utils.ts b/test/scripts/apidoc/utils.ts index 281fb2ef6e9..2addfe651a5 100644 --- a/test/scripts/apidoc/utils.ts +++ b/test/scripts/apidoc/utils.ts @@ -39,3 +39,23 @@ export function loadExampleMethods(): Record { true )['SignatureTest'][1]; } + +/** + * Loads the example modules using TypeDoc. + */ +export function loadExampleModules(): Record { + const modules = loadProjectModules( + { + entryPoints: ['test/scripts/apidoc/module.example.ts'], + tsconfig: 'test/scripts/apidoc/tsconfig.json', + }, + true + ); + + const result: Record = {}; + for (const key in modules) { + result[key] = modules[key][0]; + } + + return result; +}