Skip to content

Commit

Permalink
feat: generate-mdx, generate-registry
Browse files Browse the repository at this point in the history
  • Loading branch information
junghyeonsu committed Oct 2, 2024
1 parent b475431 commit fba42df
Show file tree
Hide file tree
Showing 4 changed files with 122 additions and 113 deletions.
8 changes: 5 additions & 3 deletions component-docs/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,11 @@
"private": true,
"type": "module",
"scripts": {
"dev": "yarn generate:registry && next dev",
"start": "yarn generate:registry && next start",
"build": "yarn generate:registry && next build",
"dev": "yarn generate:all && next dev",
"start": "yarn generate:all && next start",
"build": "yarn generate:all && next build",
"generate:all": "yarn generate:registry && yarn generate:mdx",
"generate:mdx": "node --no-warnings=ExperimentalWarning --loader ts-node/esm scripts/generate-mdx.ts",
"generate:registry": "node --no-warnings=ExperimentalWarning --loader ts-node/esm scripts/generate-registry.ts",
"watch:registry": "watchlist snippets -- yarn generate:registry"
},
Expand Down
69 changes: 69 additions & 0 deletions component-docs/scripts/generate-mdx.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
import chalk from "chalk";
import { existsSync, promises as fs, readFileSync } from "fs";
import path, { basename } from "node:path";

import { generateMDXTemplate } from "./utils/generate-mdx-template.js";

const PUBLIC_PATH = path.join(process.cwd(), "public");
const SNIPPETS_PATH = path.join(process.cwd(), "snippets");

interface GenerateMDXProps {
target: string;
}

async function generateMDX(props: GenerateMDXProps) {
const { target } = props;

const targetMDXPath = path.join(PUBLIC_PATH, "mdx");
const targetSnippetPath = path.join(SNIPPETS_PATH, "example", target);

if (!existsSync(targetMDXPath)) {
console.log(chalk.red(`[Generate Registry] ${chalk.bgRed(targetMDXPath)} dir does not exist!`));
await fs.mkdir(targetMDXPath, { recursive: true });
}

if (!existsSync(targetSnippetPath)) {
console.log(
chalk.red(`[Generate Registry] ${chalk.bgRed(targetSnippetPath)} dir does not exist!`),
);
await fs.mkdir(targetSnippetPath, { recursive: true });
}

const snippets = await fs.readdir(targetSnippetPath);
for (const snippet of snippets) {
const snippetPath = path.join(targetSnippetPath, snippet);

if (!existsSync(snippetPath)) {
console.log(
chalk.red(`[Generate Registry] ${chalk.bgRed(target)} Snippet file does not exist!`),
);
return null;
}

const content = readFileSync(snippetPath, "utf-8");
const code = generateMDXTemplate({
language: "tsx",
template: content,
copy: true,
});
const fileName = basename(snippet).split(".")[0];
const writeDir = path.join(targetMDXPath, target);

if (!existsSync(writeDir)) {
await fs.mkdir(writeDir, { recursive: true });
}

await fs.writeFile(path.join(writeDir, `${fileName}.mdx`), code, "utf-8");
}
}

function main() {
console.log(chalk.gray("Generate MDX..."));

generateMDX({ target: "react" });
generateMDX({ target: "stackflow" });

console.log(chalk.green("MDX Generated!"));
}

main();
115 changes: 5 additions & 110 deletions component-docs/scripts/generate-registry.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
import { existsSync, promises as fs, readFileSync, readdirSync, unlinkSync } from "fs";
import path, { basename, join } from "node:path";
import chalk from "chalk";
import { existsSync, promises as fs, readFileSync } from "fs";
import path, { basename } from "node:path";

import { match } from "ts-pattern";
import { dedent } from "ts-dedent";

// ts-node로 실행할 때 extension을 명시해주지 않으면 모듈을 찾지 못함.
import { componentMetadatas } from "../metadatas/component.js";

import { type ComponentMetadataSchema, componentRegistrySchema } from "../schemas/component.js";
import { componentRegistrySchema, type ComponentMetadataSchema } from "../schemas/component.js";
import { generateMDXTemplate } from "./utils/generate-mdx-template.js";

const REGISTRY_PATH = path.join(process.cwd(), "public/registry");
const PUBLIC_PATH = path.join(process.cwd(), "public");
Expand Down Expand Up @@ -62,6 +62,7 @@ async function generateRegistry({ metadatas, type }: GenerateRegistryProps) {
filename: `${metadata.name}.tsx`,
});

// Write MDX file
fs.writeFile(path.join(mdxTargetPath, `${metadata.name}.mdx`), template, "utf8");

return {
Expand Down Expand Up @@ -93,118 +94,12 @@ async function generateRegistry({ metadatas, type }: GenerateRegistryProps) {
}
}

async function generateMDXRegistry(targetPath: string) {
const targetMDXPath = path.join(PUBLIC_PATH, "mdx");
const targetSnippetPath = path.join(SNIPPETS_PATH, "example", targetPath);

if (!existsSync(targetMDXPath)) {
console.log(chalk.red(`[Generate Registry] ${chalk.bgRed(targetMDXPath)} dir does not exist!`));
await fs.mkdir(targetMDXPath, { recursive: true });
}

if (!existsSync(targetSnippetPath)) {
console.log(
chalk.red(`[Generate Registry] ${chalk.bgRed(targetSnippetPath)} dir does not exist!`),
);
await fs.mkdir(targetSnippetPath, { recursive: true });
}

const snippets = await fs.readdir(targetSnippetPath);
for (const snippet of snippets) {
const snippetPath = path.join(targetSnippetPath, snippet);

if (!existsSync(snippetPath)) {
console.log(
chalk.red(`[Generate Registry] ${chalk.bgRed(targetPath)} Snippet file does not exist!`),
);
return null;
}

const content = readFileSync(snippetPath, "utf-8");
const code = generateMDXTemplate({
language: "tsx",
template: content,
copy: true,
});
const fileName = basename(snippet).split(".")[0];
const writeDir = path.join(targetMDXPath, targetPath);

if (!existsSync(writeDir)) {
await fs.mkdir(writeDir, { recursive: true });
}

await fs.writeFile(path.join(writeDir, `${fileName}.mdx`), code, "utf-8");
}
}

interface GenerateMDXTemplateProps {
language: string;
template: string;

/**
* @example ["1", "2-5", "3"]
*/
highlightLines?: string[];

/**
* @example ["import", "export"]
*/
subStrings?: string[];

copy?: boolean;
showLineNumbers?: boolean;

/**
* @example "BoxButtonPreview.tsx"
*/
filename?: string;
}

function generateMDXTemplate(props: GenerateMDXTemplateProps) {
const { language, highlightLines, subStrings, copy, showLineNumbers, filename, template } = props;

const highlightLinesCode = highlightLines && `{${highlightLines.join(",")}}`;
const subStringsCode = subStrings && `/${subStrings.join(",")}/`;
const copyCode = copy && "copy";
const showLineNumbersCode = showLineNumbers && "showLineNumbers";
const filenameCode = filename && `filename="${filename}"`;
const metas = [highlightLinesCode, subStringsCode, copyCode, showLineNumbersCode, filenameCode]
.filter(Boolean)
.join(" ");

return dedent`
\`\`\`${language} ${metas}
${template}
\`\`\`\n
`;
}

// biome-ignore lint/correctness/noUnusedVariables: <explanation>
const deleteAllFilesInDir = (dirPath: string): void => {
if (!existsSync(dirPath)) {
console.log(`Directory ${dirPath} does not exist.`);
return;
}

try {
// biome-ignore lint/complexity/noForEach: <explanation>
readdirSync(dirPath).forEach((file) => {
unlinkSync(join(dirPath, file));
});
} catch (error) {
console.error(`Error while deleting files in directory ${dirPath}:`, error);
}
};

function main() {
console.log(chalk.gray("Generate Component Registry..."));

generateRegistryIndex({ metadatas: componentMetadatas, type: "component" });
generateRegistry({ metadatas: componentMetadatas, type: "component" });

generateMDXRegistry("react");
generateMDXRegistry("stackflow");

console.log(chalk.green("Component Registry Generated !"));
}

Expand Down
43 changes: 43 additions & 0 deletions component-docs/scripts/utils/generate-mdx-template.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import { dedent } from "ts-dedent";

interface GenerateMDXTemplateProps {
language: string;
template: string;

/**
* @example ["1", "2-5", "3"]
*/
highlightLines?: string[];

/**
* @example ["import", "export"]
*/
subStrings?: string[];

copy?: boolean;
showLineNumbers?: boolean;

/**
* @example "BoxButtonPreview.tsx"
*/
filename?: string;
}

export function generateMDXTemplate(props: GenerateMDXTemplateProps) {
const { language, highlightLines, subStrings, copy, showLineNumbers, filename, template } = props;

const highlightLinesCode = highlightLines && `{${highlightLines.join(",")}}`;
const subStringsCode = subStrings && `/${subStrings.join(",")}/`;
const copyCode = copy && "copy";
const showLineNumbersCode = showLineNumbers && "showLineNumbers";
const filenameCode = filename && `filename="${filename}"`;
const metas = [highlightLinesCode, subStringsCode, copyCode, showLineNumbersCode, filenameCode]
.filter(Boolean)
.join(" ");

return dedent`
\`\`\`${language} ${metas}
${template}
\`\`\`\n
`;
}

0 comments on commit fba42df

Please sign in to comment.