format files

pull/4692/head
Okinea Dev 5 months ago
parent 673db7d4b6
commit 5c83259896
No known key found for this signature in database
GPG Key ID: 07944BC5E01E7B43

@ -122,7 +122,7 @@ export const shared = defineConfig({
), ),
firebase: 'logos:firebase' firebase: 'logos:firebase'
} }
}), })
] ]
}, },
llms: { llms: {

@ -243,7 +243,7 @@ export async function resolveSiteData(
scrollOffset: userConfig.scrollOffset ?? 134, scrollOffset: userConfig.scrollOffset ?? 134,
cleanUrls: !!userConfig.cleanUrls, cleanUrls: !!userConfig.cleanUrls,
contentProps: userConfig.contentProps, contentProps: userConfig.contentProps,
llms: userConfig.llms ?? false, llms: userConfig.llms ?? false
} }
} }

@ -9,7 +9,7 @@ import type {
LinksExtension, LinksExtension,
LlmstxtSettings, LlmstxtSettings,
PreparedFile, PreparedFile,
VitePressConfig, VitePressConfig
} from '../types' } from '../types'
import { generateTOC } from './toc' import { generateTOC } from './toc'
import { expandTemplate, extractTitle, generateMetadata } from './utils' import { expandTemplate, extractTitle, generateMetadata } from './utils'
@ -70,7 +70,7 @@ export interface GenerateLLMsTxtOptions {
*/ */
export async function generateLLMsTxt( export async function generateLLMsTxt(
preparedFiles: PreparedFile[], preparedFiles: PreparedFile[],
options: GenerateLLMsTxtOptions, options: GenerateLLMsTxtOptions
): Promise<string> { ): Promise<string> {
const { const {
indexMd, indexMd,
@ -81,7 +81,7 @@ export async function generateLLMsTxt(
domain, domain,
sidebar, sidebar,
linksExtension, linksExtension,
cleanUrls, cleanUrls
} = options } = options
// @ts-expect-error // @ts-expect-error
@ -119,7 +119,7 @@ export async function generateLLMsTxt(
domain, domain,
sidebarConfig: sidebar || vitepressConfig?.themeConfig?.sidebar, sidebarConfig: sidebar || vitepressConfig?.themeConfig?.sidebar,
linksExtension, linksExtension,
cleanUrls, cleanUrls
}) })
return expandTemplate(LLMsTxtTemplate, templateVariables) return expandTemplate(LLMsTxtTemplate, templateVariables)
@ -151,7 +151,7 @@ export interface GenerateLLMsFullTxtOptions {
*/ */
export function generateLLMsFullTxt( export function generateLLMsFullTxt(
preparedFiles: PreparedFile[], preparedFiles: PreparedFile[],
options: GenerateLLMsFullTxtOptions, options: GenerateLLMsFullTxtOptions
) { ) {
const { srcDir, domain, linksExtension, cleanUrls } = options const { srcDir, domain, linksExtension, cleanUrls } = options
@ -165,8 +165,8 @@ export function generateLLMsFullTxt(
domain, domain,
filePath: relativePath, filePath: relativePath,
linksExtension, linksExtension,
cleanUrls, cleanUrls
}), })
) )
}) })
.join('\n---\n\n') .join('\n---\n\n')

@ -37,7 +37,7 @@ const log = {
* @param message - The message to log. * @param message - The message to log.
*/ */
error: (message: string) => error: (message: string) =>
console.error(`${logPrefix}${pc.red('✗')} ${pc.red(message)}`), console.error(`${logPrefix}${pc.red('✗')} ${pc.red(message)}`)
} }
export default log export default log

@ -4,7 +4,7 @@ import type {
LinksExtension, LinksExtension,
LlmstxtSettings, LlmstxtSettings,
PreparedFile, PreparedFile,
VitePressConfig, VitePressConfig
} from '../types' } from '../types'
import { generateLink, stripExtPosix } from './utils' import { generateLink, stripExtPosix } from './utils'
@ -23,7 +23,7 @@ export const generateTOCLink = (
domain: LlmstxtSettings['domain'], domain: LlmstxtSettings['domain'],
relativePath: string, relativePath: string,
extension?: LinksExtension, extension?: LinksExtension,
cleanUrls: VitePressConfig['cleanUrls'] = false, cleanUrls: VitePressConfig['cleanUrls'] = false
) => { ) => {
const description: string = file.file.data.description const description: string = file.file.data.description
return `- [${file.title}](${generateLink(stripExtPosix(relativePath), domain, extension ?? '.md', cleanUrls)})${description ? `: ${description.trim()}` : ''}\n` return `- [${file.title}](${generateLink(stripExtPosix(relativePath), domain, extension ?? '.md', cleanUrls)})${description ? `: ${description.trim()}` : ''}\n`
@ -36,7 +36,7 @@ export const generateTOCLink = (
* @returns Array of paths collected from the sidebar items. * @returns Array of paths collected from the sidebar items.
*/ */
function collectPathsFromSidebarItems( function collectPathsFromSidebarItems(
items: DefaultTheme.SidebarItem[], items: DefaultTheme.SidebarItem[]
): string[] { ): string[] {
const paths: string[] = [] const paths: string[] = []
@ -106,7 +106,7 @@ async function processSidebarSection(
domain?: LlmstxtSettings['domain'], domain?: LlmstxtSettings['domain'],
linksExtension?: LinksExtension, linksExtension?: LinksExtension,
cleanUrls?: VitePressConfig['cleanUrls'], cleanUrls?: VitePressConfig['cleanUrls'],
depth = 3, depth = 3
): Promise<string> { ): Promise<string> {
let sectionTOC = '' let sectionTOC = ''
@ -133,7 +133,7 @@ async function processSidebarSection(
linksExtension, linksExtension,
cleanUrls, cleanUrls,
// Increase depth for nested sections to maintain proper heading levels // Increase depth for nested sections to maintain proper heading levels
depth + 1, depth + 1
) )
nestedSections.push(processedSection) nestedSections.push(processedSection)
} }
@ -155,12 +155,12 @@ async function processSidebarSection(
domain, domain,
relativePath, relativePath,
linksExtension, linksExtension,
cleanUrls, cleanUrls
), )
) )
} }
} }
}), })
) )
// Add link items if any // Add link items if any
@ -189,7 +189,7 @@ async function processSidebarSection(
* @returns An array of sidebar items. * @returns An array of sidebar items.
*/ */
function flattenSidebarConfig( function flattenSidebarConfig(
sidebarConfig: DefaultTheme.Sidebar, sidebarConfig: DefaultTheme.Sidebar
): DefaultTheme.SidebarItem[] { ): DefaultTheme.SidebarItem[] {
// If it's already an array, return as is // If it's already an array, return as is
if (Array.isArray(sidebarConfig)) { if (Array.isArray(sidebarConfig)) {
@ -245,7 +245,7 @@ export interface GenerateTOCOptions {
*/ */
export async function generateTOC( export async function generateTOC(
preparedFiles: PreparedFile[], preparedFiles: PreparedFile[],
options: GenerateTOCOptions, options: GenerateTOCOptions
): Promise<string> { ): Promise<string> {
const { srcDir, domain, sidebarConfig, linksExtension, cleanUrls } = options const { srcDir, domain, sidebarConfig, linksExtension, cleanUrls } = options
let tableOfContent = '' let tableOfContent = ''
@ -266,7 +266,7 @@ export async function generateTOC(
srcDir, srcDir,
domain, domain,
linksExtension, linksExtension,
cleanUrls, cleanUrls
) )
// tableOfContent = `${tableOfContent.trimEnd()}\n\n` // tableOfContent = `${tableOfContent.trimEnd()}\n\n`
@ -275,12 +275,12 @@ export async function generateTOC(
// Find files that didn't match any section // Find files that didn't match any section
const allSidebarPaths = collectPathsFromSidebarItems( const allSidebarPaths = collectPathsFromSidebarItems(
flattenedSidebarConfig, flattenedSidebarConfig
) )
const unsortedFiles = filesToProcess.filter((file) => { const unsortedFiles = filesToProcess.filter((file) => {
const relativePath = `/${stripExtPosix(path.relative(srcDir, file.path))}` const relativePath = `/${stripExtPosix(path.relative(srcDir, file.path))}`
return !allSidebarPaths.some((sidebarPath) => return !allSidebarPaths.some((sidebarPath) =>
isPathMatch(relativePath, sidebarPath), isPathMatch(relativePath, sidebarPath)
) )
}) })
@ -298,9 +298,9 @@ export async function generateTOC(
filesToProcess.map(async (file) => { filesToProcess.map(async (file) => {
const relativePath = path.relative(srcDir, file.path) const relativePath = path.relative(srcDir, file.path)
tocEntries.push( tocEntries.push(
generateTOCLink(file, domain, relativePath, linksExtension, cleanUrls), generateTOCLink(file, domain, relativePath, linksExtension, cleanUrls)
) )
}), })
) )
tableOfContent += tocEntries.join('') tableOfContent += tocEntries.join('')

@ -13,7 +13,7 @@ import type { LinksExtension, LlmstxtSettings, VitePressConfig } from '../types'
*/ */
export const splitDirAndFile = (filepath: string) => ({ export const splitDirAndFile = (filepath: string) => ({
dir: path.dirname(filepath), dir: path.dirname(filepath),
file: path.basename(filepath), file: path.basename(filepath)
}) })
/** /**
@ -92,7 +92,7 @@ export function replaceTemplateVariable(
content: string, content: string,
variable: string, variable: string,
value: string | undefined, value: string | undefined,
fallback?: string, fallback?: string
) { ) {
return content.replace(templateVariable(variable), (_, prefix) => { return content.replace(templateVariable(variable), (_, prefix) => {
const val = value?.length ? value : fallback?.length ? fallback : '' const val = value?.length ? value : fallback?.length ? fallback : ''
@ -117,11 +117,11 @@ export function replaceTemplateVariable(
*/ */
export const expandTemplate = ( export const expandTemplate = (
template: string, template: string,
variables: Record<string, string | undefined>, variables: Record<string, string | undefined>
) => { ) => {
return Object.entries(variables).reduce( return Object.entries(variables).reduce(
(result, [key, value]) => replaceTemplateVariable(result, key, value), (result, [key, value]) => replaceTemplateVariable(result, key, value),
template, template
) )
} }
@ -137,12 +137,12 @@ export const generateLink = (
path: string, path: string,
domain?: string, domain?: string,
extension?: LinksExtension, extension?: LinksExtension,
cleanUrls?: VitePressConfig['cleanUrls'], cleanUrls?: VitePressConfig['cleanUrls']
) => ) =>
expandTemplate('{domain}/{path}{extension}', { expandTemplate('{domain}/{path}{extension}', {
domain: domain || '', domain: domain || '',
path, path,
extension: cleanUrls ? '' : extension, extension: cleanUrls ? '' : extension
}) })
/** /**
@ -175,7 +175,7 @@ export interface GenerateMetadataOptions {
*/ */
export function generateMetadata<GrayMatter extends GrayMatterFile<Input>>( export function generateMetadata<GrayMatter extends GrayMatterFile<Input>>(
sourceFile: GrayMatter, sourceFile: GrayMatter,
options: GenerateMetadataOptions, options: GenerateMetadataOptions
) { ) {
const { domain, filePath, linksExtension, cleanUrls } = options const { domain, filePath, linksExtension, cleanUrls } = options
const frontmatterMetadata: Record<string, string> = {} const frontmatterMetadata: Record<string, string> = {}
@ -184,7 +184,7 @@ export function generateMetadata<GrayMatter extends GrayMatterFile<Input>>(
stripExtPosix(filePath), stripExtPosix(filePath),
domain, domain,
linksExtension ?? '.md', linksExtension ?? '.md',
cleanUrls, cleanUrls
) )
if (sourceFile.data?.description?.length) { if (sourceFile.data?.description?.length) {

@ -21,13 +21,13 @@ import {
extractTitle, extractTitle,
generateMetadata, generateMetadata,
getHumanReadableSizeOf, getHumanReadableSizeOf,
stripExt, stripExt
} from './helpers/utils' } from './helpers/utils'
import type { import type {
CustomTemplateVariables, CustomTemplateVariables,
LlmstxtSettings, LlmstxtSettings,
PreparedFile, PreparedFile,
VitePressConfig, VitePressConfig
} from './types' } from './types'
const PLUGIN_NAME = 'llmstxt' const PLUGIN_NAME = 'llmstxt'
@ -50,7 +50,7 @@ export default function llmstxt(userSettings: LlmstxtSettings = {}): Plugin {
ignoreFiles: [], ignoreFiles: [],
workDir: undefined as unknown as string, workDir: undefined as unknown as string,
stripHTML: true, stripHTML: true,
...userSettings, ...userSettings
} }
// Store the resolved Vite config // Store the resolved Vite config
@ -71,7 +71,7 @@ export default function llmstxt(userSettings: LlmstxtSettings = {}): Plugin {
if (settings.workDir) { if (settings.workDir) {
settings.workDir = path.resolve( settings.workDir = path.resolve(
config.vitepress.srcDir, config.vitepress.srcDir,
settings.workDir as string, settings.workDir as string
) )
} else { } else {
settings.workDir = config.vitepress.srcDir settings.workDir = config.vitepress.srcDir
@ -79,7 +79,7 @@ export default function llmstxt(userSettings: LlmstxtSettings = {}): Plugin {
// Detect if this is the SSR build // Detect if this is the SSR build
isSsrBuild = !!resolvedConfig.build?.ssr isSsrBuild = !!resolvedConfig.build?.ssr
log.info( log.info(
`${pc.bold(PLUGIN_NAME)} initialized ${isSsrBuild ? pc.dim('(SSR build)') : pc.dim('(client build)')} with workDir: ${pc.cyan(settings.workDir as string)}`, `${pc.bold(PLUGIN_NAME)} initialized ${isSsrBuild ? pc.dim('(SSR build)') : pc.dim('(client build)')} with workDir: ${pc.cyan(settings.workDir as string)}`
) )
}, },
@ -92,7 +92,7 @@ export default function llmstxt(userSettings: LlmstxtSettings = {}): Plugin {
// Try to read and serve the markdown file // Try to read and serve the markdown file
const filePath = path.resolve( const filePath = path.resolve(
config.vitepress?.outDir ?? 'dist', config.vitepress?.outDir ?? 'dist',
`${stripExt(req.url)}.md`, `${stripExt(req.url)}.md`
) )
const content = await fs.readFile(filePath, 'utf-8') const content = await fs.readFile(filePath, 'utf-8')
res.setHeader('Content-Type', 'text/plain; charset=utf-8') res.setHeader('Content-Type', 'text/plain; charset=utf-8')
@ -143,12 +143,12 @@ export default function llmstxt(userSettings: LlmstxtSettings = {}): Plugin {
return await Promise.resolve( return await Promise.resolve(
minimatch( minimatch(
path.relative(settings.workDir as string, id), path.relative(settings.workDir as string, id),
pattern, pattern
), )
) )
} }
return false return false
}), })
) )
if (shouldIgnore.some((result) => result === true)) { if (shouldIgnore.some((result) => result === true)) {
@ -189,13 +189,13 @@ export default function llmstxt(userSettings: LlmstxtSettings = {}): Plugin {
// Skip if no files found // Skip if no files found
if (fileCount === 0) { if (fileCount === 0) {
log.warn( log.warn(
`No markdown files found to process. Check your \`${pc.bold('workDir')}\` and \`${pc.bold('ignoreFiles')}\` settings.`, `No markdown files found to process. Check your \`${pc.bold('workDir')}\` and \`${pc.bold('ignoreFiles')}\` settings.`
) )
return return
} }
log.info( log.info(
`Processing ${pc.bold(fileCount.toString())} markdown files from ${pc.cyan(settings.workDir)}`, `Processing ${pc.bold(fileCount.toString())} markdown files from ${pc.cyan(settings.workDir)}`
) )
const preparedFiles: PreparedFile[] = await Promise.all( const preparedFiles: PreparedFile[] = await Promise.all(
@ -230,7 +230,7 @@ export default function llmstxt(userSettings: LlmstxtSettings = {}): Plugin {
: file : file
return { path: filePath, title, file: mdFile } return { path: filePath, title, file: mdFile }
}), })
) )
if (settings.generateLLMFriendlyDocsForEachPage) { if (settings.generateLLMFriendlyDocsForEachPage) {
@ -243,7 +243,7 @@ export default function llmstxt(userSettings: LlmstxtSettings = {}): Plugin {
// Ensure target directory exists (async version) // Ensure target directory exists (async version)
await fs.mkdir(path.dirname(targetPath), { await fs.mkdir(path.dirname(targetPath), {
recursive: true, recursive: true
}) })
// Copy file to output directory (async version) // Copy file to output directory (async version)
@ -253,19 +253,19 @@ export default function llmstxt(userSettings: LlmstxtSettings = {}): Plugin {
mdFile.content, mdFile.content,
generateMetadata(mdFile, { generateMetadata(mdFile, {
domain: settings.domain, domain: settings.domain,
filePath: relativePath, filePath: relativePath
}), })
), )
) )
log.success(`Processed ${pc.cyan(relativePath)}`) log.success(`Processed ${pc.cyan(relativePath)}`)
} catch (error) { } catch (error) {
log.error( log.error(
// @ts-ignore // @ts-ignore
`Failed to process ${pc.cyan(relativePath)}: ${error.message}`, `Failed to process ${pc.cyan(relativePath)}: ${error.message}`
) )
} }
}), })
) )
} }
@ -282,7 +282,7 @@ export default function llmstxt(userSettings: LlmstxtSettings = {}): Plugin {
description: settings.description, description: settings.description,
details: settings.details, details: settings.details,
toc: settings.toc, toc: settings.toc,
...settings.customTemplateVariables, ...settings.customTemplateVariables
} }
tasks.push( tasks.push(
@ -301,7 +301,7 @@ export default function llmstxt(userSettings: LlmstxtSettings = {}): Plugin {
linksExtension: !settings.generateLLMFriendlyDocsForEachPage linksExtension: !settings.generateLLMFriendlyDocsForEachPage
? '.html' ? '.html'
: undefined, : undefined,
cleanUrls: config.cleanUrls, cleanUrls: config.cleanUrls
}) })
await fs.writeFile(llmsTxtPath, llmsTxt, 'utf-8') await fs.writeFile(llmsTxtPath, llmsTxt, 'utf-8')
@ -313,11 +313,11 @@ export default function llmstxt(userSettings: LlmstxtSettings = {}): Plugin {
file: pc.cyan('llms.txt'), file: pc.cyan('llms.txt'),
tokens: pc.bold(millify(approximateTokenSize(llmsTxt))), tokens: pc.bold(millify(approximateTokenSize(llmsTxt))),
size: pc.bold(getHumanReadableSizeOf(llmsTxt)), size: pc.bold(getHumanReadableSizeOf(llmsTxt)),
fileCount: pc.bold(fileCount.toString()), fileCount: pc.bold(fileCount.toString())
}, }
), )
) )
})(), })()
) )
} }
@ -328,7 +328,7 @@ export default function llmstxt(userSettings: LlmstxtSettings = {}): Plugin {
tasks.push( tasks.push(
(async () => { (async () => {
log.info( log.info(
`Generating full documentation bundle (${pc.cyan('llms-full.txt')})...`, `Generating full documentation bundle (${pc.cyan('llms-full.txt')})...`
) )
const llmsFullTxt = generateLLMsFullTxt(preparedFiles, { const llmsFullTxt = generateLLMsFullTxt(preparedFiles, {
@ -337,7 +337,7 @@ export default function llmstxt(userSettings: LlmstxtSettings = {}): Plugin {
linksExtension: !settings.generateLLMFriendlyDocsForEachPage linksExtension: !settings.generateLLMFriendlyDocsForEachPage
? '.html' ? '.html'
: undefined, : undefined,
cleanUrls: config.cleanUrls, cleanUrls: config.cleanUrls
}) })
// Write content to llms-full.txt // Write content to llms-full.txt
@ -349,17 +349,17 @@ export default function llmstxt(userSettings: LlmstxtSettings = {}): Plugin {
file: pc.cyan('llms-full.txt'), file: pc.cyan('llms-full.txt'),
tokens: pc.bold(millify(approximateTokenSize(llmsFullTxt))), tokens: pc.bold(millify(approximateTokenSize(llmsFullTxt))),
size: pc.bold(getHumanReadableSizeOf(llmsFullTxt)), size: pc.bold(getHumanReadableSizeOf(llmsFullTxt)),
fileCount: pc.bold(fileCount.toString()), fileCount: pc.bold(fileCount.toString())
}, }
),
) )
})(), )
})()
) )
} }
if (tasks.length) { if (tasks.length) {
await Promise.all(tasks) await Promise.all(tasks)
} }
}, }
} }
} }

Loading…
Cancel
Save