fix: исправить ссылки llms на markdown-файлы
- обновлены ссылки llms.txt на доступные .md-файлы - добавлено копирование markdown-файлов в публичную статику - исключена docs/public из сканирования VitePress и индекса Git - добавлена пометка для локальной копии ARCHITECTURE.md
This commit is contained in:
2
.gitignore
vendored
2
.gitignore
vendored
@@ -135,6 +135,7 @@ dist
|
||||
.vitepress/cache
|
||||
.vitepress/dist
|
||||
docs/.vitepress
|
||||
docs/public/
|
||||
|
||||
# Generated artifacts
|
||||
public/docs/
|
||||
@@ -149,4 +150,3 @@ dist
|
||||
# Рабочие заметки
|
||||
notes
|
||||
|
||||
|
||||
|
||||
@@ -14,6 +14,7 @@ const sidebar = [
|
||||
|
||||
export default defineConfig({
|
||||
srcDir: 'docs',
|
||||
srcExclude: ['public/**'],
|
||||
outDir: 'public/docs',
|
||||
title: 'SLM Design',
|
||||
description: 'Правила и стандарты архитектуры проекта',
|
||||
|
||||
60
generate.ts
60
generate.ts
@@ -5,7 +5,12 @@ import { execFileSync } from "child_process";
|
||||
|
||||
const SRC_DIR = "./docs";
|
||||
const PUBLIC_DIR = "./public";
|
||||
const DOCS_PUBLIC_DIR = path.join(SRC_DIR, "public");
|
||||
const DOC_ROUTE_PREFIX = "/docs";
|
||||
const PUBLIC_ARCHITECTURE_FILE = "ARCHITECTURE.md";
|
||||
const PUBLIC_ARCHITECTURE_NOTICE = `> Локальная копия канонической спецификации SLM Design.
|
||||
> Источник: https://slm-design.gromlab.ru/ARCHITECTURE.md
|
||||
> Не редактировать вручную в этом проекте.`;
|
||||
|
||||
interface SidebarItem {
|
||||
text: string;
|
||||
@@ -43,15 +48,25 @@ function parseSidebar(): SidebarGroup[] {
|
||||
|
||||
const SIDEBAR = parseSidebar();
|
||||
|
||||
function linkToFileRel(link: string): string {
|
||||
const rel = link.replace(/^\//, "");
|
||||
if (rel === "" || rel.endsWith("/")) return `${rel}index.md`;
|
||||
return `${rel}.md`;
|
||||
}
|
||||
|
||||
function fileRelToRoute(file: string): string {
|
||||
const route = file.endsWith("/index.md")
|
||||
? file.replace(/index\.md$/, "")
|
||||
: file.replace(/\.md$/, "");
|
||||
return `${DOC_ROUTE_PREFIX}/${route}`;
|
||||
}
|
||||
|
||||
function fileRelToMdUrl(file: string): string {
|
||||
return `${DOC_ROUTE_PREFIX}/${file}`;
|
||||
}
|
||||
|
||||
function getAllFiles(): string[] {
|
||||
return SIDEBAR.flatMap((g) =>
|
||||
g.items.map((item) => {
|
||||
const rel = item.link.replace(/^\//, "") + ".md";
|
||||
const indexPath = rel.replace(/\.md$/, "/index.md");
|
||||
const filePath = path.join(SRC_DIR, indexPath);
|
||||
return fs.existsSync(filePath) ? indexPath : rel;
|
||||
})
|
||||
);
|
||||
return SIDEBAR.flatMap((g) => g.items.map((item) => linkToFileRel(item.link)));
|
||||
}
|
||||
|
||||
const stripFrontmatter = (content: string) =>
|
||||
@@ -84,7 +99,7 @@ const buildArchitectureMarkdown = (routePrefix: string) => {
|
||||
const content = stripRulesLink(stripFrontmatter(raw)).trim();
|
||||
if (!content) continue;
|
||||
|
||||
const route = routePrefix + "/" + file.replace(/\.md$/, "");
|
||||
const route = routePrefix + fileRelToRoute(file).replace(DOC_ROUTE_PREFIX, "");
|
||||
const processed = file.endsWith("index.md") ? content : shiftHeadings(content);
|
||||
parts.push(`<!-- ${route} -->\n${processed}`);
|
||||
}
|
||||
@@ -99,9 +114,7 @@ function buildLlms() {
|
||||
for (const group of SIDEBAR) {
|
||||
parts.push(`## ${group.text}`);
|
||||
for (const item of group.items) {
|
||||
const rel = item.link.replace(/^\//, "") + ".md";
|
||||
const indexPath = rel.replace(/\.md$/, "/index.md");
|
||||
const fileRel = fs.existsSync(path.join(SRC_DIR, indexPath)) ? indexPath : rel;
|
||||
const fileRel = linkToFileRel(item.link);
|
||||
const filePath = path.join(SRC_DIR, fileRel);
|
||||
let desc = "";
|
||||
if (fs.existsSync(filePath)) {
|
||||
@@ -109,7 +122,7 @@ function buildLlms() {
|
||||
const fm = raw.match(/^---[\s\S]*?---\n*/m);
|
||||
desc = fm ? fm[0].match(/description:\s*(.+)/)?.[1] || "" : "";
|
||||
}
|
||||
const route = "/docs" + item.link;
|
||||
const route = fileRelToMdUrl(fileRel);
|
||||
const line = desc
|
||||
? `- [${item.text}](${route}): ${desc}`
|
||||
: `- [${item.text}](${route})`;
|
||||
@@ -130,10 +143,28 @@ function buildLlmsFull() {
|
||||
console.log(`llms-full.txt создан: ${outPath}`);
|
||||
}
|
||||
|
||||
function copyMarkdownFiles() {
|
||||
fs.rmSync(DOCS_PUBLIC_DIR, { recursive: true, force: true });
|
||||
|
||||
let copied = 0;
|
||||
for (const file of getAllFiles()) {
|
||||
const src = path.join(SRC_DIR, file);
|
||||
if (!fs.existsSync(src)) continue;
|
||||
|
||||
const dest = path.join(DOCS_PUBLIC_DIR, file);
|
||||
fs.mkdirSync(path.dirname(dest), { recursive: true });
|
||||
fs.copyFileSync(src, dest);
|
||||
copied++;
|
||||
}
|
||||
|
||||
console.log(`скопировано ${copied} .md-файлов в ${DOCS_PUBLIC_DIR}`);
|
||||
}
|
||||
|
||||
function buildPublicArchitecture() {
|
||||
const outPath = path.join(PUBLIC_DIR, PUBLIC_ARCHITECTURE_FILE);
|
||||
const content = `${PUBLIC_ARCHITECTURE_NOTICE}\n\n${buildArchitectureMarkdown("/docs")}`;
|
||||
fs.mkdirSync(PUBLIC_DIR, { recursive: true });
|
||||
fs.writeFileSync(outPath, buildArchitectureMarkdown("/docs"), "utf8");
|
||||
fs.writeFileSync(outPath, content, "utf8");
|
||||
console.log(`${PUBLIC_ARCHITECTURE_FILE} создан: ${outPath}`);
|
||||
}
|
||||
|
||||
@@ -180,6 +211,7 @@ function buildReadme() {
|
||||
|
||||
buildLlms();
|
||||
buildLlmsFull();
|
||||
copyMarkdownFiles();
|
||||
buildPublicArchitecture();
|
||||
buildZip();
|
||||
buildReadme();
|
||||
|
||||
@@ -1,4 +1,8 @@
|
||||
<!-- /docs/architecture//index -->
|
||||
> Локальная копия канонической спецификации SLM Design.
|
||||
> Источник: https://slm-design.gromlab.ru/ARCHITECTURE.md
|
||||
> Не редактировать вручную в этом проекте.
|
||||
|
||||
<!-- /docs/architecture/ -->
|
||||
# SLM Design
|
||||
Scoped Layered Module Design — модульная архитектура фронтенд-приложений. Код организован по слоям ответственности, а модуль содержит всё, что ему нужно: компоненты, хуки, сторы, типы, стили.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user