diff options
| author | ST-DDT <[email protected]> | 2024-12-28 04:25:06 +0100 |
|---|---|---|
| committer | GitHub <[email protected]> | 2024-12-28 03:25:06 +0000 |
| commit | e6d27a353ec9c82e60b31c8d833768141beb4dab (patch) | |
| tree | e9b728c03218d458149cb711909034170f61f3fd /scripts | |
| parent | 817f8a01d93378e00c03cf73154fcec34fd5feef (diff) | |
| download | faker-e6d27a353ec9c82e60b31c8d833768141beb4dab.tar.xz faker-e6d27a353ec9c82e60b31c8d833768141beb4dab.zip | |
docs(api): add refresh button to examples (#3301)
* docs(api): add refresh button to examples
* chore: improve button behavior slightly
* chore: improve output format
* chore: ignore examples without recordable results
* temp
* chore: use svg button
* chore: use json5 format for test
* chore: simplify result formatting
* test: add formatting tests
* test: add e2e refresh test
* test: use static test values
* chore: fix regex
* chore: simplify refresh placeholder
* Update cypress/e2e/example-refresh.cy.ts
* fix: handle property after function call
* Apply suggestions from code review
Co-authored-by: Shinigami <[email protected]>
* Apply suggestions from code review
Co-authored-by: Shinigami <[email protected]>
* Apply suggestions from code review
Co-authored-by: Shinigami <[email protected]>
* chore: format
* chore: add comment
---------
Co-authored-by: Shinigami <[email protected]>
Diffstat (limited to 'scripts')
| -rw-r--r-- | scripts/apidocs/output/page.ts | 80 |
1 files changed, 75 insertions, 5 deletions
diff --git a/scripts/apidocs/output/page.ts b/scripts/apidocs/output/page.ts index c00ba4d2..a9570309 100644 --- a/scripts/apidocs/output/page.ts +++ b/scripts/apidocs/output/page.ts @@ -33,7 +33,7 @@ export async function writePages(pages: RawApiDocsPage[]): Promise<void> { async function writePage(page: RawApiDocsPage): Promise<void> { try { await writePageMarkdown(page); - await writePageJsonData(page); + await writePageData(page); } catch (error) { throw new Error(`Error writing page ${page.title}`, { cause: error }); } @@ -51,7 +51,7 @@ async function writePageMarkdown(page: RawApiDocsPage): Promise<void> { let content = ` <script setup> import ApiDocsMethod from '../.vitepress/components/api-docs/method.vue'; - import ${camelTitle} from './${camelTitle}.json'; + import ${camelTitle} from './${camelTitle}.ts'; </script> <!-- This file is automatically generated. --> @@ -98,16 +98,33 @@ async function writePageMarkdown(page: RawApiDocsPage): Promise<void> { * * @param page The page to write. */ -async function writePageJsonData(page: RawApiDocsPage): Promise<void> { +async function writePageData(page: RawApiDocsPage): Promise<void> { const { camelTitle, methods } = page; const pageData: Record<string, ApiDocsMethod> = Object.fromEntries( await Promise.all( methods.map(async (method) => [method.name, await toMethodData(method)]) ) ); - const content = JSON.stringify(pageData, null, 2); - writeFileSync(resolve(FILE_PATH_API_DOCS, `${camelTitle}.json`), content); + const refreshFunctions: Record<string, string> = Object.fromEntries( + await Promise.all( + methods.map(async (method) => [ + method.name, + await toRefreshFunction(method), + ]) + ) + ); + + const content = + `export default ${JSON.stringify(pageData, undefined, 2)}`.replaceAll( + /"refresh-([^"-]+)-placeholder"/g, + (_, name) => refreshFunctions[name] + ); + + writeFileSync( + resolve(FILE_PATH_API_DOCS, `${camelTitle}.ts`), + await formatTypescript(content) + ); } const defaultCommentRegex = /\s+Defaults to `([^`]+)`\..*/; @@ -130,6 +147,12 @@ async function toMethodData(method: RawApiDocsMethod): Promise<ApiDocsMethod> { let formattedSignature = await formatTypescript(signature); formattedSignature = formattedSignature.trim(); + // eslint-disable-next-line @typescript-eslint/require-await + const refresh = async () => ['refresh', name, 'placeholder']; + // This is a placeholder to be replaced by the actual refresh function code + // If we put the actual code here, it would be a string and not executable + refresh.toJSON = () => `refresh-${name}-placeholder`; + /* Target order, omitted to improve diff to old files return { name, @@ -167,6 +190,7 @@ async function toMethodData(method: RawApiDocsMethod): Promise<ApiDocsMethod> { returns: returns.text, signature: codeToHtml(formattedSignature), examples: codeToHtml(examples.join('\n')), + refresh, deprecated: mdToHtml(deprecated), seeAlsos: seeAlsos.map((seeAlso) => mdToHtml(seeAlso, true)), }; @@ -175,3 +199,49 @@ async function toMethodData(method: RawApiDocsMethod): Promise<ApiDocsMethod> { export function extractSummaryDefault(description: string): string | undefined { return defaultCommentRegex.exec(description)?.[1]; } + +export async function toRefreshFunction( + method: RawApiDocsMethod +): Promise<string> { + const { name, signatures } = method; + const signatureData = required(signatures.at(-1), 'method signature'); + const { examples } = signatureData; + + const exampleCode = examples.join('\n'); + if (!/^\w*faker\w*\./im.test(exampleCode)) { + // No recordable faker calls in examples + return 'undefined'; + } + + const exampleLines = exampleCode + .replaceAll(/ ?\/\/.*$/gm, '') // Remove comments + .replaceAll(/^import .*$/gm, '') // Remove imports + .replaceAll( + // record results of faker calls + /^(\w*faker\w*\..+(?:(?:.|\n..)*\n[^ ])?\)(?:\.\w+)?);?$/gim, + `try { result.push($1); } catch (error: unknown) { result.push(error instanceof Error ? error.name : 'Error'); }\n` + ); + + const fullMethod = `async (): Promise<unknown[]> => { +await enableFaker(); +faker.seed(); +faker.setDefaultRefDate(); +const result: unknown[] = []; + +${exampleLines} + +return result; +}`; + try { + const formattedMethod = await formatTypescript(fullMethod); + return formattedMethod.replace(/;\s+$/, ''); // Remove trailing semicolon + } catch (error: unknown) { + console.error( + 'Failed to format refresh function for', + name, + fullMethod, + error + ); + return 'undefined'; + } +} |
