aboutsummaryrefslogtreecommitdiff
path: root/scripts/apidoc
diff options
context:
space:
mode:
authorST-DDT <[email protected]>2024-04-01 10:21:18 +0200
committerGitHub <[email protected]>2024-04-01 10:21:18 +0200
commit6191a5d883048b694404dbf42527caba395828ea (patch)
treed0f18f17789cb0bbdb5d6087f1a95772438dfe27 /scripts/apidoc
parent7dae52bfcd93c41ec9d2c4dd4d96a07f31c3dfc1 (diff)
downloadfaker-6191a5d883048b694404dbf42527caba395828ea.tar.xz
faker-6191a5d883048b694404dbf42527caba395828ea.zip
docs: rewrite api-docs generation using ts-morph (#2628)
Diffstat (limited to 'scripts/apidoc')
-rw-r--r--scripts/apidoc/diff.ts94
-rw-r--r--scripts/apidoc/faker-class.ts86
-rw-r--r--scripts/apidoc/faker-utilities.ts40
-rw-r--r--scripts/apidoc/format.ts31
-rw-r--r--scripts/apidoc/generate.ts42
-rw-r--r--scripts/apidoc/markdown.ts87
-rw-r--r--scripts/apidoc/module-methods.ts122
-rw-r--r--scripts/apidoc/parameter-defaults.ts136
-rw-r--r--scripts/apidoc/signature.ts365
-rw-r--r--scripts/apidoc/typedoc.ts421
-rw-r--r--scripts/apidoc/utils.ts79
-rw-r--r--scripts/apidoc/writer.ts249
12 files changed, 0 insertions, 1752 deletions
diff --git a/scripts/apidoc/diff.ts b/scripts/apidoc/diff.ts
deleted file mode 100644
index 101200cd..00000000
--- a/scripts/apidoc/diff.ts
+++ /dev/null
@@ -1,94 +0,0 @@
-import type { DocsApiDiffIndex } from './utils';
-import { nameDocsDiffIndexFile, pathDocsDiffIndexFile } from './utils';
-
-/**
- * Loads the diff index from the given source url.
- *
- * @param url The url to load the diff index from.
- */
-async function loadRemote(url: string): Promise<DocsApiDiffIndex> {
- return fetch(url).then((res) => {
- if (!res.ok) {
- throw new Error(
- `Failed to load remote diff index from ${url}: ${res.statusText}`
- );
- }
-
- return res.json() as Promise<DocsApiDiffIndex>;
- });
-}
-
-/**
- * Loads the diff index from the given local path.
- *
- * @param path The path to load the diff index from. Should start with `file://` for cross platform compatibility.
- */
-async function loadLocal(path: string): Promise<DocsApiDiffIndex> {
- return import(path).then((imp) => imp.default as DocsApiDiffIndex);
-}
-
-/**
- * Loads the diff index from the given source.
- * If the source starts with `https://` it will be loaded from the remote url.
- * Otherwise it will be loaded from the local path.
- *
- * @param source The source to load the diff index from.
- */
-async function load(source: string): Promise<DocsApiDiffIndex> {
- return source.startsWith('https://') ? loadRemote(source) : loadLocal(source);
-}
-
-/**
- * Returns a set of all keys from the given entries.
- *
- * @param entries The entries to get the keys from.
- */
-function allKeys(
- ...entries: ReadonlyArray<Record<string, unknown>>
-): Set<string> {
- return new Set(entries.flatMap(Object.keys));
-}
-
-/**
- * Compares the target (reference) and source (changed) diff index and returns the differences.
- * The returned object contains the module names as keys and the method names as values.
- * If the module name is `ADDED` or `REMOVED` it means that the module was added or removed in the local diff index.
- *
- * @param targetDiffIndex The url to the target (reference) diff index. Defaults to the next.fakerjs.dev diff index.
- * @param sourceDiffIndex The path to the source (changed) index. Defaults to the local diff index.
- */
-export async function diff(
- targetDiffIndex = `https://next.fakerjs.dev/${nameDocsDiffIndexFile}`,
- sourceDiffIndex = `file://${pathDocsDiffIndexFile}`
-): Promise<Record<string, ['ADDED'] | ['REMOVED'] | string[]>> {
- const target = await load(targetDiffIndex);
- const source = await load(sourceDiffIndex);
-
- const diff: Record<string, string[]> = {};
-
- for (const moduleName of allKeys(target, source)) {
- const remoteModule = target[moduleName];
- const localModule = source[moduleName];
-
- if (!remoteModule) {
- diff[moduleName] = ['ADDED'];
- continue;
- }
-
- if (!localModule) {
- diff[moduleName] = ['REMOVED'];
- continue;
- }
-
- for (const methodName of allKeys(remoteModule, localModule)) {
- const remoteMethod = remoteModule[methodName];
- const localMethod = localModule[methodName];
-
- if (remoteMethod !== localMethod) {
- (diff[moduleName] ??= []).push(methodName);
- }
- }
- }
-
- return diff;
-}
diff --git a/scripts/apidoc/faker-class.ts b/scripts/apidoc/faker-class.ts
deleted file mode 100644
index a9acad3c..00000000
--- a/scripts/apidoc/faker-class.ts
+++ /dev/null
@@ -1,86 +0,0 @@
-import type { DeclarationReflection, ProjectReflection } from 'typedoc';
-import { ReflectionKind } from 'typedoc';
-import type { Method } from '../../docs/.vitepress/components/api-docs/method';
-import { analyzeModule, processModuleMethods } from './module-methods';
-import { analyzeSignature } from './signature';
-import { extractModuleFieldName, selectApiSignature } from './typedoc';
-import type { ModuleSummary } from './utils';
-import { writeApiDocsModule } from './writer';
-
-export async function processFakerClasses(
- project: ProjectReflection
-): Promise<ModuleSummary[]> {
- const fakerClasses = project
- .getChildrenByKind(ReflectionKind.Class)
- .filter((clazz) => clazz.name === 'Faker' || clazz.name === 'SimpleFaker');
-
- if (fakerClasses.length !== 2) {
- throw new Error('Faker classes not found');
- }
-
- return Promise.all(fakerClasses.map(processClass));
-}
-
-export async function processFakerRandomizer(
- project: ProjectReflection
-): Promise<ModuleSummary> {
- const randomizerClass = project
- .getChildrenByKind(ReflectionKind.Interface)
- .find((clazz) => clazz.name === 'Randomizer');
-
- if (randomizerClass == null) {
- throw new Error('Randomizer class not found');
- }
-
- return processClass(randomizerClass);
-}
-
-async function processClass(
- clazz: DeclarationReflection
-): Promise<ModuleSummary> {
- const { name } = clazz;
- const moduleFieldName = extractModuleFieldName(clazz);
-
- console.log(`Processing ${name} class`);
-
- const { comment, deprecated, examples } = analyzeModule(clazz);
- const methods: Method[] = [];
-
- if (hasConstructor(clazz)) {
- console.debug(`- constructor`);
- methods.push(await processConstructor(clazz));
- }
-
- methods.push(...(await processModuleMethods(clazz, `${moduleFieldName}.`)));
-
- return writeApiDocsModule(
- name,
- moduleFieldName,
- comment,
- examples,
- deprecated,
- methods,
- ''
- );
-}
-
-function hasConstructor(clazz: DeclarationReflection): boolean {
- return clazz
- .getChildrenByKind(ReflectionKind.Constructor)
- .some((constructor) => (constructor.signatures?.length ?? 0) > 0);
-}
-
-async function processConstructor(
- clazz: DeclarationReflection
-): Promise<Method> {
- const constructor = clazz.getChildrenByKind(ReflectionKind.Constructor)[0];
-
- const signature = selectApiSignature(constructor);
-
- const method = await analyzeSignature(signature, '', `new ${clazz.name}`);
-
- return {
- ...method,
- name: 'constructor',
- };
-}
diff --git a/scripts/apidoc/faker-utilities.ts b/scripts/apidoc/faker-utilities.ts
deleted file mode 100644
index ad1f74c3..00000000
--- a/scripts/apidoc/faker-utilities.ts
+++ /dev/null
@@ -1,40 +0,0 @@
-import type { DeclarationReflection, ProjectReflection } from 'typedoc';
-import { ReflectionKind } from 'typedoc';
-import type { Method } from '../../docs/.vitepress/components/api-docs/method';
-import { processMethods } from './module-methods';
-import { selectApiSignature } from './typedoc';
-import type { ModuleSummary } from './utils';
-import { writeApiDocsModule } from './writer';
-
-export async function processFakerUtilities(
- project: ProjectReflection
-): Promise<ModuleSummary> {
- const fakerUtilities = project
- .getChildrenByKind(ReflectionKind.Function)
- .filter((method) => !method.flags.isPrivate);
-
- return processUtilities(fakerUtilities);
-}
-
-async function processUtilities(
- fakerUtilities: DeclarationReflection[]
-): Promise<ModuleSummary> {
- console.log(`Processing Faker Utilities`);
- const comment = 'A list of all the utilities available in Faker.js.';
-
- const methods: Method[] = await processMethods(
- Object.fromEntries(
- fakerUtilities.map((method) => [method.name, selectApiSignature(method)])
- )
- );
-
- return writeApiDocsModule(
- 'Utilities',
- 'utils',
- comment,
- undefined,
- undefined,
- methods,
- ''
- );
-}
diff --git a/scripts/apidoc/format.ts b/scripts/apidoc/format.ts
deleted file mode 100644
index a8f63ac0..00000000
--- a/scripts/apidoc/format.ts
+++ /dev/null
@@ -1,31 +0,0 @@
-import type { Options } from 'prettier';
-import { format } from 'prettier';
-import prettierConfig from '../../.prettierrc.js';
-
-/**
- * Formats markdown contents.
- *
- * @param text The text to format.
- */
-export async function formatMarkdown(text: string): Promise<string> {
- return format(text, prettierMarkdown);
-}
-
-/**
- * Formats typedoc contents.
- *
- * @param text The text to format.
- */
-export async function formatTypescript(text: string): Promise<string> {
- return format(text, prettierTypescript);
-}
-
-const prettierMarkdown: Options = {
- ...prettierConfig,
- parser: 'markdown',
-};
-
-const prettierTypescript: Options = {
- ...prettierConfig,
- parser: 'typescript',
-};
diff --git a/scripts/apidoc/generate.ts b/scripts/apidoc/generate.ts
deleted file mode 100644
index eb00cea4..00000000
--- a/scripts/apidoc/generate.ts
+++ /dev/null
@@ -1,42 +0,0 @@
-import { resolve } from 'node:path';
-import { processFakerClasses, processFakerRandomizer } from './faker-class';
-import { processFakerUtilities } from './faker-utilities';
-import { processModules } from './module-methods';
-import { loadProject } from './typedoc';
-import { pathOutputDir } from './utils';
-import {
- writeApiDiffIndex,
- writeApiPagesIndex,
- writeApiSearchIndex,
- writeSourceBaseUrl,
-} from './writer';
-
-const pathOutputJson = resolve(pathOutputDir, 'typedoc.json');
-
-/**
- * Generates the API documentation.
- */
-export async function generate(): Promise<void> {
- const [app, project] = await loadProject();
-
- // Useful for manually analyzing the content
- await app.generateJson(project, pathOutputJson);
-
- const pages = [
- ...(await processFakerClasses(project)),
- await processFakerRandomizer(project),
- await processFakerUtilities(project),
- ...(await processModules(project)).sort((a, b) =>
- a.text.localeCompare(b.text)
- ),
- ];
- await writeApiPagesIndex(
- pages.map(({ text, link, category }) => ({ text, link, category }))
- );
- writeApiDiffIndex(
- Object.fromEntries(pages.map(({ text, diff }) => [text, diff]))
- );
- writeApiSearchIndex(pages);
-
- await writeSourceBaseUrl(project);
-}
diff --git a/scripts/apidoc/markdown.ts b/scripts/apidoc/markdown.ts
deleted file mode 100644
index 0b1e3b40..00000000
--- a/scripts/apidoc/markdown.ts
+++ /dev/null
@@ -1,87 +0,0 @@
-import sanitizeHtml from 'sanitize-html';
-import type { MarkdownRenderer } from 'vitepress';
-import { createMarkdownRenderer } from 'vitepress';
-import vitepressConfig from '../../docs/.vitepress/config';
-import { adjustUrls, pathOutputDir } from './utils';
-
-let markdown: MarkdownRenderer;
-
-export async function initMarkdownRenderer(): Promise<void> {
- markdown = await createMarkdownRenderer(
- pathOutputDir,
- vitepressConfig.markdown,
- '/'
- );
-}
-
-const htmlSanitizeOptions: sanitizeHtml.IOptions = {
- allowedTags: [
- 'a',
- 'button',
- 'code',
- 'div',
- 'li',
- 'p',
- 'pre',
- 'span',
- 'strong',
- 'ul',
- ],
- allowedAttributes: {
- a: ['href', 'target', 'rel'],
- button: ['class', 'title'],
- div: ['class'],
- pre: ['class', 'tabindex', 'v-pre'],
- span: ['class', 'style'],
- },
- selfClosing: [],
-};
-
-function comparableSanitizedHtml(html: string): string {
- return html
- .replaceAll(/&#x[0-9A-F]{2};/g, (x) =>
- String.fromCodePoint(Number.parseInt(x.slice(3, -1), 16))
- )
- .replaceAll('&gt;', '>')
- .replaceAll('&lt;', '<')
- .replaceAll('&amp;', '&')
- .replaceAll('&quot;', '"')
- .replaceAll('=""', '')
- .replaceAll(' ', '');
-}
-
-/**
- * Converts a Typescript code block to an HTML string and sanitizes it.
- *
- * @param code The code to convert.
- *
- * @returns The converted HTML string.
- */
-export function codeToHtml(code: string): string {
- const delimiter = '```';
- return mdToHtml(`${delimiter}ts\n${code}\n${delimiter}`);
-}
-
-/**
- * Converts Markdown to an HTML string and sanitizes it.
- *
- * @param md The markdown to convert.
- * @param inline Whether to render the markdown as inline, without a wrapping `<p>` tag. Defaults to `false`.
- *
- * @returns The converted HTML string.
- */
-export function mdToHtml(md: string, inline: boolean = false): string {
- const rawHtml = inline ? markdown.renderInline(md) : markdown.render(md);
-
- const safeHtml: string = sanitizeHtml(rawHtml, htmlSanitizeOptions);
- // Revert some escaped characters for comparison.
- if (comparableSanitizedHtml(rawHtml) === comparableSanitizedHtml(safeHtml)) {
- return adjustUrls(safeHtml);
- }
-
- console.debug('Rejected unsafe md:', md);
- console.error('Rejected unsafe html:', rawHtml);
- console.error('Rejected unsafe html:', comparableSanitizedHtml(rawHtml));
- console.error('Expected safe html:', comparableSanitizedHtml(safeHtml));
- throw new Error('Found unsafe html');
-}
diff --git a/scripts/apidoc/module-methods.ts b/scripts/apidoc/module-methods.ts
deleted file mode 100644
index c21ccf97..00000000
--- a/scripts/apidoc/module-methods.ts
+++ /dev/null
@@ -1,122 +0,0 @@
-import type {
- DeclarationReflection,
- ProjectReflection,
- SignatureReflection,
-} from 'typedoc';
-import type { Method } from '../../docs/.vitepress/components/api-docs/method';
-import { codeToHtml } from './markdown';
-import { analyzeSignature } from './signature';
-import {
- extractDeprecated,
- extractDescription,
- extractJoinedRawExamples,
- extractModuleFieldName,
- extractModuleName,
- selectApiMethodSignatures,
- selectApiModules,
-} from './typedoc';
-import type { ModuleSummary } from './utils';
-import { adjustUrls } from './utils';
-import { writeApiDocsModule } from './writer';
-
-/**
- * Analyzes and writes the documentation for modules and their methods such as `faker.animal.cat()`.
- *
- * @param project The project used to extract the modules.
- *
- * @returns The generated pages.
- */
-export async function processModules(
- project: ProjectReflection
-): Promise<ModuleSummary[]> {
- return Promise.all(selectApiModules(project).map(processModule));
-}
-
-/**
- * Analyzes and writes the documentation for a module and its methods such as `faker.animal.cat()`.
- *
- * @param module The module to process.
- *
- * @returns The generated pages.
- */
-async function processModule(
- module: DeclarationReflection
-): Promise<ModuleSummary> {
- const moduleName = extractModuleName(module);
- console.log(`Processing Module ${moduleName}`);
- const moduleFieldName = extractModuleFieldName(module);
- const { comment, deprecated, examples } = analyzeModule(module);
- const methods = await processModuleMethods(
- module,
- `faker.${moduleFieldName}.`
- );
-
- return writeApiDocsModule(
- moduleName,
- moduleFieldName,
- comment,
- examples,
- deprecated,
- methods,
- 'Modules'
- );
-}
-
-/**
- * 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;
- examples: string | undefined;
-} {
- const examplesRaw = extractJoinedRawExamples(module);
- const examples = examplesRaw ? codeToHtml(examplesRaw) : undefined;
-
- return {
- comment: adjustUrls(extractDescription(module)),
- deprecated: extractDeprecated(module),
- examples,
- };
-}
-
-/**
- * Processes all api methods of the given class. This does not include the constructor.
- *
- * @param module The module to process.
- * @param accessor The code used to access the methods within the module.
- *
- * @returns A list containing the documentation for the api methods in the given module.
- */
-export async function processModuleMethods(
- module: DeclarationReflection,
- accessor: string
-): Promise<Method[]> {
- return processMethods(selectApiMethodSignatures(module), accessor);
-}
-
-/**
- * Processes all api methods.
- *
- * @param signatures The signatures to process.
- * @param accessor The code used to access the methods.
- *
- * @returns A list containing the documentation for the api methods.
- */
-export async function processMethods(
- signatures: Record<string, SignatureReflection>,
- accessor: string = ''
-): Promise<Method[]> {
- const methods: Method[] = [];
-
- for (const [methodName, signature] of Object.entries(signatures)) {
- console.debug(`- ${methodName}`);
- methods.push(await analyzeSignature(signature, accessor, methodName));
- }
-
- return methods;
-}
diff --git a/scripts/apidoc/parameter-defaults.ts b/scripts/apidoc/parameter-defaults.ts
deleted file mode 100644
index a7f53c2b..00000000
--- a/scripts/apidoc/parameter-defaults.ts
+++ /dev/null
@@ -1,136 +0,0 @@
-import type {
- Context,
- DeclarationReflection,
- EventCallback,
- JSONOutput,
- ProjectReflection,
- SerializerComponent,
- SignatureReflection,
-} from 'typedoc';
-import { Reflection, ReflectionKind, TypeScript } from 'typedoc';
-
-const reflectionKindFunctionOrMethod =
- ReflectionKind.Function | ReflectionKind.Method;
-
-interface ParameterDefaultsAware extends Reflection {
- implementationDefaultParameters: Array<string | undefined>;
-}
-
-/**
- * TypeDoc EventCallback for EVENT_CREATE_DECLARATION events that reads the default parameters from the implementation.
- *
- * @param context The converter context.
- * @param reflection The reflection to read the default parameters from.
- */
-export const parameterDefaultReader: EventCallback = (
- context: Context,
- reflection: Reflection
-): void => {
- const symbol = context.project.getSymbolFromReflection(reflection);
- if (!symbol) return;
-
- if (
- reflection.kindOf(reflectionKindFunctionOrMethod) &&
- symbol.declarations?.length
- ) {
- const lastDeclaration = symbol.declarations.at(-1);
- if (TypeScript.isFunctionLike(lastDeclaration)) {
- (reflection as ParameterDefaultsAware).implementationDefaultParameters =
- lastDeclaration.parameters.map((param) =>
- cleanParameterDefault(param.initializer?.getText())
- );
- }
- }
-};
-
-/**
- * Removes compile expressions that don't add any value for readers.
- *
- * @param value The default value to clean.
- *
- * @returns The cleaned default value.
- */
-function cleanParameterDefault(value: string): string;
-function cleanParameterDefault(value?: string): string | undefined;
-function cleanParameterDefault(value?: string): string | undefined {
- if (value == null) {
- return undefined;
- }
-
- // Strip type casts: "'foobar' as unknown as T" => "'foobar'"
- return value.replace(/( as unknown)? as [A-Za-z<>]+/, '');
-}
-
-/**
- * Serializer that adds the `implementationDefaultParameters` to the JSON output.
- */
-export class DefaultParameterAwareSerializer
- implements SerializerComponent<Reflection>
-{
- readonly priority = 0;
-
- supports(item: unknown): item is Reflection {
- return item instanceof Reflection;
- }
-
- toObject(
- item: Reflection,
- obj: Partial<JSONOutput.Reflection>
- ): Partial<JSONOutput.Reflection> {
- (obj as unknown as ParameterDefaultsAware).implementationDefaultParameters =
- (item as ParameterDefaultsAware).implementationDefaultParameters;
- return obj;
- }
-}
-
-/**
- * Replaces all methods' last signature's parameter's default value with the default value read from the implementation.
- *
- * @param project The project to patch.
- */
-export function patchProjectParameterDefaults(
- project: ProjectReflection
-): void {
- const functionOrMethods = project.getReflectionsByKind(
- reflectionKindFunctionOrMethod
- ) as DeclarationReflection[];
- for (const functionOrMethod of functionOrMethods) {
- patchMethodParameterDefaults(functionOrMethod);
- }
-}
-
-/**
- * Replaces the last signature's parameter's default value with the default value read from the implementation.
- *
- * @param method The method to patch.
- */
-function patchMethodParameterDefaults(method: DeclarationReflection): void {
- const signatures = method.signatures;
- const signature = signatures?.[signatures.length - 1];
- const parameterDefaults = (method as unknown as ParameterDefaultsAware)
- .implementationDefaultParameters;
- if (signature && parameterDefaults) {
- patchSignatureParameterDefaults(signature, parameterDefaults);
- }
-}
-
-/**
- * Replaces the given signature's parameter's default value with the given default values.
- *
- * @param signature The signature to patch.
- * @param parameterDefaults The defaults to add.
- */
-function patchSignatureParameterDefaults(
- signature: SignatureReflection,
- parameterDefaults: Array<string | undefined>
-): void {
- const signatureParameters =
- signature.parameters ?? Array.from({ length: parameterDefaults.length });
- if (signatureParameters.length !== parameterDefaults.length) {
- throw new Error('Unexpected parameter length mismatch');
- }
-
- for (const [index, param] of signatureParameters.entries()) {
- param.defaultValue = parameterDefaults[index] || param.defaultValue;
- }
-}
diff --git a/scripts/apidoc/signature.ts b/scripts/apidoc/signature.ts
deleted file mode 100644
index 64910534..00000000
--- a/scripts/apidoc/signature.ts
+++ /dev/null
@@ -1,365 +0,0 @@
-import type {
- Comment,
- DeclarationReflection,
- ParameterReflection,
- Reflection,
- ReflectionType,
- SignatureReflection,
- SomeType,
- Type,
-} from 'typedoc';
-import { ReflectionFlag, ReflectionKind } from 'typedoc';
-import type {
- Method,
- MethodParameter,
-} from '../../docs/.vitepress/components/api-docs/method';
-import { formatTypescript } from './format';
-import { codeToHtml, mdToHtml } from './markdown';
-import {
- extractDeprecated,
- extractDescription,
- extractJoinedRawExamples,
- extractRawDefault,
- extractSeeAlsos,
- extractSince,
- extractSourcePath,
- extractSummaryDefault,
- extractThrows,
- toBlock,
-} from './typedoc';
-
-export async function analyzeSignature(
- signature: SignatureReflection,
- accessor: string,
- methodName: string
-): Promise<Method> {
- const parameters: MethodParameter[] = [];
-
- // Collect Type Parameters
- const typeParameters = signature.typeParameters || [];
- const signatureTypeParameters: string[] = [];
- for (const parameter of typeParameters) {
- signatureTypeParameters.push(parameter.name);
- parameters.push({
- name: `<${parameter.name}>`,
- type: parameter.type ? await typeToText(parameter.type) : undefined,
- description: mdToHtml(extractDescription(parameter)),
- });
- }
-
- // Collect Parameters
- const signatureParameters: string[] = [];
- for (
- let index = 0;
- signature.parameters && index < signature.parameters.length;
- index++
- ) {
- const parameter = signature.parameters[index];
-
- const aParam = await analyzeParameter(parameter);
- signatureParameters.push(aParam.signature);
- parameters.push(...aParam.parameters);
- }
-
- // Generate usage section
-
- let signatureTypeParametersString = '';
- if (signatureTypeParameters.length > 0) {
- signatureTypeParametersString = `<${signatureTypeParameters.join(', ')}>`;
- }
-
- const signatureParametersString = signatureParameters.join(', ');
-
- let examples = `${accessor}${methodName}${signatureTypeParametersString}(${signatureParametersString}): ${signature.type?.toString()}\n`;
-
- const exampleTags = extractJoinedRawExamples(signature);
- if (exampleTags) {
- examples += exampleTags;
- }
-
- const seeAlsos = extractSeeAlsos(signature).map((seeAlso) =>
- mdToHtml(seeAlso, true)
- );
- const deprecatedMessage = extractDeprecated(signature);
- const deprecated = deprecatedMessage
- ? mdToHtml(deprecatedMessage)
- : undefined;
- const throwsMessage = extractThrows(signature);
- const throws = throwsMessage ? mdToHtml(throwsMessage, true) : undefined;
-
- return {
- name: methodName,
- description: mdToHtml(extractDescription(signature)),
- parameters: parameters,
- since: extractSince(signature),
- sourcePath: extractSourcePath(signature),
- throws,
- returns: await typeToText(signature.type),
- examples: codeToHtml(examples),
- deprecated,
- seeAlsos,
- };
-}
-
-async function analyzeParameter(parameter: ParameterReflection): Promise<{
- parameters: MethodParameter[];
- signature: string;
-}> {
- const name = parameter.name;
- const declarationName = name + (isOptional(parameter) ? '?' : '');
- const type = parameter.type;
- const defaultValue = extractDefaultFromParameter(parameter);
-
- let signatureText = '';
- if (defaultValue) {
- signatureText = ` = ${defaultValue}`;
- }
-
- const signature = `${declarationName}: ${await typeToText(
- type
- )}${signatureText}`;
-
- const parameters: MethodParameter[] = [
- {
- name: declarationName,
- type: await typeToText(type, true),
- default: defaultValue,
- description: mdToHtml(extractDescription(parameter)),
- },
- ];
- parameters.push(...(await analyzeParameterOptions(name, type)));
-
- return {
- parameters,
- signature,
- };
-}
-
-// keep in sync with assertNestedParameterDefault
-async function analyzeParameterOptions(
- name: string,
- parameterType?: SomeType
-): Promise<MethodParameter[]> {
- if (!parameterType) {
- return [];
- }
-
- switch (parameterType.type) {
- case 'array': {
- return analyzeParameterOptions(`${name}[]`, parameterType.elementType);
- }
-
- case 'union': {
- return Promise.all(
- parameterType.types.map((type) => analyzeParameterOptions(name, type))
- ).then((options) => options.flat());
- }
-
- case 'reflection': {
- const properties = parameterType.declaration.children ?? [];
- return Promise.all(
- properties.map(async (property) => {
- const reflection = property.comment
- ? property
- : (property.type as ReflectionType)?.declaration?.signatures?.[0];
- const comment = reflection?.comment;
- const deprecated = extractDeprecated(reflection);
- return {
- name: `${name}.${property.name}${isOptional(property) ? '?' : ''}`,
- type: await declarationTypeToText(property),
- default: extractDefaultFromComment(comment),
- description: mdToHtml(
- toBlock(comment) +
- (deprecated ? `\n\n**DEPRECATED:** ${deprecated}` : '')
- ),
- };
- })
- );
- }
-
- case 'typeOperator': {
- return analyzeParameterOptions(name, parameterType.target);
- }
-
- default: {
- return [];
- }
- }
-}
-
-function isOptional(parameter: Reflection): boolean {
- return parameter.flags.hasFlag(ReflectionFlag.Optional);
-}
-
-async function typeToText(type_?: Type, short = false): Promise<string> {
- if (!type_) {
- return '?';
- }
-
- const type = type_ as SomeType;
- switch (type.type) {
- case 'array': {
- const text = await typeToText(type.elementType, short);
- const isComplexType = text.includes('|') || text.includes('{');
- return isComplexType ? `Array<${text}>` : `${text}[]`;
- }
-
- case 'union': {
- return (await Promise.all(type.types.map((t) => typeToText(t, short))))
- .map((t) => (t.includes('=>') ? `(${t})` : t))
- .sort()
- .join(' | ');
- }
-
- case 'reference': {
- if (!type.typeArguments || type.typeArguments.length === 0) {
- const reflection = type.reflection as DeclarationReflection | undefined;
- const reflectionType = reflection?.type;
- if (
- (reflectionType?.type === 'literal' ||
- reflectionType?.type === 'union') &&
- !type.name.endsWith('Char')
- ) {
- return typeToText(reflectionType, short);
- }
-
- return type.name;
- } else if (type.name === 'LiteralUnion') {
- return [
- await typeToText(type.typeArguments[0], short),
- await typeToText(type.typeArguments[1], short),
- ].join(' | ');
- }
-
- return `${type.name}<${(
- await Promise.all(type.typeArguments.map((t) => typeToText(t, short)))
- ).join(', ')}>`;
- }
-
- case 'reflection': {
- return declarationTypeToText(type.declaration, short);
- }
-
- case 'indexedAccess': {
- return `${await typeToText(type.objectType, short)}[${await typeToText(
- type.indexType,
- short
- )}]`;
- }
-
- case 'literal': {
- return (await formatTypescript(type.toString())).replace(/;\n$/, '');
- }
-
- case 'typeOperator': {
- const text = await typeToText(type.target, short);
- if (short && type.operator === 'readonly') {
- return text;
- }
-
- return `${type.operator} ${text}`;
- }
-
- default: {
- return type.toString();
- }
- }
-}
-
-async function declarationTypeToText(
- declaration: DeclarationReflection,
- short = false
-): Promise<string> {
- switch (declaration.kind) {
- case ReflectionKind.Method: {
- return signatureTypeToText(declaration.signatures?.[0]);
- }
-
- case ReflectionKind.Property: {
- return typeToText(declaration.type);
- }
-
- case ReflectionKind.TypeLiteral: {
- if (declaration.children?.length) {
- if (short) {
- // This is too long for the parameter table, thus we abbreviate this.
- return '{ ... }';
- }
-
- const list = (
- await Promise.all(
- declaration.children.map(
- async (c) => ` ${c.name}: ${await declarationTypeToText(c)}`
- )
- )
- ).join(',\n');
-
- return `{\n${list}\n}`;
- } else if (declaration.signatures?.length) {
- return signatureTypeToText(declaration.signatures[0]);
- }
-
- return declaration.toString();
- }
-
- default: {
- return declaration.toString();
- }
- }
-}
-
-async function signatureTypeToText(
- signature?: SignatureReflection
-): Promise<string> {
- if (!signature) {
- return '(???) => ?';
- }
-
- return `(${(
- await Promise.all(
- signature.parameters?.map(
- async (p) => `${p.name}: ${await typeToText(p.type)}`
- ) ?? []
- )
- ).join(', ')}) => ${await typeToText(signature.type)}`;
-}
-
-/**
- * Extracts and optionally removes the parameter default from the parameter.
- *
- * @param parameter The parameter to extract the default from.
- * @param eraseDefault Whether to erase the default text from the parameter comment.
- *
- * @returns The extracted default value.
- */
-function extractDefaultFromParameter(
- parameter: ParameterReflection,
- eraseDefault = true
-): string | undefined {
- const commentDefault = extractDefaultFromComment(
- parameter.comment,
- eraseDefault
- );
- return parameter.defaultValue ?? commentDefault;
-}
-
-/**
- * Extracts and optionally removes the parameter default from the comments.
- *
- * @param comment The comment to extract the default from.
- * @param eraseDefault Whether to erase the default text from the comment.
- *
- * @returns The extracted default value.
- */
-function extractDefaultFromComment(
- comment?: Comment,
- eraseDefault = true
-): string | undefined {
- if (!comment) {
- return;
- }
-
- const tagDefault = extractRawDefault({ comment });
- const summaryDefault = extractSummaryDefault(comment, eraseDefault);
- return tagDefault || summaryDefault;
-}
diff --git a/scripts/apidoc/typedoc.ts b/scripts/apidoc/typedoc.ts
deleted file mode 100644
index 1cdcf3e1..00000000
--- a/scripts/apidoc/typedoc.ts
+++ /dev/null
@@ -1,421 +0,0 @@
-import type {
- Comment,
- CommentDisplayPart,
- CommentTag,
- DeclarationReflection,
- ProjectReflection,
- Reflection,
- SignatureReflection,
- TypeDocOptions,
-} from 'typedoc';
-import {
- Application,
- Converter,
- ReflectionKind,
- TSConfigReader,
-} from 'typedoc';
-import { faker } from '../../src';
-import {
- DefaultParameterAwareSerializer,
- parameterDefaultReader,
- patchProjectParameterDefaults,
-} from './parameter-defaults';
-import { mapByName } from './utils';
-
-type CommentHolder = Pick<Reflection, 'comment'>;
-
-/**
- * Loads the project using TypeDoc.
- *
- * @param options The options to use for the project.
- *
- * @returns The TypeDoc application and the project reflection.
- */
-export async function loadProject(
- options: Partial<TypeDocOptions> = {
- entryPoints: ['src/index.ts'],
- pretty: true,
- cleanOutputDir: true,
- tsconfig: 'tsconfig.build.json',
- }
-): Promise<[Application, ProjectReflection]> {
- const app = await newTypeDocApp(options);
-
- const project = await app.convert();
-
- if (!project) {
- throw new Error('Failed to convert project');
- }
-
- patchProjectParameterDefaults(project);
-
- return [app, project];
-}
-
-/**
- * Creates and configures a new typedoc application.
- *
- * @param options The options to use for the project.
- */
-async function newTypeDocApp(
- options?: Partial<TypeDocOptions>
-): Promise<Application> {
- const app = await Application.bootstrapWithPlugins(options, [
- new TSConfigReader(),
- ]);
-
- // Read parameter defaults
- app.converter.on(Converter.EVENT_CREATE_DECLARATION, parameterDefaultReader);
- // Add to debug json output
- app.serializer.addSerializer(new DefaultParameterAwareSerializer());
-
- return app;
-}
-
-/**
- * Selects the modules from the project that needs to be documented.
- *
- * @param project The project to extract the modules from.
- * @param includeTestModules Whether to include test modules.
- *
- * @returns The modules to document.
- */
-export function selectApiModules(
- project: ProjectReflection,
- includeTestModules = false
-): DeclarationReflection[] {
- return project
- .getChildrenByKind(ReflectionKind.Class)
- .filter(
- (module) =>
- faker[extractModuleFieldName(module) as keyof typeof faker] != 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)
- .filter((method) => !method.flags.isPrivate);
-}
-
-/**
- * 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.`);
- }
-
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
- return signatures.at(-1)!;
-}
-
-/**
- * Selects the method signatures from the module that needs to be documented.
- * Method-Name -> Method-Signature
- *
- * @param module 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[0].toLowerCase() + moduleName.substring(1);
-}
-
-export const MISSING_DESCRIPTION = 'Missing';
-
-export function toBlock(comment?: Comment): string {
- return joinTagParts(comment?.summary) || MISSING_DESCRIPTION;
-}
-
-export function extractDescription(reflection: Reflection): string {
- return toBlock(reflection.comment);
-}
-
-/**
- * Extracts the source url from the jsdocs.
- *
- * @param reflection The reflection instance to extract the source url from.
- */
-function extractSourceUrl(
- reflection: DeclarationReflection | SignatureReflection
-): string {
- const source = reflection.sources?.[0];
- return source?.url ?? '';
-}
-
-/**
- * Extracts the source base url from the jsdocs.
- *
- * @param reflection The reflection instance to extract the source base url from.
- */
-export function extractSourceBaseUrl(
- reflection: DeclarationReflection | SignatureReflection
-): string {
- return extractSourceUrl(reflection).replace(
- /^(.*\/blob\/[0-9a-f]+\/)(.*)$/,
- '$1'
- );
-}
-
-/**
- * Extracts the relative source path from the jsdocs.
- *
- * @param reflection The reflection instance to extract the source path from.
- */
-export function extractSourcePath(
- reflection: DeclarationReflection | SignatureReflection
-): string {
- return extractSourceUrl(reflection).replace(
- /^(.*\/blob\/[0-9a-f]+\/)(.*)$/,
- '$2'
- );
-}
-
-/**
- * Extracts the text (md) from a jsdoc tag.
- *
- * @param tag The tag to extract the text from.
- * @param reflection The reflection to extract the text from.
- * @param tagProcessor The function used to extract the text from the tag.
- */
-export function extractTagContent(
- tag: `@${string}`,
- reflection?: CommentHolder,
- tagProcessor: (tag: CommentTag) => string[] = joinTagContent
-): string[] {
- const tags =
- reflection?.comment
- ?.getTags(tag)
- .flatMap(tagProcessor)
- .map((tag) => tag.trim()) ?? [];
- if (tags.some((tag) => tag.length === 0)) {
- throw new Error(`Expected non-empty ${tag} tag.`);
- }
-
- return tags;
-}
-
-/**
- * Extracts the text (md) from a single jsdoc tag.
- *
- * @param tag The tag to extract the text from.
- * @param reflection The reflection to extract the text from.
- * @param tagProcessor The function used to extract the text from the tag.
- *
- * @throws If there are multiple tags of that type.
- */
-function extractSingleTagContent(
- tag: `@${string}`,
- reflection?: CommentHolder,
- tagProcessor: (tag: CommentTag) => string[] = joinTagContent
-): string | undefined {
- const tags = extractTagContent(tag, reflection, tagProcessor);
- if (tags.length === 0) {
- return undefined;
- } else if (tags.length === 1) {
- return tags[0];
- }
-
- throw new Error(`Expected 1 ${tag} tag, but got ${tags.length}.`);
-}
-
-/**
- * Extracts the raw code from the jsdocs without the surrounding md code block.
- *
- * @param tag The tag to extract the code from.
- * @param reflection The reflection to extract the code from.
- */
-function extractRawCode(
- tag: `@${string}`,
- reflection?: CommentHolder
-): string[] {
- return extractTagContent(tag, reflection).map((tag) =>
- tag.replace(/^```ts\n/, '').replace(/\n```$/, '')
- );
-}
-
-/**
- * Extracts the default from the jsdocs without the surrounding md code block.
- *
- * @param reflection The reflection to extract the examples from.
- */
-export function extractRawDefault(reflection?: CommentHolder): string {
- return extractRawCode('@default', reflection)[0] ?? '';
-}
-
-/**
- * Extracts and optionally removes the default from the comment summary.
- *
- * @param comment The comment to extract the default from.
- * @param eraseDefault Whether to erase the default text from the comment.
- *
- * @returns The extracted default value.
- */
-export function extractSummaryDefault(
- comment?: Comment,
- eraseDefault = true
-): string | undefined {
- if (!comment) {
- return;
- }
-
- const summary = comment.summary;
- const text = joinTagParts(summary).trim();
- if (!text) {
- return;
- }
-
- const result = /^(.*)[ \n]Defaults to `([^`]+)`\.(.*)$/s.exec(text);
- if (!result) {
- return;
- }
-
- if (result[3].trim()) {
- throw new Error(`Found description text after the default value:\n${text}`);
- }
-
- if (eraseDefault) {
- summary.splice(-2, 2);
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
- const lastSummaryPart = summary.at(-1)!;
- lastSummaryPart.text = lastSummaryPart.text.replace(
- /[ \n]Defaults to $/,
- ''
- );
- }
-
- return result[2];
-}
-
-/**
- * Extracts the examples from the jsdocs without the surrounding md code block.
- *
- * @param reflection The reflection to extract the examples from.
- */
-function extractRawExamples(reflection?: CommentHolder): string[] {
- return extractRawCode('@example', reflection);
-}
-
-/**
- * Extracts the examples from the jsdocs without the surrounding md code block, then joins them with newlines and trims.
- *
- * @param reflection The reflection to extract the examples from.
- */
-export function extractJoinedRawExamples(
- reflection?: CommentHolder
-): string | undefined {
- const examples = extractRawExamples(reflection);
- return examples.length === 0 ? undefined : examples.join('\n').trim();
-}
-
-/**
- * Extracts all the `@see` references from the jsdocs separately.
- *
- * @param reflection The reflection to extract the see also references from.
- */
-export function extractSeeAlsos(reflection?: CommentHolder): string[] {
- return extractTagContent('@see', reflection, (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).trimStart();
- }
-
- return link;
- })
- .filter((link) => link.length > 0)
- );
-}
-
-/**
- * Joins the parts of the given jsdocs tag.
- *
- * @param tag The tag to join the parts of.
- */
-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 reflection is deprecated.
- *
- * @param reflection The reflection to check.
- *
- * @returns The message explaining the deprecation if deprecated, otherwise `undefined`.
- */
-export function extractDeprecated(
- reflection?: CommentHolder
-): string | undefined {
- return extractSingleTagContent('@deprecated', reflection);
-}
-
-/**
- * Extracts the "throws" tag from the provided signature.
- *
- * @param reflection The reflection to check.
- *
- * @returns The message explaining the conditions when this method throws. Or `undefined` if it does not throw.
- */
-export function extractThrows(reflection?: CommentHolder): string | undefined {
- const content = extractTagContent('@throws', reflection).join('\n');
- return content.length === 0 ? undefined : content;
-}
-
-/**
- * Extracts the "since" tag from the provided signature.
- *
- * @param reflection The signature to check.
- *
- * @returns The contents of the `@since` tag.
- */
-export function extractSince(reflection: CommentHolder): string {
- return extractSingleTagContent('@since', reflection) || MISSING_DESCRIPTION;
-}
diff --git a/scripts/apidoc/utils.ts b/scripts/apidoc/utils.ts
deleted file mode 100644
index b23f3568..00000000
--- a/scripts/apidoc/utils.ts
+++ /dev/null
@@ -1,79 +0,0 @@
-import { createHash } from 'node:crypto';
-import { dirname, resolve } from 'node:path';
-import { fileURLToPath } from 'node:url';
-import type { Method } from '../../docs/.vitepress/components/api-docs/method';
-
-// Types
-
-export type Page = { text: string; link: string; category: string };
-
-export type ModuleSummary = Page & {
- methods: Method[];
- diff: DocsApiDiff;
-};
-
-export interface DocsApiDiffIndex {
- /**
- * The methods in the module by name.
- */
- [module: string]: DocsApiDiff;
-}
-
-export interface DocsApiDiff {
- /**
- * The checksum of the entire module.
- */
- moduleHash: string;
- /**
- * The checksum of the method by name.
- */
- [method: string]: string;
-}
-
-// Paths
-
-const pathRoot = resolve(dirname(fileURLToPath(import.meta.url)), '..', '..');
-export const pathDocsDir = resolve(pathRoot, 'docs');
-const pathPublicDir = resolve(pathDocsDir, 'public');
-export const nameDocsDiffIndexFile = 'api-diff-index.json';
-export const pathDocsDiffIndexFile = resolve(
- pathPublicDir,
- nameDocsDiffIndexFile
-);
-export const pathOutputDir = resolve(pathDocsDir, 'api');
-
-// Functions
-
-export function adjustUrls(description: string): string {
- return description.replaceAll(/https:\/\/(next.)?fakerjs.dev\//g, '/');
-}
-
-export function mapByName<TInput extends { name: string }, TValue>(
- input: TInput[],
- valueExtractor: (item: TInput) => TValue
-): Record<string, TValue> {
- return Object.fromEntries(
- input.map((item) => [item.name, valueExtractor(item)])
- );
-}
-
-/**
- * Creates a diff hash for the given method by removing the line number from the source path.
- *
- * @param method The method to create a hash for.
- */
-export function methodDiffHash(method: Method): string {
- return diffHash({
- ...method,
- sourcePath: method.sourcePath.replaceAll(/#.*/g, ''),
- });
-}
-
-/**
- * Creates a diff hash for the given object.
- *
- * @param object The object to create a hash for.
- */
-export function diffHash(object: unknown): string {
- return createHash('md5').update(JSON.stringify(object)).digest('hex');
-}
diff --git a/scripts/apidoc/writer.ts b/scripts/apidoc/writer.ts
deleted file mode 100644
index b03cfe85..00000000
--- a/scripts/apidoc/writer.ts
+++ /dev/null
@@ -1,249 +0,0 @@
-import { writeFileSync } from 'node:fs';
-import { resolve } from 'node:path';
-import type { ProjectReflection } from 'typedoc';
-import { ReflectionKind } from 'typedoc';
-import type { DefaultTheme } from 'vitepress';
-import type { Method } from '../../docs/.vitepress/components/api-docs/method';
-import type { APIGroup } from '../../docs/api/api-types';
-import { groupBy } from '../../src/internal/group-by';
-import { formatMarkdown, formatTypescript } from './format';
-import { extractSourceBaseUrl } from './typedoc';
-import type { DocsApiDiffIndex, ModuleSummary, Page } from './utils';
-import {
- diffHash,
- methodDiffHash,
- pathDocsDiffIndexFile,
- pathDocsDir,
- pathOutputDir,
-} from './utils';
-
-const pathDocsApiPages = resolve(pathDocsDir, '.vitepress', 'api-pages.ts');
-const pathDocsApiSearchIndex = resolve(
- pathDocsDir,
- 'api',
- 'api-search-index.json'
-);
-
-const scriptCommand = 'pnpm run generate:api-docs';
-
-// Moved here because this must not be formatted by prettier
-const vitePressInFileOptions = `---
-editLink: false
----
-
-`;
-
-/**
- * Writes the api docs for the given modules.
- *
- * @param moduleName The name of the module to write the docs for.
- * @param lowerModuleName The lowercase name of the module.
- * @param comment The module comments.
- * @param examples The example code.
- * @param deprecated The deprecation message.
- * @param methods The methods of the module.
- * @param category The category of the module.
- */
-export async function writeApiDocsModule(
- moduleName: string,
- lowerModuleName: string,
- comment: string,
- examples: string | undefined,
- deprecated: string | undefined,
- methods: Method[],
- category: string
-): Promise<ModuleSummary> {
- await writeApiDocsModulePage(
- moduleName,
- lowerModuleName,
- comment,
- examples,
- deprecated,
- methods
- );
- writeApiDocsModuleData(lowerModuleName, methods);
-
- return {
- text: moduleName,
- link: `/api/${lowerModuleName}.html`,
- methods,
- category,
- diff: {
- moduleHash: diffHash({
- name: moduleName,
- field: lowerModuleName,
- deprecated,
- comment,
- }),
- ...Object.fromEntries(
- methods.map((method) => [method.name, methodDiffHash(method)])
- ),
- },
- };
-}
-
-/**
- * Writes the api page for the given module to the correct location.
- *
- * @param moduleName The name of the module to write the docs for.
- * @param lowerModuleName The lowercase name of the module.
- * @param comment The module comments.
- * @param examples The example code.
- * @param deprecated The deprecation message.
- * @param methods The methods of the module.
- */
-async function writeApiDocsModulePage(
- moduleName: string,
- lowerModuleName: string,
- comment: string,
- examples: string | undefined,
- deprecated: string | undefined,
- methods: Method[]
-): Promise<void> {
- // Write api docs page
- let content = `
- <script setup>
- import ApiDocsMethod from '../.vitepress/components/api-docs/method.vue';
- import ${lowerModuleName} from './${lowerModuleName}.json';
- </script>
-
- <!-- This file is automatically generated. -->
- <!-- Run '${scriptCommand}' to update -->
-
- # ${moduleName}
-
- ::: v-pre
-
- ${
- deprecated == null
- ? ''
- : `<div class="warning custom-block">
- <p class="custom-block-title">Deprecated</p>
- <p>This module is deprecated and will be removed in a future version.</p>
- <span>${deprecated}</span>
- </div>`
- }
-
- ${comment}
-
- ${examples == null ? '' : `<div class="examples">${examples}</div>`}
-
- :::
-
- ${methods
- .map(
- (method) => `
- ## ${method.name}
-
- <ApiDocsMethod :method="${lowerModuleName}.${method.name}" v-once />
- `
- )
- .join('')}
- `.replaceAll(/\n +/g, '\n');
-
- content = vitePressInFileOptions + (await formatMarkdown(content));
-
- writeFileSync(resolve(pathOutputDir, `${lowerModuleName}.md`), content);
-}
-
-/**
- * Writes the api docs data to correct location.
- *
- * @param lowerModuleName The lowercase name of the module.
- * @param methods The methods data to save.
- */
-function writeApiDocsModuleData(
- lowerModuleName: string,
- methods: Method[]
-): void {
- const content = JSON.stringify(
- Object.fromEntries(methods.map((method) => [method.name, method]))
- );
-
- writeFileSync(resolve(pathOutputDir, `${lowerModuleName}.json`), content);
-}
-
-/**
- * Writes the api docs index to correct location.
- *
- * @param pages The pages to write into the index.
- */
-export async function writeApiPagesIndex(pages: Page[]): Promise<void> {
- const pagesByCategory: Record<string, DefaultTheme.SidebarItem[]> = groupBy(
- pages,
- (page) => page.category,
- ({ text, link }) => ({ text, link })
- );
- const pageTree = Object.entries(pagesByCategory).flatMap(
- ([category, items]) => (category ? [{ text: category, items }] : items)
- );
-
- // Write api-pages.ts
- console.log('Updating api-pages.ts');
- pageTree.splice(0, 0, { text: 'Overview', link: '/api/' });
- let apiPagesContent = `
- // This file is automatically generated.
- // Run '${scriptCommand}' to update
- export const apiPages = ${JSON.stringify(pageTree)};
- `.replace(/\n +/, '\n');
-
- apiPagesContent = await formatTypescript(apiPagesContent);
-
- writeFileSync(pathDocsApiPages, apiPagesContent);
-}
-
-/**
- * Writes the api diff index to the correct location.
- *
- * @param diffIndex The diff index project to write.
- */
-export function writeApiDiffIndex(diffIndex: DocsApiDiffIndex): void {
- writeFileSync(pathDocsDiffIndexFile, JSON.stringify(diffIndex));
-}
-
-/**
- * Writes the api search index to the correct location.
- *
- * @param pages The pages to write into the index.
- */
-export function writeApiSearchIndex(pages: ModuleSummary[]): void {
- const apiIndex: APIGroup[] = [
- {
- text: 'Module API',
- items: pages.map((module) => ({
- text: module.text,
- link: module.link,
- headers: module.methods.map((method) => ({
- anchor: method.name,
- text: method.name,
- deprecated: !!method.deprecated,
- })),
- })),
- },
- ];
-
- writeFileSync(pathDocsApiSearchIndex, JSON.stringify(apiIndex));
-}
-
-/**
- * Writes the source base url to the correct location.
- *
- * @param project The typedoc project.
- */
-export async function writeSourceBaseUrl(
- project: ProjectReflection
-): Promise<void> {
- const baseUrl = extractSourceBaseUrl(
- project.getChildrenByKind(ReflectionKind.Class)[0]
- );
-
- let content = `
- // This file is automatically generated.
- // Run '${scriptCommand}' to update
- export const sourceBaseUrl = '${baseUrl}';
- `.replace(/\n +/, '\n');
-
- content = await formatTypescript(content);
-
- writeFileSync(resolve(pathOutputDir, 'source-base-url.ts'), content);
-}