From 7bd4c3ee41739d39a0f0259ede62769f160f8033 Mon Sep 17 00:00:00 2001 From: Eric Liu Date: Sun, 24 Nov 2024 12:13:42 -0800 Subject: [PATCH] build(scripts): format `COMPONENT_API.json` --- package.json | 2 +- scripts/format-component-api.js | 111 ++++++++++++++++++++++++++++++++ 2 files changed, 112 insertions(+), 1 deletion(-) create mode 100644 scripts/format-component-api.js diff --git a/package.json b/package.json index 175f2c45a5..32af01ac47 100644 --- a/package.json +++ b/package.json @@ -36,7 +36,7 @@ "test:types": "svelte-check --workspace tests", "lint": "prettier --write --cache \"**/*.{svelte,md,js,json,ts}\"", "build:css": "node scripts/build-css", - "build:docs": "node scripts/build-docs", + "build:docs": "node scripts/build-docs && node scripts/format-component-api", "postinstall": "ibmtelemetry --config=telemetry.yml", "release": "standard-version && npm run build:docs" }, diff --git a/scripts/format-component-api.js b/scripts/format-component-api.js new file mode 100644 index 0000000000..28f7078472 --- /dev/null +++ b/scripts/format-component-api.js @@ -0,0 +1,111 @@ +// @ts-check +import fs from "node:fs"; +import componentApi from "../docs/src/COMPONENT_API.json" assert { type: "json" }; +import { format } from "prettier"; +import plugin from "prettier/plugins/typescript"; + +const formatTypeScript = async (value) => { + return await format(value, { parser: "typescript", plugins: [plugin] }); +}; + +console.time("formatComponentApi"); + +let modified = { ...componentApi }; + +modified.components = await Promise.all( + componentApi.components.map(async (component) => { + component.props = await Promise.all( + component.props.map(async (prop) => { + if (!prop.value || !/\s{2,}/.test(prop.value)) { + return prop; + } + + let normalizedValue = prop.value; + let prefix = `const ${prop.name} = `; + + if (prop.isFunction || prop.value.startsWith("{")) { + normalizedValue = prefix + prop.value; + } + + const formatted = (await formatTypeScript(normalizedValue)) + // Remove prefix needed for formatting. + .replace(new RegExp(`^${prefix}`), "") + // Remove trailing semi-colon. + .replace(/;\s*$/, ""); + + return { + ...prop, + value: formatted, + }; + }), + ); + + component.typedefs = await Promise.all( + component.typedefs.map(async (typedef) => { + if (!typedef.ts) { + return typedef; + } + + return { + ...typedef, + ts: await formatTypeScript(typedef.ts), + }; + }), + ); + + component.events = await Promise.all( + component.events.map(async (event) => { + if (event.type === "forwarded") { + return event; + } + + let normalizedValue = `type EventDetail = ` + event.detail; + + const formatted = (await formatTypeScript(normalizedValue)) + // Remove prefix needed for formatting. + .replace(/type EventDetail = /, "") + // Remove trailing semi-colon. + .replace(/;\s*$/, ""); + + return { + ...event, + detail: formatted, + }; + }), + ); + + component.slots = await Promise.all( + component.slots.map(async (slot) => { + if (!slot.slot_props) { + return slot; + } + + let normalizedValue = slot.slot_props; + + if (normalizedValue.startsWith("{")) { + normalizedValue = `type SlotProps = ` + normalizedValue; + } + + const formatted = (await formatTypeScript(normalizedValue)) + // Remove prefix needed for formatting. + .replace(/type SlotProps = /, "") + // Remove trailing semi-colon. + .replace(/;\s*$/, ""); + + return { + ...slot, + slot_props: formatted, + }; + }), + ); + + return component; + }), +); + +fs.writeFileSync( + "./docs/src/COMPONENT_API.json", + JSON.stringify(modified, null, 2), +); + +console.timeEnd("formatComponentApi");