import fs from 'node:fs'
import path from 'node:path'
import { docs, type DocAction, type DocActionCollection, type DocActionGroup } from '../src/config/docs.config'
const rootDir = path.resolve(import.meta.dirname, '..')
const indexPath = path.join(rootDir, 'index.html')
const startMarker = ''
const endMarker = ''
function escapeHtml(value: string) {
return value
.replaceAll('&', '&')
.replaceAll('<', '<')
.replaceAll('>', '>')
.replaceAll('"', '"')
}
function isActionGroup(action: DocAction | DocActionGroup): action is DocActionGroup {
return 'actions' in action
}
function splitActionCollection(collection: DocActionCollection | undefined) {
if (!collection?.length) return { actions: [], groups: [] }
if (isActionGroup(collection[0])) {
const groups = collection as DocActionGroup[]
return {
actions: [],
groups: groups.filter((group) => group.actions.length > 0),
}
}
return {
actions: collection as DocAction[],
groups: [],
}
}
function renderLink(action: DocAction, type: 'download' | 'open') {
const attrs = [
`href="${escapeHtml(action.href)}"`,
type === 'open' ? 'target="_blank"' : '',
type === 'open' ? 'rel="noopener noreferrer"' : '',
type === 'download' ? 'download' : '',
].filter(Boolean).join(' ')
return `
${escapeHtml(action.label)}`
}
function renderActionList(actions: DocAction[], type: 'download' | 'open') {
return `${actions.map((action) => renderLink(action, type)).join('')}
`
}
function renderActionCollection(collection: DocActionCollection | undefined, title: string, type: 'download' | 'open') {
const { actions, groups } = splitActionCollection(collection)
if (actions.length === 0 && groups.length === 0) return ''
const content = groups.length > 0
? groups.map((group) => `
${escapeHtml(group.title)}
${renderActionList(group.actions, type)}
`).join('')
: actions.map((action) => renderLink(action, type)).join('')
return `
${title}
`
}
function renderDocLinks(title: string, links: DocAction[]) {
if (links.length === 0) return ''
return `
AI
${renderActionList(links, 'open')}
`
}
function renderDoc(doc: typeof docs[number]) {
const title = escapeHtml(doc.title)
const heading = doc.href ? `${title}` : title
const actionGroups = doc.actionGroups
const actions = [
renderActionCollection(actionGroups?.open, 'Открыть', 'open'),
renderActionCollection(actionGroups?.download, 'Скачать', 'download'),
doc.actionGroups ? '' : renderDocLinks(doc.title, doc.links),
].filter(Boolean).join('')
const actionBlock = actions ? `
` : ''
return `
${escapeHtml(doc.label)} · ${escapeHtml(doc.status)}
${heading}
${escapeHtml(doc.description)}
${actionBlock}
`
}
function renderStaticDocs() {
return `
Список документаций
${docs.map(renderDoc).join('')}
`
}
const indexHtml = fs.readFileSync(indexPath, 'utf8')
const startIndex = indexHtml.indexOf(startMarker)
const endIndex = indexHtml.indexOf(endMarker)
if (startIndex === -1 || endIndex === -1 || endIndex < startIndex) {
throw new Error(`Не найдены маркеры ${startMarker} / ${endMarker} в index.html`)
}
const nextIndexHtml = [
indexHtml.slice(0, startIndex + startMarker.length),
'\n ',
renderStaticDocs().replaceAll('\n', '\n '),
'\n ',
indexHtml.slice(endIndex),
].join('')
fs.writeFileSync(indexPath, nextIndexHtml, 'utf8')
console.log('Подготовлен static fallback в index.html')