aboutsummaryrefslogtreecommitdiff
path: root/scripts
diff options
context:
space:
mode:
authorST-DDT <[email protected]>2023-01-23 18:47:09 +0100
committerGitHub <[email protected]>2023-01-23 17:47:09 +0000
commit23aa08800ac66a5b16e405d04d07ea538d16dd6b (patch)
treed031ddeff74354b9064b4b32ceb5f5e2bf5f0ac4 /scripts
parent826cb0b2db247fde4d0ee93933dfecd4f3a656dd (diff)
downloadfaker-23aa08800ac66a5b16e405d04d07ea538d16dd6b.tar.xz
faker-23aa08800ac66a5b16e405d04d07ea538d16dd6b.zip
refactor: reorganize apidoc scripts and reuse them for tests (#1759)
Diffstat (limited to 'scripts')
-rw-r--r--scripts/apidoc.ts3
-rw-r--r--scripts/apidoc/apiDocsWriter.ts40
-rw-r--r--scripts/apidoc/format.ts31
-rw-r--r--scripts/apidoc/moduleMethods.ts47
-rw-r--r--scripts/apidoc/signature.ts6
-rw-r--r--scripts/apidoc/typedoc.ts210
-rw-r--r--scripts/apidoc/utils.ts165
7 files changed, 278 insertions, 224 deletions
diff --git a/scripts/apidoc.ts b/scripts/apidoc.ts
index 921859e7..3e11572e 100644
--- a/scripts/apidoc.ts
+++ b/scripts/apidoc.ts
@@ -5,8 +5,9 @@ import {
} from './apidoc/apiDocsWriter';
import { processModuleMethods } from './apidoc/moduleMethods';
import { initMarkdownRenderer } from './apidoc/signature';
+import { newTypeDocApp, patchProject } from './apidoc/typedoc';
import type { PageIndex } from './apidoc/utils';
-import { newTypeDocApp, patchProject, pathOutputDir } from './apidoc/utils';
+import { pathOutputDir } from './apidoc/utils';
const pathOutputJson = resolve(pathOutputDir, 'typedoc.json');
diff --git a/scripts/apidoc/apiDocsWriter.ts b/scripts/apidoc/apiDocsWriter.ts
index cd8dd2e5..f18b7cd9 100644
--- a/scripts/apidoc/apiDocsWriter.ts
+++ b/scripts/apidoc/apiDocsWriter.ts
@@ -1,17 +1,16 @@
import { writeFileSync } from 'node:fs';
import { resolve } from 'node:path';
import type { ProjectReflection } from 'typedoc';
-import { ReflectionKind } from 'typedoc';
import type { Method } from '../../docs/.vitepress/components/api-docs/method';
import type { APIGroup, APIItem } from '../../docs/api/api-types';
-import { extractModuleName, selectApiModules } from './moduleMethods';
-import type { PageIndex } from './utils';
+import { formatMarkdown, formatTypescript } from './format';
import {
- formatMarkdown,
- formatTypescript,
- pathDocsDir,
- pathOutputDir,
-} from './utils';
+ extractModuleName,
+ selectApiMethods,
+ selectApiModules,
+} from './typedoc';
+import type { PageIndex } from './utils';
+import { pathDocsDir, pathOutputDir } from './utils';
const pathDocsApiPages = resolve(pathDocsDir, '.vitepress', 'api-pages.ts');
const pathDocsApiSearchIndex = resolve(
@@ -139,28 +138,11 @@ export function writeApiSearchIndex(project: ProjectReflection): void {
const apiSection: APIItem = {
text: moduleName,
link: moduleName.toLowerCase(),
- headers: [],
+ headers: selectApiMethods(module).map((child) => ({
+ anchor: child.name,
+ text: child.name,
+ })),
};
- if (module.kind !== ReflectionKind.Property) {
- apiSection.headers = module
- .getChildrenByKind(ReflectionKind.Method)
- .map((child) => ({
- anchor: child.name,
- text: child.name,
- }));
- } else {
- // TODO @Shinigami92 2022-08-17: Extract capitalization into own function
- apiSection.text =
- apiSection.text.substring(0, 1).toUpperCase() +
- apiSection.text.substring(1);
-
- apiSection.headers = [
- {
- anchor: module.name,
- text: module.name,
- },
- ];
- }
return apiSection;
})
diff --git a/scripts/apidoc/format.ts b/scripts/apidoc/format.ts
new file mode 100644
index 00000000..0a502c5f
--- /dev/null
+++ b/scripts/apidoc/format.ts
@@ -0,0 +1,31 @@
+import type { Options } from 'prettier';
+import { format } from 'prettier';
+import prettierConfig from '../../.prettierrc.cjs';
+
+/**
+ * Formats markdown contents.
+ *
+ * @param text The text to format.
+ */
+export function formatMarkdown(text: string): string {
+ return format(text, prettierMarkdown);
+}
+
+/**
+ * Formats typedoc contents.
+ *
+ * @param text The text to format.
+ */
+export function formatTypescript(text: string): string {
+ return format(text, prettierTypescript);
+}
+
+const prettierMarkdown: Options = {
+ ...prettierConfig,
+ parser: 'markdown',
+};
+
+const prettierTypescript: Options = {
+ ...prettierConfig,
+ parser: 'typescript',
+};
diff --git a/scripts/apidoc/moduleMethods.ts b/scripts/apidoc/moduleMethods.ts
index dd4f528a..b52d4780 100644
--- a/scripts/apidoc/moduleMethods.ts
+++ b/scripts/apidoc/moduleMethods.ts
@@ -1,26 +1,16 @@
import type { DeclarationReflection, ProjectReflection } from 'typedoc';
-import { ReflectionKind } from 'typedoc';
import type { Method } from '../../docs/.vitepress/components/api-docs/method';
-import { faker } from '../../src';
import { writeApiDocsData, writeApiDocsModulePage } from './apiDocsWriter';
import { analyzeSignature, toBlock } from './signature';
+import {
+ extractModuleFieldName,
+ extractModuleName,
+ selectApiMethodSignatures,
+ selectApiModules,
+} from './typedoc';
import type { PageIndex } from './utils';
/**
- * Selects the modules from the project that needs to be documented.
- *
- * @param project The project used to extract the modules.
- * @returns The modules to document.
- */
-export function selectApiModules(
- project: ProjectReflection
-): DeclarationReflection[] {
- return project
- .getChildrenByKind(ReflectionKind.Class)
- .filter((module) => faker[extractModuleFieldName(module)] != null);
-}
-
-/**
* Analyzes and writes the documentation for modules and their methods such as `faker.animal.cat()`.
*
* @param project The project used to extract the modules.
@@ -37,24 +27,6 @@ export function processModuleMethods(project: ProjectReflection): PageIndex {
return pages;
}
-export function extractModuleName(module: DeclarationReflection): string {
- const { name } = module;
- // TODO @ST-DDT 2022-10-16: Remove in v10.
- // Typedoc prefers the name of the module that is exported first.
- if (name === 'AddressModule') {
- return 'Location';
- } else if (name === 'NameModule') {
- return 'Person';
- }
-
- return name.replace(/Module$/, '');
-}
-
-function extractModuleFieldName(module: DeclarationReflection): string {
- const moduleName = extractModuleName(module);
- return moduleName.substring(0, 1).toLowerCase() + moduleName.substring(1);
-}
-
/**
* Analyzes and writes the documentation for a module and its methods such as `faker.animal.cat()`.
*
@@ -69,11 +41,10 @@ function processModuleMethod(module: DeclarationReflection): PageIndex {
const methods: Method[] = [];
// Generate method section
- for (const method of module.getChildrenByKind(ReflectionKind.Method)) {
- const methodName = method.name;
+ for (const [methodName, signature] of Object.entries(
+ selectApiMethodSignatures(module)
+ )) {
console.debug(`- ${methodName}`);
- const signatures = method.signatures;
- const signature = signatures[signatures.length - 1];
methods.push(analyzeSignature(signature, moduleFieldName, methodName));
}
diff --git a/scripts/apidoc/signature.ts b/scripts/apidoc/signature.ts
index f2a4bd85..d34abf18 100644
--- a/scripts/apidoc/signature.ts
+++ b/scripts/apidoc/signature.ts
@@ -18,15 +18,15 @@ import type {
} from '../../docs/.vitepress/components/api-docs/method';
import vitepressConfig from '../../docs/.vitepress/config';
import { faker } from '../../src';
+import { formatTypescript } from './format';
import {
extractRawExamples,
extractSeeAlsos,
extractSince,
- formatTypescript,
isDeprecated,
joinTagParts,
- pathOutputDir,
-} from './utils';
+} from './typedoc';
+import { pathOutputDir } from './utils';
export function prettifyMethodName(method: string): string {
return (
diff --git a/scripts/apidoc/typedoc.ts b/scripts/apidoc/typedoc.ts
new file mode 100644
index 00000000..d9b34a0b
--- /dev/null
+++ b/scripts/apidoc/typedoc.ts
@@ -0,0 +1,210 @@
+import type {
+ CommentDisplayPart,
+ CommentTag,
+ DeclarationReflection,
+ ProjectReflection,
+ SignatureReflection,
+} from 'typedoc';
+import {
+ Application,
+ Converter,
+ ReflectionKind,
+ TSConfigReader,
+} from 'typedoc';
+import { faker } from '../../src';
+import {
+ DefaultParameterAwareSerializer,
+ parameterDefaultReader,
+ patchProjectParameterDefaults,
+} from './parameterDefaults';
+import { mapByName } from './utils';
+
+/**
+ * Creates and configures a new typedoc application.
+ */
+export function newTypeDocApp(): Application {
+ const app = new Application();
+
+ app.options.addReader(new TSConfigReader());
+ // If you want TypeDoc to load typedoc.json files
+ //app.options.addReader(new TypeDoc.TypeDocReader());
+
+ // Read parameter defaults
+ app.converter.on(Converter.EVENT_CREATE_DECLARATION, parameterDefaultReader);
+ // Add to debug json output
+ app.serializer.addSerializer(new DefaultParameterAwareSerializer());
+
+ return app;
+}
+
+/**
+ * Apply our patches to the generated typedoc data.
+ *
+ * This is moved to a separate method to allow printing/saving the original content before patching it.
+ *
+ * @param project The project to patch.
+ */
+export function patchProject(project: ProjectReflection): void {
+ patchProjectParameterDefaults(project);
+}
+
+/**
+ * Selects the modules from the project that needs to be documented.
+ *
+ * @param project The project to extract the modules from.
+ * @returns The modules to document.
+ */
+export function selectApiModules(
+ project: ProjectReflection,
+ includeTestModules = false
+): DeclarationReflection[] {
+ return project
+ .getChildrenByKind(ReflectionKind.Class)
+ .filter(
+ (module) =>
+ faker[extractModuleFieldName(module)] != null || includeTestModules
+ );
+}
+
+/**
+ * Selects the methods from the module that needs to be documented.
+ *
+ * @param module The module to extract the methods from.
+ * @returns The methods to document.
+ */
+export function selectApiMethods(
+ module: DeclarationReflection
+): DeclarationReflection[] {
+ return module.getChildrenByKind(ReflectionKind.Method);
+}
+
+/**
+ * Selects the signature from the method that needs to be documented.
+ *
+ * @param method The method to extract the signature from.
+ * @returns The signature to document.
+ */
+export function selectApiSignature(
+ method: DeclarationReflection
+): SignatureReflection {
+ const signatures = method.signatures;
+ if (signatures == null || signatures.length === 0) {
+ throw new Error(`Method ${method.name} has no signature.`);
+ }
+
+ return signatures[signatures.length - 1];
+}
+
+/**
+ * Selects the method signatures from the module that needs to be documented.
+ * Method-Name -> Method-Signature
+ *
+ * @param method The module to extract the method signatures from.
+ * @returns The method signatures to document.
+ */
+export function selectApiMethodSignatures(
+ module: DeclarationReflection
+): Record<string, SignatureReflection> {
+ return mapByName(selectApiMethods(module), selectApiSignature);
+}
+
+export function extractModuleName(module: DeclarationReflection): string {
+ const { name } = module;
+ // TODO @ST-DDT 2022-10-16: Remove in v10.
+ // Typedoc prefers the name of the module that is exported first.
+ if (name === 'AddressModule') {
+ return 'Location';
+ } else if (name === 'NameModule') {
+ return 'Person';
+ }
+
+ return name.replace(/Module$/, '');
+}
+
+export function extractModuleFieldName(module: DeclarationReflection): string {
+ const moduleName = extractModuleName(module);
+ return moduleName.substring(0, 1).toLowerCase() + moduleName.substring(1);
+}
+
+/**
+ * Extracts the text (md) from a jsdoc tag.
+ *
+ * @param tag The tag to extract the text from.
+ * @param signature The signature to extract the text from.
+ */
+export function extractTagContent(
+ tag: `@${string}`,
+ signature?: SignatureReflection,
+ tagProcessor: (tag: CommentTag) => string[] = joinTagContent
+): string[] {
+ return signature?.comment?.getTags(tag).flatMap(tagProcessor) ?? [];
+}
+
+/**
+ * Extracts the examples from the jsdocs without the surrounding md code block.
+ *
+ * @param signature The signature to extract the examples from.
+ */
+export function extractRawExamples(signature?: SignatureReflection): string[] {
+ return extractTagContent('@example', signature).map((tag) =>
+ tag.replace(/^```ts\n/, '').replace(/\n```$/, '')
+ );
+}
+
+/**
+ * Extracts all the `@see` references from the jsdocs separately.
+ *
+ * @param signature The signature to extract the see also references from.
+ */
+export function extractSeeAlsos(signature?: SignatureReflection): string[] {
+ return extractTagContent('@see', signature, (tag) =>
+ // If the @see tag contains code in backticks, the content is split into multiple parts.
+ // So we join together, split on newlines and filter out empty tags.
+ joinTagParts(tag.content)
+ .split('\n')
+ .map((link) => {
+ link = link.trim();
+ if (link.startsWith('-')) {
+ link = link.slice(1).trim();
+ }
+
+ return link;
+ })
+ .filter((link) => link)
+ );
+}
+
+/**
+ * Joins the parts of the given jsdocs tag.
+ */
+export function joinTagContent(tag: CommentTag): string[] {
+ return [joinTagParts(tag?.content)];
+}
+
+export function joinTagParts(parts: CommentDisplayPart[]): string;
+export function joinTagParts(parts?: CommentDisplayPart[]): string | undefined;
+export function joinTagParts(parts?: CommentDisplayPart[]): string | undefined {
+ return parts?.map((part) => part.text).join('');
+}
+
+/**
+ * Checks if the given signature is deprecated.
+ *
+ * @param signature The signature to check.
+ *
+ * @returns `true` if it is deprecated, otherwise `false`.
+ */
+export function isDeprecated(signature: SignatureReflection): boolean {
+ return extractTagContent('@deprecated', signature).length > 0;
+}
+
+/**
+ * Extracts the "since" tag from the provided signature.
+ *
+ * @param signature The signature to check.
+ *
+ * @returns the contents of the @since tag
+ */
+export function extractSince(signature: SignatureReflection): string {
+ return extractTagContent('@since', signature).join().trim();
+}
diff --git a/scripts/apidoc/utils.ts b/scripts/apidoc/utils.ts
index 9dad1b14..7939adb1 100644
--- a/scripts/apidoc/utils.ts
+++ b/scripts/apidoc/utils.ts
@@ -1,165 +1,24 @@
import { resolve } from 'node:path';
-import type { Options } from 'prettier';
-import { format } from 'prettier';
-import type {
- CommentDisplayPart,
- CommentTag,
- SignatureReflection,
-} from 'typedoc';
-import * as TypeDoc from 'typedoc';
-import prettierConfig from '../../.prettierrc.cjs';
-import {
- DefaultParameterAwareSerializer,
- parameterDefaultReader,
- patchProjectParameterDefaults,
-} from './parameterDefaults';
+
+// Types
export type Page = { text: string; link: string };
export type PageIndex = Array<Page>;
+// Paths
+
const pathRoot = resolve(__dirname, '..', '..');
export const pathDocsDir = resolve(pathRoot, 'docs');
export const pathOutputDir = resolve(pathDocsDir, 'api');
-/**
- * Creates and configures a new typedoc application.
- */
-export function newTypeDocApp(): TypeDoc.Application {
- const app = new TypeDoc.Application();
+// Functions
- app.options.addReader(new TypeDoc.TSConfigReader());
- // If you want TypeDoc to load typedoc.json files
- //app.options.addReader(new TypeDoc.TypeDocReader());
-
- // Read parameter defaults
- app.converter.on(
- TypeDoc.Converter.EVENT_CREATE_DECLARATION,
- parameterDefaultReader
+export function mapByName<T extends { name: string }, V>(
+ input: Array<T>,
+ valueExtractor: (item: T) => V
+): Record<string, V> {
+ return input.reduce(
+ (acc, item) => ({ ...acc, [item.name]: valueExtractor(item) }),
+ {}
);
- // Add to debug json output
- app.serializer.addSerializer(new DefaultParameterAwareSerializer());
-
- return app;
-}
-
-/**
- * Apply our patches to the generated typedoc data.
- *
- * This is moved to a separate method to allow printing/saving the original content before patching it.
- *
- * @param project The project to patch.
- */
-export function patchProject(project: TypeDoc.ProjectReflection): void {
- patchProjectParameterDefaults(project);
-}
-
-/**
- * Formats markdown contents.
- *
- * @param text The text to format.
- */
-export function formatMarkdown(text: string): string {
- return format(text, prettierMarkdown);
-}
-
-/**
- * Formats typedoc contents.
- *
- * @param text The text to format.
- */
-export function formatTypescript(text: string): string {
- return format(text, prettierTypescript);
-}
-
-const prettierMarkdown: Options = {
- ...prettierConfig,
- parser: 'markdown',
-};
-
-const prettierTypescript: Options = {
- ...prettierConfig,
- parser: 'typescript',
-};
-
-/**
- * Extracts the text (md) from a jsdoc tag.
- *
- * @param tag The tag to extract the text from.
- * @param signature The signature to extract the text from.
- */
-export function extractTagContent(
- tag: `@${string}`,
- signature?: SignatureReflection,
- tagProcessor: (tag: CommentTag) => string[] = joinTagContent
-): string[] {
- return signature?.comment?.getTags(tag).flatMap(tagProcessor) ?? [];
-}
-
-/**
- * Extracts the examples from the jsdocs without the surrounding md code block.
- *
- * @param signature The signature to extract the examples from.
- */
-export function extractRawExamples(signature?: SignatureReflection): string[] {
- return extractTagContent('@example', signature).map((tag) =>
- tag.replace(/^```ts\n/, '').replace(/\n```$/, '')
- );
-}
-
-/**
- * Extracts all the `@see` references from the jsdocs separately.
- *
- * @param signature The signature to extract the see also references from.
- */
-export function extractSeeAlsos(signature?: SignatureReflection): string[] {
- return extractTagContent('@see', signature, (tag) =>
- // If the @see tag contains code in backticks, the content is split into multiple parts.
- // So we join together, split on newlines and filter out empty tags.
- joinTagParts(tag.content)
- .split('\n')
- .map((link) => {
- link = link.trim();
- if (link.startsWith('-')) {
- link = link.slice(1).trim();
- }
-
- return link;
- })
- .filter((link) => link)
- );
-}
-
-/**
- * Joins the parts of the given jsdocs tag.
- */
-export function joinTagContent(tag: CommentTag): string[] {
- return [joinTagParts(tag?.content)];
-}
-
-export function joinTagParts(parts: CommentDisplayPart[]): string;
-export function joinTagParts(parts?: CommentDisplayPart[]): string | undefined;
-export function joinTagParts(parts?: CommentDisplayPart[]): string | undefined {
- return parts?.map((part) => part.text).join('');
-}
-
-/**
- * Checks if the given signature is deprecated.
- *
- * @param signature The signature to check.
- *
- * @returns `true` if it is deprecated, otherwise `false`.
- */
-export function isDeprecated(signature: SignatureReflection): boolean {
- return extractTagContent('@deprecated', signature).length > 0;
-}
-
-/**
- * Extracts the "since" tag from the provided signature.
- *
- * @param signature The signature to check.
- *
- * @returns the contents of the @since tag
- */
-export function extractSince(signature: SignatureReflection): string {
- return extractTagContent('@since', signature).join().trim();
}