Skip to content

Commit

Permalink
chore: Implemented nextra docs
Browse files Browse the repository at this point in the history
  • Loading branch information
tgreyuk committed Dec 11, 2023
1 parent 086dc53 commit dfbfd4b
Show file tree
Hide file tree
Showing 73 changed files with 8,612 additions and 12,794 deletions.
14 changes: 14 additions & 0 deletions dev-packages/prebuild-options/cli.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
#!/usr/bin/env ts-node

import { consola } from 'consola';
import { generateDocs } from './tasks/generate-docs';
import { generateModels } from './tasks/generate-models';
import { getPackageName } from './utils/constants';

main();

async function main() {
await generateModels();
await generateDocs();
consola.success(`[${getPackageName()}] Prebuild options complete`);
}
11 changes: 11 additions & 0 deletions dev-packages/prebuild-options/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"name": "@dev-packages/prebuild-options",
"version": "0.0.0",
"private": true,
"files": [
"/"
],
"bin": {
"prebuild-options": "cli.ts"
}
}
160 changes: 160 additions & 0 deletions dev-packages/prebuild-options/tasks/generate-docs.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,160 @@
import * as fs from 'fs';
import { groupBy } from 'lodash';
import * as path from 'path';
import { Project, VariableStatement } from 'ts-morph';
import { ParameterType } from 'typedoc';
import { DECLARATIONS_PATH, DOCS_PATH } from '../utils/constants';

export async function generateDocs() {
const optionsConfig: any = await import(DECLARATIONS_PATH);

const project = new Project({
tsConfigFilePath: 'tsconfig.json',
});

const configFileTs = project.getSourceFile(DECLARATIONS_PATH);

const optionsVariableStatements =
configFileTs?.getVariableStatements() as VariableStatement[];

const parsedConfig = Object.entries(optionsConfig).map(
([name, option]: any, i) => {
const docs = optionsVariableStatements[i].getJsDocs().map((doc) => {
return {
comments: (doc.getComment() as string)
?.replace(/\\\//g, '/')
.replace(/\\@/g, '@'),
tags: doc
.getTags()
.filter(
(tag) =>
tag.getTagName() !== 'category' &&
tag.getTagName() !== 'example',
)
.map((tag) => ({
name: tag.getTagName(),
comments: tag.getComment(),
})),
example: doc
.getTags()
.find((tag) => tag.getTagName() === 'example')
?.getComment(),
category:
doc
.getTags()
.find((tag) => tag.getTagName() === 'category')
?.getComment() || 'other',
};
})[0];
return {
name,
...option,
...(docs ? docs : { category: 'other' }),
};
},
);

const groupedConfig = groupBy(parsedConfig, 'category');

Object.entries(groupedConfig).forEach(([categoryName, options]) => {
const out: string[] = [];
out.push(`import { Callout } from 'nextra/components';`);
out.push(`# ${getDocsTitle(categoryName)}`);
options.forEach((option) => {
out.push(`## ${option.name}`);
out.push(`<Callout>${option.help}</Callout>`);
const meta: string[] = [];
const type = getType(option);
if (type) {
meta.push(type);
}
if (option.type !== ParameterType.Array) {
meta.push(`Defaults to \`${getDefaultValue(option)}\`.`);
}
out.push(`${meta.join(' ')}`);
out.push(`
\`\`\`json filename="typedoc.json"
{
"${option.name}": ${getExampleValue(option)}
}
\`\`\``);
if (option.comments?.length) {
out.push(option.comments);
option.tags?.forEach((tag) => {
out.push(`**${tag.name}**`);
out.push(tag.comments);
});
}
});

const optionDocPath = path.join(getDocsPath(), getDocsName(categoryName));

fs.writeFileSync(optionDocPath, out.join('\n\n'));
});
}

function getType(option: any) {
if (option.type === ParameterType.Array && option.defaultValue) {
return `Accepts an array of the following values ${option.defaultValue
.toString()
.split(',')
.map((item) => `\`"${item}"\``)
.join(' ')}.`;
}

if (option.type === ParameterType.Array) {
return 'Accepts an Array.';
}

if (option.type === ParameterType.Mixed) {
return 'Accepts a key/value Object.';
}

if (option.type === ParameterType.Map && option.map) {
const values = Object.values(option.map);
return `Accepts ${values.length === 2 ? 'either' : 'one of'} ${values
.map((value) => `\`"${value}"\``)
.join(` ${values.length === 2 ? 'or' : '|'} `)}.`;
}
return null;
}

function getDefaultValue(option) {
if (option.type === ParameterType.Boolean) {
return option.defaultValue;
}
if (option.type === ParameterType.Flags) {
return JSON.stringify(option.defaults);
}
if (option.type === ParameterType.Array) {
return '';
}
if (option.type === ParameterType.Mixed) {
return JSON.stringify(option.defaultValue);
}
return `"${option.defaultValue}"`;
}

function getExampleValue(option) {
if (option.example) {
return option.example;
}
return getDefaultValue(option);
}

function getDocsPath() {
const pagesPath = path.join(__dirname, '..', '..', '..', 'docs', 'pages');
const cwdParts = process.cwd().split(path.sep);
const packageName = cwdParts[cwdParts.length - 1];
return path.join(pagesPath, DOCS_PATH[packageName]);
}

function getDocsTitle(categoryName: string) {
return categoryName === 'other' ? `Options` : `${categoryName} Options`;
}

function getDocsName(categoryName: string) {
return categoryName === 'other'
? `options.mdx`
: `${categoryName.toLowerCase()}-options.mdx`;
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,49 +2,46 @@ import * as fs from 'fs';
import * as path from 'path';
import * as prettier from 'prettier';
import { DeclarationOption, ParameterType } from 'typedoc';
import * as optionsConfig from '../../src/plugin/options/config';
import { DECLARATIONS_PATH } from '../utils/constants';

/**
* Creates models for plugin options
*/

export async function generateModels() {
const optionsConfig = await import(DECLARATIONS_PATH);

export function prepareOptions() {
const optionsOutput = `
// THIS FILE IS AUTO GENERATED FROM THE OPTIONS CONFIG. DO NOT EDIT DIRECTLY.
declare module 'typedoc' {
export interface TypeDocOptionMap {
${Object.entries(optionsConfig)
.map(([key, option], i) => {
return `${option.name}: ${getType(option)};`;
})
${(Object.entries(optionsConfig) as any)
.map(([name, option]) => `${name}: ${getType(option)};`)
.join('\n')}
}
}
export interface PluginOptions {
${Object.entries(optionsConfig)
.map(([key, option], i) => {
return `${option.name}: ${getType(option)};`;
})
${(Object.entries(optionsConfig) as any)
.map(([name, option]) => `${name}: ${getType(option)};`)
.join('\n')}
}`;

const optionsModelFile = path.join(
__dirname,
'..',
'..',
process.cwd(),
'src',
'plugin',
'options',
'models.ts',
);

prettier
.format(optionsOutput, {
parser: 'typescript',
singleQuote: true,
trailingComma: 'all',
})
.then((formatted) => {
fs.writeFileSync(optionsModelFile, formatted);
});
const formatted = await prettier.format(optionsOutput, {
parser: 'typescript',
singleQuote: true,
trailingComma: 'all',
});

fs.writeFileSync(optionsModelFile, formatted);
}

function getType(option: Partial<DeclarationOption>) {
Expand All @@ -57,6 +54,9 @@ function getType(option: Partial<DeclarationOption>) {
if (option.type === ParameterType.Flags) {
return 'Record<string, boolean>';
}
if (option.type === ParameterType.Mixed) {
return 'any';
}
if (option.type === ParameterType.Map && option.map) {
return `${Object.values(option.map)
.map((value) => `"${value}"`)
Expand Down
22 changes: 22 additions & 0 deletions dev-packages/prebuild-options/utils/constants.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import * as path from 'path';

export const DECLARATIONS_PATH = `${process.cwd()}/src/options/declarations.ts`;

export const DOCS_PATH = {
['typedoc-plugin-markdown']: 'options',
['typedoc-plugin-frontmatter']: 'utilities/frontmatter',
};

export function getPackageName() {
const cwdParts = process.cwd().split(path.sep);
return cwdParts[cwdParts.length - 1];
}

export interface OptionDocument {
name: string;
comments: string;
tags: { name: string; comments: string }[];
example: string;
category: string;
help: string;
}
1 change: 1 addition & 0 deletions docs/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
.next
10 changes: 10 additions & 0 deletions docs/next.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
const withNextra = require('nextra')({
theme: 'nextra-theme-docs',
themeConfig: './theme.config.jsx',
defaultShowCopyCode: true,
});

module.exports = withNextra();

// If you have other Next.js configurations, you can pass them as the parameter:
// module.exports = withNextra({ /* other next.js config */ })
Loading

0 comments on commit dfbfd4b

Please sign in to comment.