refactor: monorepo setup with lerna (#243)
This commit is contained in:
committed by
GitHub
parent
dac29fbf3c
commit
504d95c34f
5
packages/docs/src/lib/community.ts
Normal file
5
packages/docs/src/lib/community.ts
Normal file
@ -0,0 +1,5 @@
|
||||
import data from '../../content/community.json';
|
||||
|
||||
import type { CommunityData } from '../interface';
|
||||
|
||||
export default data as CommunityData;
|
5
packages/docs/src/lib/config.ts
Normal file
5
packages/docs/src/lib/config.ts
Normal file
@ -0,0 +1,5 @@
|
||||
import config from '../../content/config.json';
|
||||
|
||||
import type { SiteConfig } from '../interface';
|
||||
|
||||
export default config as SiteConfig;
|
179
packages/docs/src/lib/docs.ts
Normal file
179
packages/docs/src/lib/docs.ts
Normal file
@ -0,0 +1,179 @@
|
||||
import fs from 'fs';
|
||||
import matter from 'gray-matter';
|
||||
import yaml from 'js-yaml';
|
||||
import path from 'path';
|
||||
|
||||
import { getAnchor } from '../components/docs/components/headers/hooks/useAnchor';
|
||||
import { SUMMARY_MIN_PARAGRAPH_LENGTH } from '../constants';
|
||||
import menu from './menu';
|
||||
|
||||
import type { GetStaticProps } from 'next';
|
||||
import type {
|
||||
DocsData,
|
||||
DocsGroup,
|
||||
DocsGroupLink,
|
||||
DocsPage,
|
||||
FileMatter,
|
||||
SearchablePage,
|
||||
} from '../interface';
|
||||
|
||||
export interface SearchProps {
|
||||
searchablePages: SearchablePage[];
|
||||
}
|
||||
|
||||
export interface DocsMenuProps extends SearchProps {
|
||||
docsGroups: DocsGroup[];
|
||||
}
|
||||
|
||||
const docsDirectory = path.join(process.cwd(), 'content/docs');
|
||||
|
||||
let docsMatterCache: FileMatter[];
|
||||
let docsCache: [DocsPage[], DocsGroup[]];
|
||||
|
||||
export function fetchDocsMatter(): FileMatter[] {
|
||||
if (docsMatterCache && process.env.NODE_ENV !== 'development') {
|
||||
return docsMatterCache;
|
||||
}
|
||||
// Get file names under /docs
|
||||
const fileNames = fs.readdirSync(docsDirectory);
|
||||
const allDocsMatter = fileNames
|
||||
.filter(it => it.endsWith('.mdx'))
|
||||
.map(fileName => {
|
||||
// Read file as string
|
||||
const fullPath = path.join(docsDirectory, fileName);
|
||||
const fileContents = fs.readFileSync(fullPath, 'utf8');
|
||||
|
||||
// Use gray-matter to parse the doc metadata section
|
||||
const matterResult = matter(fileContents, {
|
||||
engines: {
|
||||
yaml: s => yaml.load(s, { schema: yaml.JSON_SCHEMA }) as object,
|
||||
},
|
||||
});
|
||||
return { fileName, fullPath, matterResult };
|
||||
});
|
||||
|
||||
// Sort docs by date
|
||||
docsMatterCache = allDocsMatter.sort(
|
||||
(a, b) => a.matterResult.data.weight - b.matterResult.data.weight,
|
||||
);
|
||||
|
||||
return docsMatterCache;
|
||||
}
|
||||
|
||||
function getHeadings(content: string): string[] {
|
||||
const headingRegex = /^## ([^\n]+)/gm;
|
||||
let matches = headingRegex.exec(content);
|
||||
|
||||
const headings: string[] = [];
|
||||
while (matches && matches.length === 2) {
|
||||
headings.push(matches[1]);
|
||||
matches = headingRegex.exec(content);
|
||||
}
|
||||
|
||||
return headings;
|
||||
}
|
||||
|
||||
function getTextContent(content: string): string {
|
||||
const textContentRegex =
|
||||
/^(?:-|\*|\n)((?!```|<| |const|interface|export|import|let|var|CMS\.)(?:[`\-# {*]*)[a-zA-Z]+[^|\n]+)$/gm;
|
||||
let matches = textContentRegex.exec(content);
|
||||
|
||||
const paragraphs: string[] = [];
|
||||
while (matches && matches.length === 2) {
|
||||
paragraphs.push(
|
||||
matches[1]
|
||||
.replace(/(^- )|(`)|(^[#]+ )|(\*\*)|((?<= )_)|(^_)|(_(?=[ .]{1}))|(_$)/gm, '')
|
||||
.replace(/\[([^\]]+)\]\((?:[^)]+)\)/gm, '$1'),
|
||||
);
|
||||
matches = textContentRegex.exec(content);
|
||||
}
|
||||
|
||||
return paragraphs.join('\n');
|
||||
}
|
||||
|
||||
export function fetchDocsContent(): [DocsPage[], DocsGroup[]] {
|
||||
if (docsCache && process.env.NODE_ENV !== 'development') {
|
||||
return docsCache;
|
||||
}
|
||||
|
||||
const allDocsData: DocsPage[] = fetchDocsMatter().map(
|
||||
({ fileName, fullPath, matterResult: { data, content } }) => {
|
||||
const slug = fileName.replace(/\.mdx$/, '');
|
||||
|
||||
const summaryRegex = /^<p>([\w\W]+?)<\/p>/i;
|
||||
let summaryMatch = summaryRegex.exec(content);
|
||||
|
||||
const htmlSummaryRegex =
|
||||
/^([\s\n]*(?:<(?:p|ul|ol|h1|h2|h3|h4|h5|h6|div)>(?:[\s\S])*?<\/(?:p|ul|ol|h1|h2|h3|h4|h5|h6|div)>[\s\n]*){1,2})/i;
|
||||
if (
|
||||
!summaryMatch ||
|
||||
summaryMatch.length < 2 ||
|
||||
summaryMatch[1].length < SUMMARY_MIN_PARAGRAPH_LENGTH
|
||||
) {
|
||||
summaryMatch = htmlSummaryRegex.exec(content);
|
||||
}
|
||||
|
||||
return {
|
||||
fullPath,
|
||||
data: {
|
||||
...data,
|
||||
slug,
|
||||
} as DocsData,
|
||||
textContent: getTextContent(content),
|
||||
headings: getHeadings(content).map(heading => ({
|
||||
title: heading,
|
||||
anchor: getAnchor(heading),
|
||||
})),
|
||||
content,
|
||||
};
|
||||
},
|
||||
);
|
||||
|
||||
const pagesByGroup: Record<string, DocsGroupLink[]> = allDocsData.reduce((acc, doc) => {
|
||||
if (!(doc.data.group in acc)) {
|
||||
acc[doc.data.group] = [];
|
||||
}
|
||||
acc[doc.data.group].push({
|
||||
title: doc.data.title,
|
||||
slug: doc.data.slug,
|
||||
});
|
||||
return acc;
|
||||
}, {} as Record<string, DocsGroupLink[]>);
|
||||
|
||||
const docsGroups: DocsGroup[] = menu.docs.map(group => ({
|
||||
...group,
|
||||
links: pagesByGroup[group.name] ?? [],
|
||||
}));
|
||||
|
||||
docsCache = [allDocsData, docsGroups];
|
||||
|
||||
return docsCache;
|
||||
}
|
||||
|
||||
export function getSearchablePages(): SearchablePage[] {
|
||||
const pages = fetchDocsContent()[0];
|
||||
|
||||
return pages.map(page => ({
|
||||
title: page.data.title,
|
||||
textContent: page.textContent,
|
||||
url: `/docs/${page.data.slug}`,
|
||||
headings: page.headings,
|
||||
}));
|
||||
}
|
||||
|
||||
export const getSearchStaticProps: GetStaticProps = (): { props: SearchProps } => {
|
||||
return {
|
||||
props: {
|
||||
searchablePages: getSearchablePages(),
|
||||
},
|
||||
};
|
||||
};
|
||||
|
||||
export const getDocsMenuStaticProps: GetStaticProps = (): { props: DocsMenuProps } => {
|
||||
return {
|
||||
props: {
|
||||
docsGroups: fetchDocsContent()[1],
|
||||
searchablePages: getSearchablePages(),
|
||||
},
|
||||
};
|
||||
};
|
5
packages/docs/src/lib/homepage.ts
Normal file
5
packages/docs/src/lib/homepage.ts
Normal file
@ -0,0 +1,5 @@
|
||||
import data from '../../content/homepage.json';
|
||||
|
||||
import type { HomepageData } from '../interface';
|
||||
|
||||
export default data as HomepageData;
|
5
packages/docs/src/lib/menu.ts
Normal file
5
packages/docs/src/lib/menu.ts
Normal file
@ -0,0 +1,5 @@
|
||||
import data from '../../content/menu.json';
|
||||
|
||||
import type { Menu } from '../interface';
|
||||
|
||||
export default data.menu as Menu;
|
5
packages/docs/src/lib/releases.ts
Normal file
5
packages/docs/src/lib/releases.ts
Normal file
@ -0,0 +1,5 @@
|
||||
import data from '../../content/releases.json';
|
||||
|
||||
import type { Release } from '../interface';
|
||||
|
||||
export default data.releases as Release[];
|
Reference in New Issue
Block a user