aboutsummaryrefslogtreecommitdiff
path: root/scripts
diff options
context:
space:
mode:
authorST-DDT <[email protected]>2024-12-28 04:25:06 +0100
committerGitHub <[email protected]>2024-12-28 03:25:06 +0000
commite6d27a353ec9c82e60b31c8d833768141beb4dab (patch)
treee9b728c03218d458149cb711909034170f61f3fd /scripts
parent817f8a01d93378e00c03cf73154fcec34fd5feef (diff)
downloadfaker-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.ts80
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';
+ }
+}