aboutsummaryrefslogtreecommitdiff
path: root/scripts
diff options
context:
space:
mode:
authorST-DDT <[email protected]>2022-03-01 19:55:53 +0100
committerGitHub <[email protected]>2022-03-01 19:55:53 +0100
commit61fafe47547873fcde74e98bff2a70738df7d4f2 (patch)
tree379432fee1ba309ba1a004bd37af04bba4628a79 /scripts
parent442812f66a5ad9a42e389ad1ae06dbbcddad4e99 (diff)
downloadfaker-61fafe47547873fcde74e98bff2a70738df7d4f2.tar.xz
faker-61fafe47547873fcde74e98bff2a70738df7d4f2.zip
docs: generate docs for fake() and unique() (#564)
Diffstat (limited to 'scripts')
-rw-r--r--scripts/apidoc.ts279
-rw-r--r--scripts/apidoc/apiDocsWriter.ts135
-rw-r--r--scripts/apidoc/directMethods.ts56
-rw-r--r--scripts/apidoc/moduleMethods.ts67
-rw-r--r--scripts/apidoc/signature.ts166
-rw-r--r--scripts/apidoc/utils.ts8
6 files changed, 443 insertions, 268 deletions
diff --git a/scripts/apidoc.ts b/scripts/apidoc.ts
index fd9ebcd0..cb4ed2a4 100644
--- a/scripts/apidoc.ts
+++ b/scripts/apidoc.ts
@@ -1,88 +1,13 @@
-import { writeFileSync } from 'fs';
import { resolve } from 'path';
-import type { Options } from 'prettier';
-import { format } from 'prettier';
-import sanitizeHtml from 'sanitize-html';
import * as TypeDoc from 'typedoc';
-import { createMarkdownRenderer } from 'vitepress';
-import prettierConfig from '../.prettierrc.cjs';
-import type {
- Method,
- MethodParameter,
-} from '../docs/.vitepress/components/api-docs/method';
-import faker from '../src';
-// TODO ST-DDT 2022-02-20: Actually import this/fix module import errors
-// import vitepressConfig from '../docs/.vitepress/config';
+import { writeApiPagesIndex } from './apidoc/apiDocsWriter';
+import { processDirectMethods } from './apidoc/directMethods';
+import { processModuleMethods } from './apidoc/moduleMethods';
+import type { PageIndex } from './apidoc/utils';
+import { pathOutputDir } from './apidoc/utils';
-const pathRoot = resolve(__dirname, '..');
-const pathDocsDir = resolve(pathRoot, 'docs');
-const pathDocsApiPages = resolve(pathDocsDir, '.vitepress', 'api-pages.mjs');
-const pathOutputDir = resolve(pathDocsDir, 'api');
const pathOutputJson = resolve(pathOutputDir, 'typedoc.json');
-const scriptCommand = 'pnpm run generate:api-docs';
-
-const markdown = createMarkdownRenderer(
- pathOutputDir
- // TODO ST-DDT 2022-02-20: Actually import this/fix module import errors
- // vitepressConfig.markdown
-);
-
-const prettierMarkdown: Options = {
- ...prettierConfig,
- parser: 'markdown',
-};
-
-const prettierTypescript: Options = {
- ...prettierConfig,
- parser: 'typescript',
-};
-
-const prettierBabel: Options = {
- ...prettierConfig,
- parser: 'babel',
-};
-
-const htmlSanitizeOptions: sanitizeHtml.IOptions = {
- allowedTags: ['a', 'code', 'div', 'li', 'span', 'p', 'pre', 'ul'],
- allowedAttributes: {
- a: ['href', 'target', 'rel'],
- div: ['class'],
- pre: ['v-pre'],
- span: ['class'],
- },
- selfClosing: [],
-};
-
-export function prettifyMethodName(method: string): string {
- return (
- // Capitalize and insert space before upper case characters
- method.substring(0, 1).toUpperCase() +
- method.substring(1).replace(/([A-Z]+)/g, ' $1')
- );
-}
-
-function toBlock(comment?: TypeDoc.Comment): string {
- return (
- (comment?.shortText.trim() || 'Missing') +
- (comment?.text ? '\n\n' + comment.text : '')
- );
-}
-
-function mdToHtml(md: string): string {
- const rawHtml = markdown.render(md);
- const safeHtml: string = sanitizeHtml(rawHtml, htmlSanitizeOptions);
- // Revert some escaped characters for comparison.
- if (rawHtml.replace(/&gt;/g, '>') === safeHtml.replace(/&gt;/g, '>')) {
- return safeHtml;
- } else {
- console.debug('Rejected unsafe md:', md);
- console.error('Rejected unsafe html:', rawHtml.replace(/&gt;/g, '>'));
- console.error('Expected safe html:', safeHtml.replace(/&gt;/g, '>'));
- throw new Error('Found unsafe html');
- }
-}
-
async function build(): Promise<void> {
const app = new TypeDoc.Application();
@@ -102,197 +27,15 @@ async function build(): Promise<void> {
// Project may not have converted correctly
return;
}
- // Useful for analyzing the content
+ // Useful for manually analyzing the content
await app.generateJson(project, pathOutputJson);
+ console.log(pathOutputDir);
- const modules = project
- .getChildrenByKind(TypeDoc.ReflectionKind.Namespace)[0]
- .getChildrenByKind(TypeDoc.ReflectionKind.Class);
-
- const modulesPages: Array<{ text: string; link: string }> = [];
- modulesPages.push({ text: 'Fake', link: '/api/fake.html' });
+ const modulesPages: PageIndex = [];
modulesPages.push({ text: 'Localization', link: '/api/localization.html' });
-
- // Generate module file
- for (const module of modules) {
- const moduleName = module.name.replace('_', '');
- const lowerModuleName =
- moduleName.substring(0, 1).toLowerCase() + moduleName.substring(1);
- if (faker[lowerModuleName] === undefined) {
- continue;
- }
- console.log(`Processing Module ${moduleName}`);
-
- modulesPages.push({
- text: moduleName,
- link: `/api/${lowerModuleName}.html`,
- });
-
- const methods: Method[] = [];
-
- // Generate method section
- for (const method of module.getChildrenByKind(
- TypeDoc.ReflectionKind.Method
- )) {
- const methodName = method.name;
- const prettyMethodName = prettifyMethodName(methodName);
- console.debug(`- method ${prettyMethodName}`);
- const signature = method.signatures[0];
-
- 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,
- description: mdToHtml(toBlock(parameter.comment)),
- });
- }
-
- // Collect Parameters
- const signatureParameters: string[] = [];
- let requiresArgs = false;
- for (
- let index = 0;
- signature.parameters && index < signature.parameters.length;
- index++
- ) {
- const parameter = signature.parameters[index];
-
- const parameterDefault = parameter.defaultValue;
- const parameterRequired = typeof parameterDefault === 'undefined';
- if (index === 0) {
- requiresArgs = parameterRequired;
- }
- const parameterName = parameter.name + (parameterRequired ? '?' : '');
- const parameterType = parameter.type.toString();
-
- let parameterDefaultSignatureText = '';
- if (!parameterRequired) {
- parameterDefaultSignatureText = ' = ' + parameterDefault;
- }
-
- signatureParameters.push(
- parameterName + ': ' + parameterType + parameterDefaultSignatureText
- );
- parameters.push({
- name: parameter.name,
- type: parameterType,
- default: parameterDefault,
- description: mdToHtml(toBlock(parameter.comment)),
- });
- }
-
- // Generate usage section
-
- let signatureTypeParametersString = '';
- if (signatureTypeParameters.length !== 0) {
- signatureTypeParametersString = `<${signatureTypeParameters.join(
- ', '
- )}>`;
- }
- const signatureParametersString = signatureParameters.join(', ');
-
- let examples = `faker.${lowerModuleName}.${methodName}${signatureTypeParametersString}(${signatureParametersString}): ${signature.type.toString()}\n`;
- faker.seed(0);
- if (!requiresArgs) {
- try {
- let example = JSON.stringify(faker[lowerModuleName][methodName]());
- if (example.length > 50) {
- example = example.substring(0, 47) + '...';
- }
-
- examples += `faker.${lowerModuleName}.${methodName}()`;
- examples += (example ? ` // => ${example}` : '') + '\n';
- } catch (error) {
- // Ignore the error => hide the example call + result.
- }
- }
- const exampleTags =
- signature?.comment?.tags
- .filter((tag) => tag.tagName === 'example')
- .map((tag) => tag.text.trimEnd()) || [];
-
- if (exampleTags.length > 0) {
- examples += exampleTags.join('\n').trim() + '\n';
- }
-
- const seeAlsos =
- signature.comment?.tags
- .filter((t) => t.tagName === 'see')
- .map((t) => t.text.trim()) ?? [];
-
- methods.push({
- name: methodName,
- title: prettyMethodName,
- description: mdToHtml(toBlock(signature.comment)),
- parameters: parameters,
- returns: signature.type.toString(),
- examples: mdToHtml('```ts\n' + examples + '```'),
- deprecated: signature.comment?.hasTag('deprecated') ?? false,
- seeAlsos,
- });
- }
-
- // Write api docs page
- let content = `
- <script setup>
- import ApiDocsMethod from '../.vitepress/components/api-docs/method.vue'
- import { ${lowerModuleName} } from './${lowerModuleName}'
- import { ref } from 'vue';
-
- const methods = ref(${lowerModuleName});
- </script>
-
- # ${moduleName}
-
- <!-- This file is automatically generated. -->
- <!-- Run '${scriptCommand}' to update -->
-
- ::: v-pre
-
- ${toBlock(module.comment)}
-
- :::
-
- <ApiDocsMethod v-for="method of methods" v-bind:key="method.name" :method="method" v-once />
- `.replace(/\n +/g, '\n');
-
- content = format(content, prettierMarkdown);
-
- writeFileSync(resolve(pathOutputDir, lowerModuleName + '.md'), content);
-
- // Write api docs data
-
- let contentTs = `
- import type { Method } from '../.vitepress/components/api-docs/method';
-
- export const ${lowerModuleName}: Method[] = ${JSON.stringify(
- methods,
- null,
- 2
- )}`;
-
- contentTs = format(contentTs, prettierTypescript);
-
- writeFileSync(resolve(pathOutputDir, lowerModuleName + '.ts'), contentTs);
- }
-
- // Write api-pages.mjs
- console.log('Updating api-pages.mjs');
- modulesPages.sort((a, b) => a.text.localeCompare(b.text));
- let apiPagesContent = `
- // This file is automatically generated.
- // Run '${scriptCommand}' to update
- export const apiPages = ${JSON.stringify(modulesPages)};
- `.replace(/\n +/, '\n');
-
- apiPagesContent = format(apiPagesContent, prettierBabel);
-
- writeFileSync(pathDocsApiPages, apiPagesContent);
+ modulesPages.push(...processModuleMethods(project));
+ modulesPages.push(...processDirectMethods(project));
+ writeApiPagesIndex(modulesPages);
}
build().catch(console.error);
diff --git a/scripts/apidoc/apiDocsWriter.ts b/scripts/apidoc/apiDocsWriter.ts
new file mode 100644
index 00000000..e2b42816
--- /dev/null
+++ b/scripts/apidoc/apiDocsWriter.ts
@@ -0,0 +1,135 @@
+import { writeFileSync } from 'node:fs';
+import { resolve } from 'node:path';
+import type { Options } from 'prettier';
+import { format } from 'prettier';
+import prettierConfig from '../../.prettierrc.cjs';
+import type { Method } from '../../docs/.vitepress/components/api-docs/method';
+import type { PageIndex } from './utils';
+import { pathDocsDir, pathOutputDir } from './utils';
+
+const pathDocsApiPages = resolve(pathDocsDir, '.vitepress', 'api-pages.mjs');
+
+const scriptCommand = 'pnpm run generate:api-docs';
+
+const prettierMarkdown: Options = {
+ ...prettierConfig,
+ parser: 'markdown',
+};
+
+const prettierTypescript: Options = {
+ ...prettierConfig,
+ parser: 'typescript',
+};
+
+const prettierBabel: Options = {
+ ...prettierConfig,
+ parser: 'babel',
+};
+
+/**
+ * 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.
+ */
+export function writeApiDocsModulePage(
+ moduleName: string,
+ lowerModuleName: string,
+ comment: string
+): void {
+ // Write api docs page
+ let content = `
+ <script setup>
+ import ApiDocsMethod from '../.vitepress/components/api-docs/method.vue'
+ import { ${lowerModuleName} } from './${lowerModuleName}'
+ import { ref } from 'vue';
+
+ const methods = ref(${lowerModuleName});
+ </script>
+
+ # ${moduleName}
+
+ <!-- This file is automatically generated. -->
+ <!-- Run '${scriptCommand}' to update -->
+
+ ::: v-pre
+
+ ${comment}
+
+ :::
+
+ <ApiDocsMethod v-for="method of methods" :key="method.name" :method="method" v-once />
+ `.replace(/\n +/g, '\n');
+
+ content = format(content, prettierMarkdown);
+
+ writeFileSync(resolve(pathOutputDir, lowerModuleName + '.md'), content);
+}
+
+/**
+ * Writes the api page for the given method to the correct location.
+ *
+ * @param methodName The name of the method to write the docs for.
+ */
+export function writeApiDocsDirectPage(methodName: string): void {
+ let content = `
+ <script setup>
+ import ApiDocsMethod from '../.vitepress/components/api-docs/method.vue'
+ import { ${methodName} } from './${methodName}'
+ import { ref } from 'vue';
+
+ const methods = ref(${methodName});
+ </script>
+
+ <ApiDocsMethod v-for="method of methods" :key="method.name" :method="method" v-once />
+ `.replace(/\n +/g, '\n');
+
+ content = format(content, prettierMarkdown);
+
+ writeFileSync(resolve(pathOutputDir, methodName + '.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.
+ */
+export function writeApiDocsData(
+ lowerModuleName: string,
+ methods: Method[]
+): void {
+ let contentTs = `
+import type { Method } from '../.vitepress/components/api-docs/method';
+
+export const ${lowerModuleName}: Method[] = ${JSON.stringify(
+ methods,
+ null,
+ 2
+ )}`;
+
+ contentTs = format(contentTs, prettierTypescript);
+
+ writeFileSync(resolve(pathOutputDir, lowerModuleName + '.ts'), contentTs);
+}
+
+/**
+ * Writes the api docs index to correct location.
+ *
+ * @param pages The pages to write into the index.
+ */
+export function writeApiPagesIndex(pages: PageIndex): void {
+ // Write api-pages.mjs
+ console.log('Updating api-pages.mjs');
+ pages.sort((a, b) => a.text.localeCompare(b.text));
+ let apiPagesContent = `
+ // This file is automatically generated.
+ // Run '${scriptCommand}' to update
+ export const apiPages = ${JSON.stringify(pages)};
+ `.replace(/\n +/, '\n');
+
+ apiPagesContent = format(apiPagesContent, prettierBabel);
+
+ writeFileSync(pathDocsApiPages, apiPagesContent);
+}
diff --git a/scripts/apidoc/directMethods.ts b/scripts/apidoc/directMethods.ts
new file mode 100644
index 00000000..616226ee
--- /dev/null
+++ b/scripts/apidoc/directMethods.ts
@@ -0,0 +1,56 @@
+import * as TypeDoc from 'typedoc';
+import { writeApiDocsData, writeApiDocsDirectPage } from './apiDocsWriter';
+import { analyzeSignature } from './signature';
+import type { Page, PageIndex } from './utils';
+
+/**
+ * Analyzes and writes the documentation for direct methods such as `faker.fake()`.
+ *
+ * @param project The project used to extract the direct methods.
+ * @returns The generated pages.
+ */
+export function processDirectMethods(
+ project: TypeDoc.ProjectReflection
+): PageIndex {
+ const pages: PageIndex = [];
+
+ const directs = project
+ .getChildrenByKind(TypeDoc.ReflectionKind.Class)
+ .filter((ref) => ref.name === 'Faker')[0]
+ .getChildrenByKind(TypeDoc.ReflectionKind.Property)
+ .filter((ref) => ['fake', 'unique'].includes(ref.name));
+
+ for (const direct of directs) {
+ pages.push(processDirectMethod(direct));
+ }
+
+ return pages;
+}
+
+/**
+ * Analyzes and writes the documentation for a direct method such as `faker.fake()`.
+ *
+ * @param direct The direct method to process.
+ * @returns The generated pages.
+ */
+export function processDirectMethod(
+ direct: TypeDoc.DeclarationReflection
+): Page {
+ const methodName = direct.name;
+ const upperMethodName =
+ methodName.substring(0, 1).toUpperCase() + methodName.substring(1);
+ console.log(`Processing Direct: ${upperMethodName}`);
+
+ const signature = (direct.type as TypeDoc.ReflectionType).declaration
+ .signatures[0];
+
+ writeApiDocsDirectPage(methodName);
+ writeApiDocsData(methodName, [
+ analyzeSignature(signature, undefined, methodName),
+ ]);
+
+ return {
+ text: upperMethodName,
+ link: `/api/${methodName}.html`,
+ };
+}
diff --git a/scripts/apidoc/moduleMethods.ts b/scripts/apidoc/moduleMethods.ts
new file mode 100644
index 00000000..89c42a33
--- /dev/null
+++ b/scripts/apidoc/moduleMethods.ts
@@ -0,0 +1,67 @@
+import * as TypeDoc 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 type { PageIndex } from './utils';
+
+/**
+ * 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 function processModuleMethods(
+ project: TypeDoc.ProjectReflection
+): PageIndex {
+ const modules = project
+ .getChildrenByKind(TypeDoc.ReflectionKind.Namespace)[0]
+ .getChildrenByKind(TypeDoc.ReflectionKind.Class);
+
+ const pages: PageIndex = [];
+ // Generate module file
+ for (const module of modules) {
+ pages.push(...processModuleMethod(module));
+ }
+
+ return pages;
+}
+
+/**
+ * Analyzes and writes the documentation for a module and its methods such as `faker.animal.cat()`.
+ *
+ * @param direct The module to process.
+ * @returns The generated pages.
+ */
+function processModuleMethod(module: TypeDoc.DeclarationReflection): PageIndex {
+ const moduleName = module.name.replace('_', '');
+ const lowerModuleName =
+ moduleName.substring(0, 1).toLowerCase() + moduleName.substring(1);
+ if (faker[lowerModuleName] === undefined) {
+ return [];
+ }
+ console.log(`Processing Module ${moduleName}`);
+
+ const methods: Method[] = [];
+
+ // Generate method section
+ for (const method of module.getChildrenByKind(
+ TypeDoc.ReflectionKind.Method
+ )) {
+ const methodName = method.name;
+ console.debug(`- ${methodName}`);
+ const signature = method.signatures[0];
+
+ methods.push(analyzeSignature(signature, lowerModuleName, methodName));
+ }
+
+ writeApiDocsModulePage(moduleName, lowerModuleName, toBlock(module.comment));
+ writeApiDocsData(lowerModuleName, methods);
+
+ return [
+ {
+ text: moduleName,
+ link: `/api/${lowerModuleName}.html`,
+ },
+ ];
+}
diff --git a/scripts/apidoc/signature.ts b/scripts/apidoc/signature.ts
new file mode 100644
index 00000000..cd4e4e76
--- /dev/null
+++ b/scripts/apidoc/signature.ts
@@ -0,0 +1,166 @@
+import sanitizeHtml from 'sanitize-html';
+import type * as TypeDoc from 'typedoc';
+import { createMarkdownRenderer } from 'vitepress';
+import type {
+ Method,
+ MethodParameter,
+} from '../../docs/.vitepress/components/api-docs/method';
+import faker from '../../src';
+import { pathOutputDir } from './utils';
+// TODO ST-DDT 2022-02-20: Actually import this/fix module import errors
+// import vitepressConfig from '../../docs/.vitepress/config';
+
+export function prettifyMethodName(method: string): string {
+ return (
+ // Capitalize and insert space before upper case characters
+ method.substring(0, 1).toUpperCase() +
+ method.substring(1).replace(/([A-Z]+)/g, ' $1')
+ );
+}
+
+export function toBlock(comment?: TypeDoc.Comment): string {
+ return (
+ (comment?.shortText.trim() || 'Missing') +
+ (comment?.text ? '\n\n' + comment.text : '')
+ );
+}
+
+const markdown = createMarkdownRenderer(
+ pathOutputDir,
+ undefined,
+ // TODO ST-DDT 2022-02-20: Actually import this/fix module import errors
+ // vitepressConfig.markdown,
+ '/'
+);
+
+const htmlSanitizeOptions: sanitizeHtml.IOptions = {
+ allowedTags: ['a', 'code', 'div', 'li', 'span', 'p', 'pre', 'ul'],
+ allowedAttributes: {
+ a: ['href', 'target', 'rel'],
+ div: ['class'],
+ pre: ['v-pre'],
+ span: ['class'],
+ },
+ selfClosing: [],
+};
+
+function mdToHtml(md: string): string {
+ const rawHtml = markdown.render(md);
+ const safeHtml: string = sanitizeHtml(rawHtml, htmlSanitizeOptions);
+ // Revert some escaped characters for comparison.
+ if (rawHtml.replace(/&gt;/g, '>') === safeHtml.replace(/&gt;/g, '>')) {
+ return safeHtml;
+ } else {
+ console.debug('Rejected unsafe md:', md);
+ console.error('Rejected unsafe html:', rawHtml.replace(/&gt;/g, '>'));
+ console.error('Expected safe html:', safeHtml.replace(/&gt;/g, '>'));
+ throw new Error('Found unsafe html');
+ }
+}
+
+export function analyzeSignature(
+ signature: TypeDoc.SignatureReflection,
+ moduleName: string,
+ methodName: string
+): 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,
+ description: mdToHtml(toBlock(parameter.comment)),
+ });
+ }
+
+ // Collect Parameters
+ const signatureParameters: string[] = [];
+ let requiresArgs = false;
+ for (
+ let index = 0;
+ signature.parameters && index < signature.parameters.length;
+ index++
+ ) {
+ const parameter = signature.parameters[index];
+
+ const parameterDefault = parameter.defaultValue;
+ const parameterRequired = typeof parameterDefault === 'undefined';
+ if (index === 0) {
+ requiresArgs = parameterRequired;
+ }
+ const parameterName = parameter.name + (parameterRequired ? '?' : '');
+ const parameterType = parameter.type.toString();
+
+ let parameterDefaultSignatureText = '';
+ if (!parameterRequired) {
+ parameterDefaultSignatureText = ' = ' + parameterDefault;
+ }
+
+ signatureParameters.push(
+ parameterName + ': ' + parameterType + parameterDefaultSignatureText
+ );
+ parameters.push({
+ name: parameter.name,
+ type: parameterType,
+ default: parameterDefault,
+ description: mdToHtml(toBlock(parameter.comment)),
+ });
+ }
+
+ // Generate usage section
+
+ let signatureTypeParametersString = '';
+ if (signatureTypeParameters.length !== 0) {
+ signatureTypeParametersString = `<${signatureTypeParameters.join(', ')}>`;
+ }
+ const signatureParametersString = signatureParameters.join(', ');
+
+ let examples: string;
+ if (moduleName) {
+ examples = `faker.${moduleName}.${methodName}${signatureTypeParametersString}(${signatureParametersString}): ${signature.type.toString()}\n`;
+ } else {
+ examples = `faker.${methodName}${signatureTypeParametersString}(${signatureParametersString}): ${signature.type.toString()}\n`;
+ }
+ faker.seed(0);
+ if (!requiresArgs && moduleName) {
+ try {
+ let example = JSON.stringify(faker[moduleName][methodName]());
+ if (example.length > 50) {
+ example = example.substring(0, 47) + '...';
+ }
+
+ examples += `faker.${moduleName}.${methodName}()`;
+ examples += (example ? ` // => ${example}` : '') + '\n';
+ } catch (error) {
+ // Ignore the error => hide the example call + result.
+ }
+ }
+ const exampleTags =
+ signature?.comment?.tags
+ .filter((tag) => tag.tagName === 'example')
+ .map((tag) => tag.text.trimEnd()) || [];
+
+ if (exampleTags.length > 0) {
+ examples += exampleTags.join('\n').trim() + '\n';
+ }
+
+ const seeAlsos =
+ signature.comment?.tags
+ .filter((t) => t.tagName === 'see')
+ .map((t) => t.text.trim()) ?? [];
+
+ const prettyMethodName = prettifyMethodName(methodName);
+ return {
+ name: methodName,
+ title: prettyMethodName,
+ description: mdToHtml(toBlock(signature.comment)),
+ parameters: parameters,
+ returns: signature.type.toString(),
+ examples: mdToHtml('```ts\n' + examples + '```'),
+ deprecated: signature.comment?.hasTag('deprecated') ?? false,
+ seeAlsos,
+ };
+}
diff --git a/scripts/apidoc/utils.ts b/scripts/apidoc/utils.ts
new file mode 100644
index 00000000..ee38d58d
--- /dev/null
+++ b/scripts/apidoc/utils.ts
@@ -0,0 +1,8 @@
+import { resolve } from 'node:path';
+
+export type Page = { text: string; link: string };
+export type PageIndex = Array<Page>;
+
+const pathRoot = resolve(__dirname, '..', '..');
+export const pathDocsDir = resolve(pathRoot, 'docs');
+export const pathOutputDir = resolve(pathDocsDir, 'api');