Leading Service
Leading Service отвечает за обработку страниц оглавления (leading pages) в Diplodoc. Эти специальные страницы описывают разделы документации и содержат метаданные для них.
Основные возможности
- Обработка YAML-файлов с описанием разделов
- Управление метаданными разделов
- Поддержка шаблонов с условиями и подстановками
- Сбор и анализ зависимостей и ассетов
Получение доступа к сервису
export class Extension {
apply(program: Build) {
getBaseHooks(program).BeforeAnyRun.tap('MyExtension', (run) => {
// Получение сервиса из контекста
const {leading} = run;
// Получение хуков сервиса
const leadingHooks = getLeadingHooks(leading);
});
}
}
Доступные хуки
Plugins
Хук для регистрации плагинов обработки leading-страниц. Вызывается при инициализации сервиса.
leadingHooks.Plugins.tapPromise('MyExtension', async (plugins) => {
// plugins: Массив существующих плагинов
// Добавляем новый плагин
return [
...plugins,
{
name: 'my-plugin',
transform: (leading) => {
// Трансформация leading-страницы
return leading;
}
}
];
});
Loaded
Хук вызывается после загрузки и начальной обработки leading-страницы.
leadingHooks.Loaded.tapPromise('MyProcessor', async (leading, meta, path) => {
// leading: Загруженная leading-страница
// meta: Метаданные страницы
// path: Путь к файлу
// Обработка загруженной страницы
return leading;
});
Resolved
Хук вызывается после полного разрешения leading-страницы.
leadingHooks.Resolved.tapPromise('MyProcessor', async (leading, meta, path) => {
// leading: Разрешенная leading-страница
// meta: Метаданные страницы
// path: Путь к файлу
// Трансформация страницы
return leading;
});
Dump
Хук вызывается перед сохранением leading-страницы.
leadingHooks.Dump.tapPromise('MyProcessor', async (vfile) => {
// vfile: VFile с leading-страницей и метаданными
// Модификация перед сохранением
return vfile;
});
API сервиса
Метод init
Инициализирует сервис, загружая плагины.
await leadingService.init();
Метод load
Загружает и обрабатывает leading-страницу.
Параметры:
path: RelativePath
- относительный путь к файлу
Возвращает:
Promise<LeadingPage>
- промис с обработанной leading-страницей
Вызывает хуки:
Loaded
- после загрузки файлаResolved
- после полного разрешения страницы
const leading = await leadingService.load('path/to/leading.yaml');
Метод dump
Сохраняет leading-страницу.
Параметры:
path: RelativePath
- путь к файлуleading?: LeadingPage
- страница для сохранения (если не указана, загружается из файла)
Возвращает:
Promise<VFile<LeadingPage>>
- промис с VFile
Вызывает хуки:
Dump
- перед сохранением файла
const vfile = await leadingService.dump('path/to/leading.yaml', leading);
Метод walkLinks
Обходит все ссылки в leading-странице.
Параметры:
leading: LeadingPage | undefined
- leading-страницаwalker: (link: string) => string | void
- функция обработки ссылки
Возвращает:
LeadingPage | undefined
- модифицированная leading-страница или undefined
const modifiedLeading = leadingService.walkLinks(leading, (link) => {
// Модификация ссылки
return modifiedLink;
});
Метод deps
Получает зависимости leading-страницы.
Параметры:
path: RelativePath
- путь к файлу
Возвращает:
Promise<never[]>
- промис с массивом зависимостей
const deps = await leadingService.deps('path/to/leading.yaml');
Метод assets
Получает список ассетов leading-страницы.
Параметры:
path: RelativePath
- путь к файлу
Возвращает:
Promise<NormalizedPath[]>
- промис с массивом путей к ассетам
const assets = await leadingService.assets('path/to/leading.yaml');
Примеры использования
Добавление информации о разделе
export class Extension {
apply(program: Build) {
getBaseHooks(program).BeforeAnyRun.tap('SectionEnricher', (run) => {
const leadingHooks = getLeadingHooks(run.leading);
leadingHooks.Resolved.tapPromise('SectionEnricher', async (leading, meta, path) => {
// Получаем дополнительную информацию о разделе
const sectionInfo = await fetchSectionInfo(path);
return {
...leading,
title: sectionInfo.title,
description: sectionInfo.description,
meta: {
...leading.meta,
...sectionInfo.meta
}
};
});
});
}
}
Валидация метаданных раздела
export class Extension {
apply(program: Build) {
getBaseHooks(program).BeforeAnyRun.tap('MetadataValidator', (run) => {
const leadingHooks = getLeadingHooks(run.leading);
leadingHooks.Resolved.tapPromise('MetadataValidator', async (leading, meta, path) => {
// Проверяем обязательные поля
if (!leading.title) {
run.logger.warn(`Missing title in ${path}`);
}
// Проверяем корректность значений
validateSectionValues(leading);
return leading;
});
});
}
}
Интеграция с внешними системами
export class Extension {
constructor(private apiKey: string) {}
apply(program: Build) {
getBaseHooks(program).BeforeAnyRun.tap('ExternalIntegration', (run) => {
const leadingHooks = getLeadingHooks(run.leading);
leadingHooks.Resolved.tapPromise('ExternalIntegration', async (leading, meta, path) => {
// Получаем данные из внешней системы
const externalData = await this.fetchExternalData(
this.apiKey,
leading.title
);
return {
...leading,
meta: {
...leading.meta,
externalData
}
};
});
});
}
private async fetchExternalData(apiKey: string, sectionTitle: string) {
// Логика получения данных из внешней системы
}
}