@tobi-or-not/docpress 0.7.4 → 0.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"cli.js","sources":["../src/utils/const.ts","../src/utils/functions.ts","../src/utils/logger.ts","../src/schemas/global.ts","../src/schemas/build.ts","../src/schemas/fetch.ts","../src/schemas/prepare.ts","../src/utils/commands.ts","../src/lib/git.ts","../src/lib/fetch.ts","../src/commands/global.ts","../src/commands/fetch.ts","../src/commands/build.ts","../src/utils/templates.ts","../src/utils/regex.ts","../src/lib/vitepress.ts","../src/lib/prepare.ts","../src/commands/prepare.ts","../src/cli.ts"],"sourcesContent":["import { resolve } from 'node:path'\n\n/**\n * Main directory for DocPress files\n */\nexport const DOCPRESS_DIR = resolve(process.cwd(), 'docpress')\n\n/**\n * Path to repositories information JSON file\n */\nexport const USER_REPOS_INFOS = resolve(process.cwd(), 'docpress/repositories.json')\n\n/**\n * Path to user information JSON file\n */\nexport const USER_INFOS = resolve(process.cwd(), 'docpress/owner.json')\n\n/**\n * Directory for documentation files\n */\nexport const DOCS_DIR = resolve(process.cwd(), 'docpress/docs')\n\n/**\n * Path to the main index file\n */\nexport const INDEX_FILE = resolve(process.cwd(), 'docpress/docs/index.md')\n\n/**\n * Path to the forks documentation file\n */\nexport const FORKS_FILE = resolve(process.cwd(), 'docpress/docs/forks.md')\n\n/**\n * Path to VitePress configuration file\n */\nexport const VITEPRESS_CONFIG = resolve(process.cwd(), 'docpress/.vitepress/config.ts')\n\n/**\n * Directory for VitePress theme\n */\nexport const VITEPRESS_THEME = resolve(process.cwd(), 'docpress/.vitepress/theme')\n\n/**\n * Directory for user custom theme files\n */\nexport const VITEPRESS_USER_THEME = resolve(process.cwd(), 'docpress/.vitepress/theme/extras')\n\n/**\n * Path to template theme files\n */\n// eslint-disable-next-line dot-notation\nexport const TEMPLATE_THEME = process.env['NODE_ENV'] === 'development'\n ? resolve(import.meta.dirname, '../../public/templates/theme')\n : resolve(import.meta.dirname, './templates/theme')\n","import { existsSync, mkdirSync, readdirSync, readFileSync, statSync } from 'node:fs'\nimport { basename, join, resolve } from 'node:path'\nimport axios from 'axios'\nimport { rimrafSync } from 'rimraf'\nimport type { GlobalOpts } from '../schemas/global.js'\nimport type { EnhancedRepository } from '../lib/fetch.js'\nimport type { getInfos } from '../lib/git.js'\nimport { DOCPRESS_DIR } from './const.js'\n\n/**\n * Checks the HTTP status code of a URL\n *\n * @param url - URL to check\n * @returns HTTP status code (404 if not found, 500 for errors)\n */\nexport async function checkHttpStatus(url: string): Promise<number> {\n try {\n const response = await axios.head(url)\n return response.status\n } catch (error) {\n return error.response?.status || error.status || 500\n }\n}\n\n/**\n * Options for prettifying strings\n */\ninterface PrettifyOpts {\n mode?: 'capitalize' | 'uppercase' | 'lowercase'\n replaceDash?: boolean\n removeIdx?: boolean\n removeDot?: boolean\n removeExt?: boolean\n}\n\n/**\n * Formats a string based on specified options\n *\n * @param s - Input string to format\n * @param opts - Formatting options\n * @returns Formatted string\n */\nexport function prettify(s: string, opts: PrettifyOpts) {\n let u: string = ''\n\n if (opts?.removeDot) {\n if (s.startsWith('.')) {\n u = s.slice(1)\n } else {\n u = s\n }\n // Replace all remaining dots with dashes to ensure consistency\n u = u.replaceAll('.', '-')\n }\n\n if (opts?.removeIdx) {\n u = (u || s).replace(/^\\d{2}-/, '')\n }\n\n if (opts?.removeExt) {\n u = (u || s).split('.')[0]\n }\n\n if (opts?.replaceDash) {\n u = (u || s).replaceAll('-', ' ')\n }\n\n if (opts?.mode === 'capitalize') {\n u = (u || s).slice(0, 1).toUpperCase() + (u || s).slice(1).toLowerCase()\n } else if (opts?.mode === 'lowercase') {\n u = (u || s).toLowerCase()\n } else if (opts?.mode === 'uppercase') {\n u = (u || s).toUpperCase()\n }\n\n return u || s\n}\n\n/**\n * Creates a directory, optionally cleaning it first\n *\n * @param directory - Path to the directory to create\n * @param options - Options object\n * @param options.clean - Whether to clean the directory before creating it\n */\nexport function createDir(directory: string, { clean }: { clean?: boolean } = { clean: false }) {\n try {\n if (clean && existsSync(directory)) {\n rimrafSync(`${directory}/*`, { glob: true })\n }\n if (!existsSync(directory)) {\n mkdirSync(directory, { recursive: true })\n }\n } catch (err) {\n console.error(err)\n }\n}\n\n/**\n * Checks if a path is a directory\n *\n * @param path - Path to check\n * @returns True if path is a directory, false otherwise\n */\nexport function isDir(path: string) {\n try {\n return statSync(path).isDirectory()\n } catch (_error) {\n return false\n }\n}\n\n/**\n * Checks if a path is a file\n *\n * @param path - Path to check\n * @returns True if path is a file, false otherwise\n */\nexport function isFile(path: string) {\n try {\n return statSync(path).isFile()\n } catch (_error) {\n return false\n }\n}\n\n/**\n * Extracts a list of file paths from directories and files\n *\n * @param paths - Path or array of paths to extract files from\n * @returns Array of file paths\n */\nexport function extractFiles(paths: string[] | string): string[] {\n return (Array.isArray(paths) ? paths : [paths]).flatMap((path) => {\n if (isFile(path)) {\n return [path]\n }\n if (isDir(path)) {\n return readdirSync(path).flatMap(file => extractFiles(join(path, file)))\n }\n return []\n })\n}\n\n/**\n * Gets all markdown files from specified paths\n *\n * @param path - Array of paths to search for markdown files\n * @returns Array of markdown file paths\n */\nexport function getMdFiles(path: string[]) {\n return extractFiles(path).filter(file => basename(file).endsWith('.md'))\n}\n\n/**\n * Formats an array of strings into a readable comma-separated list\n *\n * @param arr - Array of strings to format\n * @returns Formatted string (e.g., \"a\", \"b\" or \"c\")\n */\nexport function prettifyEnum(arr: readonly string[]) {\n return arr.reduce((acc, cur, idx, arr) => {\n if (!idx) {\n return `\"${cur}\"`\n } else if (idx === arr.length - 1) {\n return `${acc} or \"${cur}\"`\n } else {\n return `${acc}, \"${cur}\"`\n }\n }, '')\n}\n\n/**\n * Gets user information from cached JSON file\n *\n * @param username - GitHub username\n * @returns User information object\n */\nexport function getUserInfos(username: GlobalOpts['usernames'][number]) {\n return JSON.parse(readFileSync(`${DOCPRESS_DIR}/user-${username}.json`).toString()) as Awaited<ReturnType<typeof getInfos>>['user']\n}\n\n/**\n * Gets repository information from cached JSON file\n *\n * @param username - GitHub username\n * @returns Array of enhanced repository objects\n */\nexport function getUserRepos(username: GlobalOpts['usernames'][number]) {\n return JSON.parse(readFileSync(`${DOCPRESS_DIR}/repos-${username}.json`).toString()) as EnhancedRepository[]\n}\n\n/**\n * Deep merges multiple objects\n *\n * @param objects - Objects to merge\n * @returns Merged object\n */\nexport function deepMerge<T extends Record<string, any> | null>(...objects: T[]): T {\n return objects.reduce((acc, obj) => {\n if (obj === null) {\n return acc\n }\n\n Object.keys(obj).forEach((key) => {\n const accValue = acc ? acc[key] : null\n const objValue = obj[key]\n\n if (isObject(accValue) && isObject(objValue)) {\n (acc as Record<string, any>)[key] = deepMerge(accValue, objValue)\n } else {\n (acc as Record<string, any>)[key] = objValue\n }\n })\n return acc\n }, {} as T)\n}\n\n/**\n * Checks if a value is an object (not an array or null)\n *\n * @param val - Value to check\n * @returns True if value is an object, false otherwise\n */\nexport function isObject(val: any): val is object {\n return val && typeof val === 'object' && !Array.isArray(val)\n}\n\n/**\n * Loads and parses a JSON configuration file\n *\n * @param configPath - Path to the configuration file\n * @returns Parsed configuration object or empty object if file doesn't exist\n */\nexport function loadConfigFile(configPath?: string) {\n if (!configPath) {\n return {}\n }\n try {\n const fullPath = resolve(process.cwd(), configPath)\n const fileContents = readFileSync(fullPath, 'utf8')\n return JSON.parse(fileContents)\n } catch (_error) {\n return {}\n }\n}\n\n/**\n * Splits a comma-separated string into an array of strings\n *\n * @param s - Comma-separated string\n * @returns Array of strings\n */\nexport function splitByComma(s: string) {\n return s.split(',')\n}\n","/* eslint-disable dot-notation */\nimport type { ColorName } from 'chalk'\nimport chalk from 'chalk'\n\n/**\n * Log message types\n */\ntype LogType = keyof Pick<Console, 'info' | 'warn' | 'error' | 'debug' | 'trace'> | 'success'\n\n/**\n * Mapping of log types to colors and levels\n */\ntype ColorMap = {\n [K in LogType]: {\n color: ColorName\n level: number\n }\n}\n\n/**\n * Gets the current log level from environment variables\n *\n * @returns Log level number (default: 30)\n */\nfunction getLogLevel() {\n return typeof Number(process.env['LOG_LEVEL']) === 'number' && !Number.isNaN(Number(process.env['LOG_LEVEL']))\n ? Number(process.env['LOG_LEVEL'])\n : 30\n}\n\n/**\n * Color mapping configuration for different log types\n */\nconst colorMap: ColorMap = {\n error: { color: 'red', level: 10 },\n warn: { color: 'yellow', level: 20 },\n info: { color: 'white', level: 30 },\n success: { color: 'green', level: 30 },\n trace: { color: 'white', level: 40 },\n debug: { color: 'blue', level: 50 },\n}\n\n/**\n * Logs a message with color formatting based on type and level\n *\n * @param msg - Message to log\n * @param type - Type of log message (info, warn, error, debug, trace, success)\n * @param color - Optional specific color to use instead of the default for the type\n */\nexport function log(msg: string, type: LogType = 'info', color?: ColorName) {\n const computedMsg = color ? chalk[color](msg) : chalk[colorMap[type].color](msg)\n const computedType = type === 'success' ? 'info' : type\n\n if (getLogLevel() >= colorMap[type].level) {\n console[computedType](computedMsg)\n }\n}\n","import { z } from 'zod'\nimport { loadConfigFile, prettifyEnum, splitByComma } from '../utils/functions.js'\nimport { log } from '../utils/logger.js'\n\n/**\n * List of supported Git providers\n */\nconst providers = ['github'] as const\n\n/**\n * Schema for the DocPress configuration file\n * Defines the structure and validation rules for the configuration\n */\nexport const configSchema = z.object({\n // Global\n usernames: z.string()\n .array()\n .describe('List of comma separated Git provider usernames used to collect data.'),\n // Fetch\n branch: z.string()\n .describe('Branch used to collect Git provider data.')\n .default('main'),\n gitProvider: z.enum(providers)\n .describe(`Git provider used to retrieve data. Values should be ${prettifyEnum(providers)}.`)\n .default('github'),\n reposFilter: z.string()\n .array()\n .describe('List of comma separated repositories to retrieve from Git provider. Default to all user\\'s public repositories.'),\n // Prepare\n extraHeaderPages: z.string()\n .array()\n .describe('List of comma separated additional files or directories to process Vitepress header pages.'),\n extraPublicContent: z.string()\n .array()\n .describe('List of comma separated additional files or directories to process Vitepress public folder.'),\n extraTheme: z.string()\n .array()\n .describe('List of comma separated additional files or directories to use as Vitepress theme.'),\n forks: z.boolean()\n .describe('Whether or not to create the dedicated fork page that aggregate external contributions.')\n .default(false),\n vitepressConfig: z.any()\n .describe('Path to the vitepress configuration file.'),\n websiteTitle: z.string()\n .describe('Website title.'),\n websiteTagline: z.string()\n .describe('Website tagline.'),\n})\n\nexport type Config = z.infer<typeof configSchema>\n\n/**\n * Base CLI schema for parsing command line arguments\n * All fields are optional in this schema\n */\nexport const baseCliSchema = configSchema.partial().extend({\n config: z.string()\n .describe('Path to the docpress configuration file.')\n .optional(),\n token: z.string()\n .describe('Git provider token used to collect data.')\n .optional(),\n usernames: z.string()\n .describe(configSchema.shape.usernames.description || '')\n .optional(),\n reposFilter: z.string()\n .describe(configSchema.shape.reposFilter.description || '')\n .optional(),\n extraHeaderPages: z.string()\n .describe(configSchema.shape.extraHeaderPages.description || '')\n .optional(),\n extraPublicContent: z.string()\n .describe(configSchema.shape.extraPublicContent.description || '')\n .optional(),\n extraTheme: z.string()\n .describe(configSchema.shape.extraTheme.description || '')\n .optional(),\n vitepressConfig: z.string()\n .describe(configSchema.shape.vitepressConfig.description || '')\n .optional(),\n})\n\nexport type RawCli = z.infer<typeof baseCliSchema>\n\n/**\n * CLI schema with transformations applied to handle string-to-array conversions\n */\nexport const cliSchema = configSchema\n .partial()\n .extend({\n config: z.string()\n .describe('Path to the docpress configuration file.')\n .optional(),\n token: z.string()\n .describe('Git provider token used to collect data.')\n .optional(),\n usernames: z.string()\n .describe(configSchema.shape.usernames.description || '')\n .transform(splitByComma)\n .optional(),\n reposFilter: z.string()\n .describe(configSchema.shape.reposFilter.description || '')\n .transform(splitByComma)\n .optional(),\n extraHeaderPages: z.string()\n .describe(configSchema.shape.extraHeaderPages.description || '')\n .transform(splitByComma)\n .optional(),\n extraPublicContent: z.string()\n .describe(configSchema.shape.extraPublicContent.description || '')\n .transform(splitByComma)\n .optional(),\n extraTheme: z.string()\n .describe(configSchema.shape.extraTheme.description || '')\n .transform(splitByComma)\n .optional(),\n vitepressConfig: z.string()\n .describe(configSchema.shape.vitepressConfig.description || '')\n .optional(),\n })\n\nexport type Cli = z.infer<typeof cliSchema>\n\n// Helper functions to reduce complexity\n/**\n * Prepares configuration data by converting string values to arrays when needed\n *\n * @param configData - Raw configuration data to process\n * @returns Processed configuration data with proper array types\n */\nfunction prepareConfigData(configData: any) {\n if (!configData) return {}\n\n // Convert arrays that might be strings\n if (configData.usernames && typeof configData.usernames === 'string') {\n configData.usernames = [configData.usernames]\n }\n if (configData.reposFilter && typeof configData.reposFilter === 'string') {\n configData.reposFilter = [configData.reposFilter]\n }\n if (configData.extraHeaderPages && typeof configData.extraHeaderPages === 'string') {\n configData.extraHeaderPages = [configData.extraHeaderPages]\n }\n if (configData.extraPublicContent && typeof configData.extraPublicContent === 'string') {\n configData.extraPublicContent = [configData.extraPublicContent]\n }\n if (configData.extraTheme && typeof configData.extraTheme === 'string') {\n configData.extraTheme = [configData.extraTheme]\n }\n\n return configData\n}\n\n/**\n * Validates the final merged configuration to ensure required fields are present\n *\n * @param mergedConfig - The merged configuration to validate\n * @returns The validated configuration if it passes validation\n * @throws Error if required fields are missing\n */\nfunction validateFinalConfig(mergedConfig: any) {\n // Ensure usernames exists\n if (!mergedConfig.usernames?.length) {\n throw new Error('The usernames field is required')\n }\n\n return mergedConfig\n}\n\n/**\n * Schema for global options that combines CLI arguments and configuration files\n * Applies transformations to merge different config sources and validate the result\n */\nexport const globalOptsSchema = cliSchema\n .partial()\n .transform((data) => {\n try {\n const { config, vitepressConfig, token, ...rest } = data\n\n log(`Debug: Schema transform input: ${JSON.stringify(data)}`, 'debug')\n\n // Load configuration from file\n const configData = loadConfigFile(config)\n const preparedConfigData = prepareConfigData(configData)\n\n // Create final config\n const mergedConfig = {\n forks: false,\n ...preparedConfigData,\n ...rest,\n ...(vitepressConfig\n ? {\n vitepressConfig: {\n ...(loadConfigFile(vitepressConfig) || {}),\n ...(preparedConfigData.vitepressConfig || {}),\n },\n }\n : {}),\n }\n\n log(`Debug: Final merged config: ${JSON.stringify(mergedConfig)}`, 'debug')\n\n return validateFinalConfig({ ...mergedConfig, token })\n } catch (error) {\n // Handle errors gracefully\n log(` An error occurred while checking configuration.`, 'error')\n if (error instanceof Error) {\n log(` ${error.message}`, 'error')\n } else {\n log(` ${JSON.stringify(error, null, 2)}`, 'error')\n }\n process.exit(1)\n }\n })\n\nexport type GlobalOpts = Required<Pick<z.infer<typeof globalOptsSchema>, 'branch' | 'gitProvider'>>\n & Omit<z.infer<typeof globalOptsSchema>, 'branch' | 'gitProvider'>\n","import type { z } from 'zod'\nimport { cliSchema } from './global.js'\n\n/**\n * Schema for build command options\n * Currently empty as build doesn't require specific options\n */\nexport const buildOptsSchema = cliSchema\n .pick({})\n\nexport type BuildOpts = z.infer<typeof buildOptsSchema>\n","import { cliSchema } from './global.js'\nimport type { GlobalOpts } from './global.js'\n\n/**\n * Schema for fetch command options\n * Includes options related to Git repository fetching\n */\nexport const fetchOptsSchema = cliSchema\n .pick({\n branch: true,\n config: true,\n gitProvider: true,\n reposFilter: true,\n token: true,\n usernames: true,\n })\n\n/**\n * Type for fetch options\n */\nexport type FetchOpts = GlobalOpts\n\n/**\n * Type for fetch options with username instead of usernames array\n */\nexport type FetchOptsUser = Omit<FetchOpts, 'usernames'> & { username: FetchOpts['usernames'][number] }\n","import { cliSchema } from './global.js'\nimport type { GlobalOpts } from './global.js'\n\n/**\n * Schema for prepare command options\n * Includes options related to documentation preparation and customization\n */\nexport const prepareOptsSchema = cliSchema\n .pick({\n extraHeaderPages: true,\n extraPublicContent: true,\n extraTheme: true,\n config: true,\n gitProvider: true,\n reposFilter: true,\n token: true,\n usernames: true,\n vitepressConfig: true,\n })\n\n/**\n * Type for prepare options\n */\nexport type PrepareOpts = GlobalOpts\n","/* eslint-disable dot-notation */\nimport type { Command, Option } from 'commander'\nimport { fromError } from 'zod-validation-error'\nimport type { GlobalOpts } from '../schemas/global.js'\nimport { configSchema, globalOptsSchema } from '../schemas/global.js'\nimport type { BuildOpts } from '../schemas/build.js'\nimport { buildOptsSchema } from '../schemas/build.js'\nimport type { FetchOpts } from '../schemas/fetch.js'\nimport { fetchOptsSchema } from '../schemas/fetch.js'\nimport type { PrepareOpts } from '../schemas/prepare.js'\nimport { prepareOptsSchema } from '../schemas/prepare.js'\nimport { loadConfigFile } from './functions.js'\nimport { log } from './logger.js'\n\n/**\n * Type definition for command names\n */\ntype Cmd = 'fetch' | 'build' | 'prepare' | 'global'\n\n/**\n * Interface mapping command names to their option types\n */\ninterface Options {\n build: BuildOpts\n fetch: FetchOpts\n prepare: PrepareOpts\n global: GlobalOpts\n}\n\n/**\n * Mapping of command names to their schema validators\n */\nexport const options = {\n build: buildOptsSchema,\n fetch: fetchOptsSchema,\n prepare: prepareOptsSchema,\n global: globalOptsSchema,\n}\n\n/**\n * Handles loading and parsing of the configuration file\n *\n * @param configPath - Path to the configuration file\n * @param token - Optional GitHub token\n * @returns Parsed configuration data or null if loading/parsing failed\n */\nfunction handleConfigFile(configPath: string, token?: string) {\n const configData = loadConfigFile(configPath)\n if (!configData) return null\n\n // No need for a try/catch here since we're handling errors at a higher level\n const parsedConfig = configSchema.partial().safeParse(configData)\n if (parsedConfig.success) {\n return {\n ...parsedConfig.data,\n config: configPath,\n token: token || undefined,\n }\n }\n\n return null\n}\n\n/**\n * Parses and validates command options based on the command type\n *\n * @param cmd - The command name ('fetch', 'build', 'prepare', or 'global')\n * @param opts - Raw options from the command line\n * @returns Validated and processed options for the specified command\n */\nexport function parseOptions<T extends Cmd>(cmd: T, opts: Record<string, unknown>): Options[T] {\n log(`Initializing Docpress...`, 'info', 'blue')\n log(`\\n\\n-> Checking for required environment settings and configurations.`, 'info')\n log(` Debug info - opts: ${JSON.stringify(opts)}`, 'debug')\n log(` Debug info - options[cmd]: ${cmd}`, 'debug')\n\n try {\n // Special handling for config file\n if (cmd === 'global' && typeof opts['config'] === 'string') {\n const configResult = handleConfigFile(\n opts['config'],\n typeof opts['token'] === 'string' ? opts['token'] : undefined,\n )\n if (configResult) {\n // Force type assertion since we know the structure will match\n return configResult as unknown as Options[T]\n }\n }\n\n const res = options[cmd].safeParse(opts)\n if (!res.success) {\n try {\n const errorMessage = fromError(res.error).toString()\n log(` An error occurred while checking configuration.\\n ${errorMessage}`, 'error')\n } catch {\n // Fallback for incompatibility between zod-validation-error and Zod v4\n log(` An error occurred while checking configuration.\\n ${JSON.stringify(res.error, null, 2)}`, 'error')\n }\n process.exit(1)\n }\n log(' Setup complete! Ready to process your documentation.', 'info')\n return res.data as Options[T]\n } catch (error) {\n log(` An error occurred while processing options.`, 'error')\n if (error instanceof Error) {\n log(` ${error.message}`, 'error')\n } else {\n log(` ${JSON.stringify(error, null, 2)}`, 'error')\n }\n process.exit(1)\n }\n}\n\n/**\n * Adds option definitions to a Command instance\n *\n * @param cmd - The Commander Command instance\n * @param opts - Array of option definitions to add\n * @returns The Command instance with options added\n */\nexport function addOptions(cmd: Command, opts: Option[]) {\n for (const opt of opts) {\n cmd.addOption(opt)\n }\n return cmd\n}\n","import { appendFileSync, cpSync, rmSync } from 'node:fs'\nimport { resolve } from 'node:path'\nimport { Octokit } from '@octokit/rest'\nimport { simpleGit } from 'simple-git'\nimport type { GlobalOpts } from '../schemas/global.js'\nimport type { FetchOpts } from '../schemas/fetch.js'\nimport { createDir } from '../utils/functions.js'\nimport { log } from '../utils/logger.js'\nimport type { EnhancedRepository } from './fetch.js'\n\n/**\n * Fetches user and repository information from GitHub\n *\n * @param options - Options for retrieving GitHub data\n * @param options.username - GitHub username\n * @param options.token - GitHub API token\n * @param options.branch - Branch to use for documentation\n * @returns Object containing user information, repositories, and branch\n */\nexport async function getInfos({ username, token, branch }: Pick<FetchOpts, 'branch'> & Pick<GlobalOpts, 'token'> & { username: GlobalOpts['usernames'][number] }) {\n log(` Get infos for username '${username}'.`, 'info')\n const octokit = new Octokit({ auth: token })\n log(` Get user infos.`, 'debug')\n const { data: user } = await octokit.rest.users.getByUsername({ username })\n log(` Get repositories infos.`, 'debug')\n const { data: repos } = await octokit.rest.repos.listForUser({ username, sort: 'full_name', per_page: 500 })\n\n return { user, repos, branch }\n}\n\n/**\n * Gets contributors for a repository\n *\n * @param options - Options for retrieving contributors\n * @param options.repository - Repository information\n * @param options.token - GitHub API token\n * @returns Object with source repository and contributors list\n */\nexport async function getContributors({\n repository,\n token,\n}: {\n repository: EnhancedRepository\n token: GlobalOpts['token']\n}) {\n log(` Get contributors infos for repository '${repository.name}'.`, 'info')\n const octokit = new Octokit({\n auth: token,\n log: {\n debug: () => {},\n info: () => {},\n warn: (message) => {\n if (!message.includes('404')) console.warn(message)\n },\n error: (message) => {\n if (!message.includes('404')) console.error(message)\n },\n },\n })\n const { data: repo } = await octokit.rest.repos.get({\n owner: repository.owner.login,\n repo: repository.name,\n })\n if (!repo.source?.owner?.login) {\n return { source: repo.source, contributors: [] }\n }\n const contributors: Array<any> = []\n try {\n for await (const { data } of octokit.paginate.iterator(\n octokit.rest.repos.listContributors,\n {\n owner: repo.source.owner.login,\n repo: repo.parent?.name ?? repo.name,\n per_page: 500,\n },\n )) {\n contributors.push(...data)\n }\n } catch (error) {\n log(\n ` Failed to get contributors infos for repository '${repository.name}'. Error : ${error.message}`,\n 'warn',\n )\n return { source: repo.source, contributors: [] }\n }\n\n return { source: repo.source, contributors }\n}\n\n/**\n * Clones a repository with sparse checkout\n *\n * @param name - Repository name\n * @param url - Repository URL\n * @param projectDir - Directory to clone into\n * @param branch - Branch to clone\n * @param includes - Patterns to include in sparse checkout\n */\nexport async function cloneRepo(name: string, url: string, projectDir: string, branch: string, includes: string[]) {\n createDir(projectDir, { clean: true })\n\n try {\n const git = simpleGit({ baseDir: projectDir })\n await git.init()\n .addConfig('core.sparseCheckout', 'true', true, 'local')\n .addRemote('origin', url)\n\n for (const item of includes) {\n log(` Add '${item}' to '${name}' sparse-checkout file.`, 'debug')\n appendFileSync(resolve(projectDir, '.git/info/sparse-checkout'), `${item}\\n`, 'utf8')\n }\n\n log(` Clone repository '${name}'.`, 'info')\n await git.pull('origin', branch)\n\n if (includes.some(item => item.includes('docs'))) {\n cpSync(resolve(projectDir, 'docs'), projectDir, { recursive: true })\n rmSync(resolve(projectDir, 'docs'), { recursive: true })\n }\n rmSync(resolve(projectDir, '.git'), { recursive: true })\n } catch (error) {\n log(` Error when cloning repository: ${error}.`, 'error')\n }\n}\n","import { resolve } from 'node:path'\nimport { writeFileSync } from 'node:fs'\nimport type { GlobalOpts } from '../schemas/global.js'\nimport type { FetchOpts, FetchOptsUser } from '../schemas/fetch.js'\nimport { checkHttpStatus, prettify } from '../utils/functions.js'\nimport { DOCPRESS_DIR, DOCS_DIR } from '../utils/const.js'\nimport { log } from '../utils/logger.js'\nimport { cloneRepo, getInfos } from './git.js'\n\n/**\n * Enhanced repository type with DocPress-specific metadata\n */\nexport type EnhancedRepository = Awaited<ReturnType<typeof getInfos>>['repos'][number] & {\n docpress: {\n branch: string\n filtered: boolean\n includes: string[]\n projectPath: string\n raw_url: string\n replace_url: string\n }\n}\n\n/**\n * Checks for the existence of documentation files in a repository\n *\n * @param repoOwner - Owner of the repository (username)\n * @param repoName - Name of the repository\n * @param branch - Branch to check for documentation\n * @returns Object containing HTTP status codes for different documentation paths\n */\nexport async function checkDoc(repoOwner: GlobalOpts['usernames'][number], repoName: string, branch: FetchOpts['branch']) {\n const rootReadmeUrl = `https://github.com/${repoOwner}/${repoName}/tree/${branch}/README.md`\n const docsFolderUrl = `https://github.com/${repoOwner}/${repoName}/tree/${branch}/docs`\n const docsReadmeUrl = `https://github.com/${repoOwner}/${repoName}/tree/${branch}/docs/01-readme.md`\n\n const rootReadmeStatus = await checkHttpStatus(rootReadmeUrl)\n const docsFolderStatus = await checkHttpStatus(docsFolderUrl)\n const docsReadmeStatus = await checkHttpStatus(docsReadmeUrl)\n\n return {\n rootReadmeStatus,\n docsFolderStatus,\n docsReadmeStatus,\n }\n}\n\n/**\n * Fetches documentation from a user's repositories\n *\n * @param options - Options for fetching documentation\n * @param options.username - GitHub username\n * @param options.branch - Branch to use for documentation\n * @param options.reposFilter - Optional filter for repositories\n * @param options.token - GitHub API token\n */\nexport async function fetchDoc({ username, branch, reposFilter, token }: FetchOptsUser) {\n await getInfos({ username, token, branch })\n .then(async ({ user, repos, branch }) => generateInfos(user, repos, branch, reposFilter))\n .then(async ({ repos }) => getDoc(repos, reposFilter))\n}\n\n/**\n * Enhances repository information with DocPress metadata\n *\n * @param repos - List of repositories from Git provider\n * @param branch - Branch to use for documentation\n * @param reposFilter - Optional filter for repositories\n * @returns Array of enhanced repositories with DocPress metadata\n */\nexport async function enhanceRepositories(repos: Awaited<ReturnType<typeof getInfos>>['repos'], branch?: FetchOpts['branch'], reposFilter?: FetchOpts['reposFilter']) {\n const enhancedRepos: EnhancedRepository[] = []\n\n await Promise.all(\n repos.map(async (repo) => {\n const computedBranch = branch ?? repo.default_branch ?? 'main'\n const projectPath = resolve(DOCS_DIR, prettify(repo.name, { removeDot: true }))\n const filtered = isRepoFiltered(repo, reposFilter)\n let includes: string[] = []\n\n if (!repo.fork && !repo.private && !filtered) {\n includes = await getSparseCheckout(repo, computedBranch)\n }\n\n enhancedRepos.push({\n ...repo,\n docpress: {\n filtered,\n branch: computedBranch,\n includes,\n projectPath,\n raw_url: `https://raw.githubusercontent.com/${repo.owner.login}/${repo.name}/${computedBranch}`,\n replace_url: `https://github.com/${repo.owner.login}/${repo.name}/tree/${computedBranch}`,\n },\n })\n }),\n )\n\n return enhancedRepos\n}\n\n/**\n * Determines which files to include in the sparse checkout based on repository structure\n *\n * @param repo - Repository information\n * @param branch - Branch to check for documentation\n * @returns Array of file patterns to include in sparse checkout\n */\nexport async function getSparseCheckout(repo: Awaited<ReturnType<typeof getInfos>>['repos'][number], branch: FetchOpts['branch']) {\n const docsStatus = await checkDoc(repo.owner.login, repo.name, branch)\n\n const includes: string[] = []\n if (Object.values(docsStatus).every(status => status === 404) || !repo.size) {\n return []\n }\n if (docsStatus.docsFolderStatus !== 404) {\n includes.push('docs/*')\n }\n if (docsStatus.docsFolderStatus === 404 || docsStatus.docsReadmeStatus === 404) {\n includes.push('README.md', '!*/**/README.md')\n }\n return includes\n}\n\n/**\n * Generates and saves user and repository information\n *\n * @param user - User information from Git provider\n * @param repos - List of repositories from Git provider\n * @param branch - Branch to use for documentation\n * @param reposFilter - Optional filter for repositories\n * @returns Object containing user and enhanced repository information\n */\nexport async function generateInfos(user: Awaited<ReturnType<typeof getInfos>>['user'], repos: Awaited<ReturnType<typeof getInfos>>['repos'], branch?: FetchOpts['branch'], reposFilter?: FetchOpts['reposFilter']) {\n writeFileSync(`${DOCPRESS_DIR}/user-${user.login}.json`, JSON.stringify(user, null, 2))\n\n const enhancedRepos = await enhanceRepositories(repos, branch, reposFilter)\n writeFileSync(`${DOCPRESS_DIR}/repos-${user.login}.json`, JSON.stringify(enhancedRepos, null, 2))\n\n return { user, repos: enhancedRepos }\n}\n\n/**\n * Fetches documentation from repositories\n *\n * @param repos - List of enhanced repositories\n * @param reposFilter - Optional filter for repositories\n */\nexport async function getDoc(repos?: EnhancedRepository[], reposFilter?: FetchOpts['reposFilter']) {\n if (!repos) {\n log(` No repository respect docpress rules.`, 'warn')\n return\n }\n\n await Promise.all(\n repos\n .filter(repo => !isRepoFiltered(repo, reposFilter))\n .map(async (repo) => {\n await cloneRepo(repo.name, repo.clone_url as string, repo.docpress.projectPath, repo.docpress.branch, repo.docpress.includes)\n }),\n )\n}\n\n/**\n * Determines if a repository should be filtered out based on filter rules\n *\n * @param repo - Repository information\n * @param reposFilter - Optional filter for repositories\n * @returns True if the repository should be filtered out, false otherwise\n */\nexport function isRepoFiltered(repo: EnhancedRepository | Awaited<ReturnType<typeof getInfos>>['repos'][number], reposFilter?: FetchOpts['reposFilter']) {\n const hasOnlyExclusions = reposFilter?.every((filter: string) => filter.startsWith('!'))\n const isExcluded = reposFilter?.filter((filter: string) => filter.startsWith('!'))\n .some((filter: string) => repo.name === filter.substring(1))\n const isIncluded = !reposFilter\n || reposFilter?.filter((filter: string) => !filter.startsWith('!')).includes(repo.name)\n || (repo.fork && !isExcluded)\n || (hasOnlyExclusions && !isExcluded)\n\n const isFiltered = isExcluded || !isIncluded\n\n if ('docpress' in repo && !repo.docpress.includes.length) {\n return true\n }\n\n if (!!repo.clone_url && !repo.private && !isFiltered) {\n return false\n }\n return true\n}\n","import { createOption } from 'commander'\nimport { baseCliSchema } from '../schemas/global.js'\n\n/**\n * Global command line options shared across all commands\n */\nexport const globalOpts = [\n createOption('-C, --config <string>', baseCliSchema.shape.config.description),\n createOption('-T, --token <string>', baseCliSchema.shape.token.description),\n createOption('-U, --usernames <string>', baseCliSchema.shape.usernames.description),\n]\n","import { createCommand, createOption } from 'commander'\nimport { createDir } from '../utils/functions.js'\nimport { DOCPRESS_DIR } from '../utils/const.js'\nimport { log } from '../utils/logger.js'\nimport { addOptions, parseOptions } from '../utils/commands.js'\nimport type { FetchOpts } from '../schemas/fetch.js'\nimport { fetchDoc } from '../lib/fetch.js'\nimport { configSchema } from '../schemas/global.js'\nimport { globalOpts } from './global.js'\n\n/**\n * Command name for the fetch operation\n */\nconst cmdName = 'fetch'\n\n/**\n * Command line options specific to the fetch command\n */\nexport const fetchOpts = [\n createOption('-b, --branch <string>', configSchema.shape.branch.description)\n .default(configSchema.shape.branch.default),\n createOption('-g, --git-provider <string>', configSchema.shape.gitProvider.description)\n .default(configSchema.shape.gitProvider.default),\n createOption('-r, --repos-filter <string>', configSchema.shape.reposFilter.description),\n]\n\n/**\n * The fetch command definition for Commander\n */\nexport const fetchCmd = addOptions(createCommand(cmdName), [...fetchOpts, ...globalOpts])\n .description('Fetch docs with the given username(s) and git provider.')\n .action(async (opts) => {\n const parsedOpts = parseOptions(cmdName, opts)\n await main(parsedOpts)\n })\n\n/**\n * Main function to execute the fetch command\n *\n * @param opts - Validated fetch options\n */\nexport async function main(opts: FetchOpts) {\n const { usernames, reposFilter, token, branch, gitProvider } = opts\n log(`\\n-> Start fetching documentation files. This may take a moment, especially for larger repositories.`, 'info')\n\n createDir(DOCPRESS_DIR, { clean: true })\n for (const username of usernames) {\n const finalRF = usernames.length > 1\n ? reposFilter?.filter((rf: string) => rf.startsWith(`${username}/`)).map((rf: string) => rf.replace(`${username}/`, ''))\n : reposFilter\n await fetchDoc({ username, branch, reposFilter: finalRF, gitProvider, token })\n }\n}\n","import { build as vitepressBuild } from 'vitepress'\nimport { createCommand } from 'commander'\nimport { addOptions } from '../utils/commands.js'\nimport { DOCPRESS_DIR } from '../utils/const.js'\nimport { log } from '../utils/logger.js'\nimport { globalOpts } from './global.js'\n\n/**\n * Suppress specific Vue warnings during the build process\n *\n * @param callback - Function to execute while warnings are suppressed\n * @returns The result of the callback function\n */\nexport async function suppressVueWarnings<T>(callback: () => Promise<T>): Promise<T> {\n // Store the original console.warn\n const originalWarn = console.warn\n\n // Override console.warn to suppress specific Vue warnings\n console.warn = function (...args) {\n if (\n args.length > 0\n && typeof args[0] === 'string'\n && (args[0].includes('[Vue warn]: Invalid watch source:')\n || args[0].includes('{ open: false }'))\n ) {\n // Skip this warning\n return\n }\n // Pass other warnings to the original console.warn\n originalWarn.apply(console, args)\n }\n\n try {\n // Execute the callback with warnings suppressed\n return await callback()\n } finally {\n // Restore the original console.warn\n console.warn = originalWarn\n }\n}\n\n/**\n * Command name for the build operation\n */\nconst cmdName = 'build'\n\n/**\n * Command line options specific to the build command (none currently)\n */\nexport const buildOpts = []\n\n/**\n * The build command definition for Commander\n */\nexport const buildCmd = addOptions(createCommand(cmdName), globalOpts)\n .description('Build vitepress website.')\n .action(async (_opts) => {\n await main()\n })\n\n/**\n * Main function to execute the build command\n * Builds the VitePress static site\n */\nexport async function main() {\n log(`\\n-> Start building Vitepress website.\\n\\n`, 'info')\n\n try {\n // Build VitePress with Vue warnings suppressed\n await suppressVueWarnings(async () => {\n await vitepressBuild(DOCPRESS_DIR)\n })\n\n log(`\\n\\nDocpress build succedeed.`, 'success')\n } catch (error) {\n log(`\\n\\nDocpress build failed : ${error}`, 'error')\n }\n}\n","import { readFileSync, writeFileSync } from 'node:fs'\nimport { dirname } from 'node:path'\nimport { createDir } from './functions.js'\n\n/**\n * Generates a file by copying content from source to destination\n *\n * @param src - Path to the source file\n * @param dest - Path to the destination file\n */\nexport function generateFile(src: string, dest: string) {\n const content = readFileSync(src, { encoding: 'utf8' })\n createDir(dirname(dest))\n writeFileSync(dest, content)\n}\n","import { readFileSync, writeFileSync } from 'node:fs'\n\n/**\n * Replaces relative paths in markdown links with absolute URLs\n *\n * @param file - Path to the markdown file to process\n * @param url - Base URL to use for absolute links\n */\nexport function replaceRelativePath(file: string, url: string) {\n const fileContent = readFileSync(file, 'utf8')\n const updatedContent = fileContent.replace(/\\[([^\\]]+)\\]\\(\\.\\.\\/([^)]+)\\)/g, (_match, p1, p2) => {\n return `[${p1}](${url}/${p2})`\n })\n writeFileSync(file, updatedContent, 'utf8')\n}\n\n/**\n * Processes README files to fix various link formats\n *\n * @param file - Path to the README file to process\n * @param url - Base URL to use for absolute links\n */\nexport function replaceReadmePath(file: string, url: string) {\n const readmeContent = readFileSync(file, 'utf8')\n const updatedContent = readmeContent\n .replace(/\\[([^\\]]+)\\]\\((?!\\.?\\/docs\\/|docs\\/|http|#)(\\.?\\/)?([^/][^)]+)\\)/g, (_match, p1, _p2, p3) => {\n return `[${p1}](${url}/${p3})`\n })\n .replace(/\\[([^\\]]+)\\]\\((\\.?\\/docs\\/|docs\\/)([^)]*)\\)/g, (_match, p1, _p2, p3) => {\n return `[${p1}](${p3})`\n })\n writeFileSync(file, updatedContent, 'utf8')\n}\n","import type { defineConfig } from 'vitepress'\nimport { deepMerge } from '../utils/functions.js'\nimport type { Page, SidebarProject } from './prepare.js'\n\n/**\n * Default VitePress configuration\n */\nconst defaultVitepressConfig: ReturnType<typeof defineConfig> = {\n base: '/',\n lang: 'en-US',\n vite: {\n publicDir: '../public',\n },\n title: 'Home',\n description: 'Docpress',\n srcDir: './docs',\n cleanUrls: false,\n ignoreDeadLinks: 'localhostLinks',\n themeConfig: {\n outline: [2, 3],\n search: {\n provider: 'local',\n options: {\n translations: {\n button: {\n buttonText: 'Search...',\n buttonAriaLabel: 'Search',\n },\n modal: {\n backButtonTitle: 'erase search',\n displayDetails: 'show details',\n noResultsText: 'No results for : ',\n resetButtonTitle: 'cancel search',\n footer: {\n selectText: 'go to',\n navigateText: 'navigate in results',\n closeText: 'close',\n },\n },\n },\n },\n },\n },\n}\n\n/**\n * Generates VitePress configuration by merging default and custom configs\n *\n * @param sidebar - Sidebar configuration\n * @param nav - Navigation configuration\n * @param vitepressConfig - Optional custom VitePress configuration\n * @returns Merged VitePress configuration\n */\nexport function getVitepressConfig(sidebar: SidebarProject[], nav: Page[], vitepressConfig?: ReturnType<typeof defineConfig>): Partial<ReturnType<typeof defineConfig>> {\n return vitepressConfig\n ? deepMerge(defaultVitepressConfig, vitepressConfig, { themeConfig: { sidebar, nav } })\n : deepMerge(defaultVitepressConfig, { themeConfig: { sidebar, nav } })\n}\n","import { basename, dirname, parse, resolve } from 'node:path'\nimport { appendFileSync, cpSync, existsSync, readdirSync, renameSync, statSync, writeFileSync } from 'node:fs'\nimport { readFile } from 'node:fs/promises'\nimport YAML from 'yaml'\nimport type { defineConfig } from 'vitepress'\nimport type { PrepareOpts } from '../schemas/prepare.js'\nimport { generateFile } from '../utils/templates.js'\nimport type { GlobalOpts } from '../schemas/global.js'\nimport { createDir, extractFiles, getMdFiles, getUserInfos, getUserRepos, prettify } from '../utils/functions.js'\nimport { DOCPRESS_DIR, DOCS_DIR, FORKS_FILE, INDEX_FILE, TEMPLATE_THEME, VITEPRESS_CONFIG, VITEPRESS_THEME, VITEPRESS_USER_THEME } from '../utils/const.js'\nimport { replaceReadmePath, replaceRelativePath } from '../utils/regex.js'\nimport { log } from '../utils/logger.js'\nimport type { EnhancedRepository } from './fetch.js'\nimport type { getInfos } from './git.js'\nimport { getContributors } from './git.js'\nimport { getVitepressConfig } from './vitepress.js'\n\n/**\n * Represents a navigation page item with text and link\n */\nexport interface Page {\n text: string\n link: string\n}\n\n/**\n * Represents a sidebar project with nested items\n */\nexport interface SidebarProject {\n text: string\n collapsed: boolean\n items: (Page | SidebarProject)[]\n}\n\n/**\n * Represents a feature to display on the index page\n */\nexport interface Feature {\n title: string\n details: string\n link: string\n}\n\n/**\n * Represents the structure of the VitePress index page\n */\nexport interface Index {\n layout: string\n hero: {\n name: string\n tagline?: string\n }\n /** List of features to display */\n features: Feature[]\n}\n\n/**\n * Prepares the documentation structure for a user's repositories\n *\n * @param options - Options for documentation preparation\n * @param options.extraHeaderPages - Array of paths to additional header pages\n * @param options.extraPublicContent - Array of paths to additional public content\n * @param options.extraTheme - Array of paths to additional theme files\n * @param options.vitepressConfig - Path to the VitePress configuration file\n * @param options.forks - Flag to include forked repositories\n * @param options.token - GitHub token for API access\n * @param options.username - GitHub username to fetch repositories for\n * @param options.websiteTitle - Custom title for the documentation website\n * @param options.websiteTagline - Custom tagline for the documentation website\n */\nexport async function prepareDoc({ extraHeaderPages, extraPublicContent, extraTheme, vitepressConfig, forks, token, username, websiteTitle, websiteTagline }: Omit<PrepareOpts, 'usernames' | 'branch' | 'gitProvider' | 'reposFilter'> & { username: PrepareOpts['usernames'][number] }) {\n const user = getUserInfos(username)\n const repositories = getUserRepos(username)\n .reduce(({ internals, forks }: { internals: EnhancedRepository[], forks: EnhancedRepository[] }, cur) => {\n const { clone_url, private: privateRepo, fork, docpress } = cur\n if (clone_url && !privateRepo && !docpress.filtered) {\n if (!fork && docpress.includes.length) {\n return { internals: [...internals, cur], forks }\n } else if (fork) {\n return { internals, forks: [...forks, cur] }\n }\n }\n return { internals, forks }\n }, { internals: [], forks: [] })\n\n const websiteInfos = { title: websiteTitle, tagline: websiteTagline }\n const { index, sidebar } = transformDoc(repositories.internals, user, websiteInfos)\n\n let finalSB\n let finalIndex\n if (existsSync(INDEX_FILE) && existsSync(VITEPRESS_CONFIG)) {\n const actualConfig = await parseVitepressConfig(VITEPRESS_CONFIG)\n const actualIndex = await parseVitepressIndex(INDEX_FILE)\n finalSB = [\n ...(actualConfig.themeConfig?.sidebar as SidebarProject[] ?? []),\n ...sidebar,\n ].sort((a, b) => a.text.localeCompare(b.text))\n finalIndex = {\n ...index,\n features: [\n ...actualIndex.features,\n ...index.features,\n ].sort((a, b) => a.title.localeCompare(b.title)),\n }\n } else {\n finalSB = sidebar\n finalIndex = index\n }\n const nav: Page[] = []\n\n if (extraHeaderPages) {\n const pages = addExtraPages(extraHeaderPages)\n if (forks) {\n nav.push(...pages.filter(p => p.link !== '/forks'))\n } else {\n nav.push(...pages)\n }\n }\n if (extraPublicContent) {\n log(` Add extras Vitepress public folder content.`, 'info')\n addContent(extraPublicContent, resolve(DOCPRESS_DIR, 'public'))\n }\n if (extraTheme) {\n log(` Add extras Vitepress theme files.`, 'info')\n addContent(extraTheme, resolve(VITEPRESS_USER_THEME))\n }\n if (forks && username.length) {\n log(` Add fork page to display external contributions.`, 'info')\n await processForks(repositories.forks, username, token)\n nav.push({ text: 'Forks', link: '/forks' })\n }\n\n const config = getVitepressConfig(finalSB, nav, vitepressConfig)\n\n generateVitepressFiles(config, finalIndex)\n}\n\n/**\n * Adds a source reference section to a markdown file\n *\n * @param repoUrl - URL of the GitHub repository\n * @param outputPath - Path to the markdown file where sources will be added\n */\nexport function addSources(repoUrl: string, outputPath: string) {\n const fileName = basename(outputPath)\n const title = prettify(fileName, { mode: 'lowercase', removeIdx: true }) === 'readme.md' ? '\\n## Sources' : '# Sources'\n\n const sourcesContent = `${title}\\n\\nTake a look at the [project sources](${repoUrl}).\\n`\n\n appendFileSync(outputPath, sourcesContent, 'utf8')\n}\n\n/**\n * Information about website title and tagline\n */\nexport interface WebsiteInfos {\n title?: string\n tagline?: string\n}\n\n/**\n * Generates the index page content for the documentation site\n *\n * @param features - Array of features to display on the homepage\n * @param user - User information retrieved from GitHub\n * @param websiteInfos - Custom title and tagline information\n * @returns An object with index page configuration\n */\nexport function generateIndex(features: Feature[], user: ReturnType<typeof getUserInfos>, websiteInfos: WebsiteInfos) {\n const { name, login, bio } = user\n const { title, tagline } = websiteInfos\n\n const hero = title\n ? { name: title, tagline }\n : { name: name ? `${name}'s projects` : `${login}'s projects`, tagline: bio ?? 'Robots are everywhere 🤖' }\n\n return {\n layout: 'home',\n hero,\n features,\n }\n}\n\n/**\n * Generates feature cards for the homepage\n *\n * @param repoName - Name of the repository\n * @param description - Description of the repository\n * @param features - Optional existing features to append to\n * @returns Array of feature objects for the homepage\n */\nexport function generateFeatures(repoName: string, description: string, features?: Feature[]) {\n const content = {\n title: prettify(repoName, { mode: 'capitalize', replaceDash: true }),\n details: description,\n link: `/${prettify(repoName, { removeDot: true })}/introduction`,\n }\n\n return features ? [...features, content] : [content]\n}\n\n/**\n * Generates a sidebar project entry for the documentation navigation\n *\n * @param repoName - Name of the repository\n * @param sidebarPages - Array of sidebar pages to include in this project\n * @returns A sidebar project configuration object\n */\nexport function generateSidebarProject(repoName: string, sidebarPages: (SidebarProject | Page)[]) {\n return {\n text: prettify(repoName, { mode: 'capitalize', replaceDash: true }),\n collapsed: true,\n items: sidebarPages,\n }\n}\n\n/**\n * Generates sidebar page entries for the documentation navigation\n *\n * @param repoName - Name of the repository\n * @param fileName - Name of the file\n * @param sidebarPages - Optional existing sidebar pages to append to\n * @returns Array of page objects for the sidebar\n */\nexport function generateSidebarPages(repoName: string, fileName: string, sidebarPages?: Page[]) {\n const content = {\n text: fileName === 'introduction' ? 'Introduction' : prettify(fileName, { mode: 'capitalize', replaceDash: true }),\n link: `/${prettify(repoName, { removeDot: true })}/${fileName}`,\n }\n\n return sidebarPages ? [...sidebarPages, content] : [content]\n}\n\n/**\n * Generates sidebar items from a repository's file structure\n *\n * @param repository - Repository information\n * @param obj - Object representing the file tree structure\n * @returns Array of sidebar items (projects and pages)\n */\nexport function generateSidebarItems(repository: EnhancedRepository, obj: any): (SidebarProject | Page)[] {\n return Object.entries(obj).flatMap(([key, value]): (SidebarProject | Page)[] => {\n if (key === '$') {\n if (Array.isArray(value)) {\n return value.map((element) => {\n const file = resolve(repository.docpress.projectPath, element)\n let filename = prettify(basename(file), { mode: 'lowercase', removeIdx: true })\n if (filename === 'readme.md') {\n filename = 'introduction.md'\n }\n if (filename !== basename(file)) {\n renameSync(file, resolve(dirname(file), filename))\n }\n\n return {\n text: parse(filename).name === 'introduction'\n ? 'Introduction'\n : prettify(filename, { mode: 'capitalize', replaceDash: true, removeExt: true }),\n link: `/${prettify(repository.name, { removeDot: true })}/${parse(filename).name}`,\n } as Page\n })\n }\n return []\n } else if (typeof value === 'object') {\n return [{\n text: prettify(key, { mode: 'capitalize', replaceDash: true }),\n collapsed: true,\n items: generateSidebarItems({ ...repository, name: `${repository.name}/${key}` }, value),\n } as SidebarProject]\n }\n\n return []\n })\n}\n\n/**\n * Builds a tree structure from an array of file paths\n *\n * @param files - Array of file paths to be organized into a tree\n * @returns A nested object representing the directory structure\n */\nexport function buildTree(files: string[]): any {\n return files.reduce((tree, file) => {\n const [first, ...rest] = file.split('/')\n if (!rest.length) {\n // eslint-disable-next-line dot-notation\n tree['$'] = [...(tree['$'] || []), first]\n } else {\n tree[first] = buildTree([\n ...(tree[first] ? flattenTree(tree[first], '') : []),\n rest.join('/'),\n ])\n }\n return tree\n }, {} as Record<string, any>)\n}\n\n/**\n * Flattens a nested tree structure into an array of file paths\n *\n * @param subtree - The tree object to flatten\n * @param prefix - Optional path prefix to prepend to each result\n * @returns An array of file paths\n */\nexport function flattenTree(subtree: any, prefix = ''): string[] {\n return Object.entries(subtree).flatMap(([key, value]) => {\n if (key === '$') {\n if (Array.isArray(value)) {\n return value.map((v: string) => (prefix ? `${prefix}/${v}` : v))\n } else {\n return []\n }\n }\n return flattenTree(value, prefix ? `${prefix}/${key}` : key)\n })\n}\n\n/**\n * Reorders sidebar items to ensure 'Sources' appears last\n *\n * @param arr - Array of sidebar items to reorder\n * @returns Reordered array with 'Sources' as the last item\n */\nfunction moveSourcesLast(arr: (SidebarProject | Page)[]) {\n if (!Array.isArray(arr)) {\n return arr\n }\n const sourcesIdx = arr.findIndex(item => item.text === 'Sources')\n if (sourcesIdx === -1) {\n return arr\n }\n const [sources] = arr.splice(sourcesIdx, 1)\n arr.push(sources)\n return arr\n}\n\n/**\n * Transforms repository data into documentation structure\n *\n * @param repositories - Array of enhanced repositories\n * @param user - User information retrieved from GitHub\n * @param websiteInfos - Custom title and tagline information\n * @returns Object containing sidebar and index page configurations\n */\nexport function transformDoc(repositories: EnhancedRepository[], user: ReturnType<typeof getUserInfos>, websiteInfos: WebsiteInfos) {\n const features: Feature[] = []\n const sidebar: SidebarProject[] = []\n\n for (const repository of repositories) {\n log(` Replace urls for repository '${repository.name}'.`, 'info')\n getMdFiles([repository.docpress.projectPath]).forEach((file) => {\n log(` Processing file '${basename(file)}' for repository '${repository.name}'.`, 'debug')\n replaceRelativePath(file, `https://github.com/${repository.owner.login}/${repository.name}/tree/${repository.docpress.branch}`)\n\n if (basename(file).toLowerCase() === 'readme.md') {\n replaceReadmePath(file, `https://github.com/${repository.owner.login}/${repository.name}/tree/${repository.docpress.branch}`)\n }\n })\n\n log(` Generate sidebar for repository '${repository.name}'.`, 'info')\n const projectFiles = readdirSync(repository.docpress.projectPath, { recursive: true })\n .filter((file) => {\n return statSync(resolve(repository.docpress.projectPath, file.toString())).isFile()\n && basename(resolve(repository.docpress.projectPath, file.toString())).endsWith('.md')\n }) as string[]\n\n log(` Add sources for repository '${repository.name}'.`, 'info')\n let sourceFile\n if (projectFiles.length > 1) {\n sourceFile = resolve(repository.docpress.projectPath, 'sources.md')\n projectFiles.push('sources.md')\n } else {\n sourceFile = resolve(repository.docpress.projectPath, projectFiles[0])\n }\n addSources(repository.html_url, sourceFile)\n\n const projectTree = buildTree(projectFiles)\n const sidebarItems = moveSourcesLast(generateSidebarItems(repository, projectTree))\n\n sidebar.push(generateSidebarProject(prettify(repository.name, { removeDot: true }), sidebarItems))\n features.push(...generateFeatures(prettify(repository.name, { removeDot: true }), repository.description || ''))\n }\n\n log(` Generate index content.`, 'info')\n const index = generateIndex(features.toSorted((a, b) => a.title.localeCompare(b.title)), user, websiteInfos)\n return {\n sidebar: sidebar.toSorted((a, b) => a.text.localeCompare(b.text)),\n index,\n }\n}\n\n/**\n * Adds extra pages to the documentation from specified paths\n *\n * @param paths - Array of paths to markdown files\n * @returns Array of navigation page objects\n */\nexport function addExtraPages(paths: string[]) {\n const files = getMdFiles(paths)\n const nav: Page[] = []\n\n log(` Add extras Vitepress headers pages.`, 'info')\n for (const file of files) {\n log(` Processing file '${file}'.`, 'debug')\n const src = resolve(process.cwd(), file)\n const dest = resolve(DOCS_DIR, prettify(basename(file), { mode: 'lowercase', removeIdx: true }))\n cpSync(src, dest)\n nav.push({\n text: prettify(parse(src).name, { replaceDash: true, removeIdx: true }),\n link: `/${prettify(parse(src).name, { removeIdx: true, mode: 'lowercase' })}`,\n })\n }\n return nav\n}\n\n/**\n * Adds content from specified paths to a target directory\n *\n * @param paths - String or array of paths to content\n * @param dir - Target directory to copy content to\n * @param fn - Optional callback function to execute for each file\n */\nexport function addContent(paths: string | string[], dir: string, fn?: () => void) {\n for (const path of Array.isArray(paths) ? paths : [paths]) {\n const absolutePath = resolve(process.cwd(), path)\n const files = extractFiles(absolutePath)\n\n for (const file of files) {\n const formattedFile = file.replace(absolutePath, '.')\n log(` Processing file '${formattedFile}' for entry '${path}'.`, 'debug')\n const src = resolve(process.cwd(), file)\n const dest = resolve(dir, formattedFile)\n if (fn) {\n fn()\n }\n cpSync(src, dest)\n }\n }\n}\n\n/**\n * Creates a fork page to display external contributions\n *\n * @param forks - Array of repositories and contribution counts\n */\nexport function addForkPage(forks: { repository: Awaited<ReturnType<typeof getInfos>>['repos'][number], contributions: number }[]) {\n const separator = '---\\n'\n const header = 'layout: fork-page\\nrepoList:\\n'\n const text = '\\n# External contributions\\n\\nThis gallery is a visual representation of the collaborative work done across a variety of open-source projects, each driven by a shared passion for innovation and community growth.\\n\\nEvery tile below represents a unique project where contributions have been made-ranging from code enhancements to documentation improvements. Each project includes a summary of its goals, features, and links to GitHub for direct access.\\n\\nThis page serves as both a portfolio of past work and a resource for revisiting projects that have made a meaningful impact.\\n'\n const frontmatter = forks.map(({ repository, contributions }) => {\n const { name, owner, html_url, description, stargazers_count } = repository\n return { name, owner: owner.login, html_url, description, stargazers_count, contributions }\n })\n log(` Generate forks page.`, 'info')\n writeFileSync(FORKS_FILE, separator.concat(header, YAML.stringify(frontmatter), separator, text))\n}\n\ntype Source = Required<Awaited<ReturnType<typeof getContributors>>['source']>\n\ntype AdaptedLicense = Omit<NonNullable<Source>['license'], 'spdx_id'> & { spdx_id?: string }\n\ntype AdaptedRepository = Omit<NonNullable<Source>, 'license'> & { license: AdaptedLicense }\n\n/**\n * Processes forked repositories to generate contribution information\n *\n * @param repositories - Array of enhanced repositories\n * @param username - GitHub username\n * @param token - Optional GitHub API token\n */\nexport async function processForks(repositories: EnhancedRepository[], username: GlobalOpts['usernames'][number], token?: GlobalOpts['token']) {\n const forks = await Promise.all(\n repositories.map(async (repository) => {\n const { source, contributors } = await getContributors({ repository, token })\n return {\n contributions: contributors?.find(contributor => contributor.login === username)?.contributions ?? 0,\n repository: source as AdaptedRepository,\n }\n }),\n ).then(f => f.filter(({ repository, contributions }) => !!repository && contributions))\n\n addForkPage(forks)\n}\n\n/**\n * Parses a VitePress configuration file\n *\n * @param path - Path to the VitePress config file\n * @returns The parsed configuration object\n */\nexport async function parseVitepressConfig(path: string): Promise<Partial<ReturnType<typeof defineConfig>>> {\n const { config } = await import(resolve(process.cwd(), path)).catch(e => e)\n return config\n}\n\n/**\n * Parses a VitePress index file\n *\n * @param path - Path to the index file\n * @returns The parsed index object\n */\nexport async function parseVitepressIndex(path: string): Promise<Index> {\n const index = (await readFile(resolve(process.cwd(), path))).toString()\n return YAML.parse(index)\n}\n\n/**\n * Generates VitePress configuration and index files\n *\n * @param vitepressConfig - VitePress configuration object\n * @param index - Index page configuration\n * @returns The list of theme files that were generated\n */\nexport function generateVitepressFiles(vitepressConfig: Partial<ReturnType<typeof defineConfig>>, index: Index) {\n const separator = '---\\n'\n createDir(dirname(VITEPRESS_CONFIG))\n\n log(` Generate Vitepress config.`, 'info')\n writeFileSync(VITEPRESS_CONFIG, `export const config = ${JSON.stringify(vitepressConfig, null, 2)}\\n\\nexport default config\\n`)\n log(` Generate index file.`, 'info')\n writeFileSync(INDEX_FILE, separator.concat(YAML.stringify(index)))\n log(` Add Docpress theme files.`, 'info')\n return extractFiles(TEMPLATE_THEME).forEach((path) => {\n const relativePath = path.replace(`${TEMPLATE_THEME}/`, '')\n generateFile(path, resolve(VITEPRESS_THEME, relativePath))\n })\n}\n","import { dirname } from 'node:path'\nimport { createCommand, createOption } from 'commander'\nimport { configSchema } from '../schemas/global.js'\nimport { addOptions, parseOptions } from '../utils/commands.js'\nimport { prepareDoc } from '../lib/prepare.js'\nimport type { PrepareOpts } from '../schemas/prepare.js'\nimport { log } from '../utils/logger.js'\nimport { createDir } from '../utils/functions.js'\nimport { VITEPRESS_CONFIG } from '../utils/const.js'\nimport { globalOpts } from './global.js'\n\n/**\n * Command name for the prepare operation\n */\nconst cmdName = 'prepare'\n\n/**\n * Command line options specific to the prepare command\n */\nexport const prepareOpts = [\n createOption('-c, --extra-public-content <string>', configSchema.shape.extraPublicContent.description),\n createOption('-f, --forks', configSchema.shape.forks.description),\n createOption('-p, --extra-header-pages <string>', configSchema.shape.extraHeaderPages.description),\n createOption('-t, --extra-theme <string>', configSchema.shape.extraTheme.description),\n createOption('-v, --vitepress-config <string>', configSchema.shape.vitepressConfig.description),\n createOption('--website-title <string>', configSchema.shape.websiteTitle.description),\n createOption('--website-tagline <string>', configSchema.shape.websiteTagline.description),\n]\n\n/**\n * The prepare command definition for Commander\n */\nexport const prepareCmd = addOptions(createCommand(cmdName), [...prepareOpts, ...globalOpts])\n .description('Transform doc to the target vitepress format.')\n .action(async (opts) => {\n const parsedOpts = parseOptions(cmdName, opts)\n await main(parsedOpts)\n })\n\n/**\n * Main function to execute the prepare command\n *\n * @param opts - Validated prepare options\n */\nexport async function main(opts: PrepareOpts) {\n const { extraHeaderPages, extraPublicContent, extraTheme, vitepressConfig, forks, token, usernames, websiteTitle, websiteTagline } = opts\n log(`\\n-> Start transform files to prepare Vitepress build.`, 'info')\n\n createDir(dirname(VITEPRESS_CONFIG), { clean: true })\n for (const username of usernames) {\n await prepareDoc({ extraHeaderPages, extraPublicContent, extraTheme, vitepressConfig, forks, token, username, websiteTitle, websiteTagline })\n }\n}\n","import { Command } from 'commander'\nimport pkg from '../package.json' with { type: 'json' }\nimport { fetchCmd, main as fetchFn, fetchOpts } from './commands/fetch.js'\nimport { buildCmd, main as buildFn } from './commands/build.js'\nimport { prepareCmd, main as prepareFn, prepareOpts } from './commands/prepare.js'\nimport { addOptions, parseOptions } from './utils/commands.js'\nimport { globalOpts } from './commands/global.js'\n\n/**\n * Adds explicit defaults to options object for branch and gitProvider\n *\n * @param opts - Options object from Commander\n * @returns Options with defaults explicitly set\n */\nfunction addDefaults(opts: Record<string, unknown>): Record<string, unknown> {\n // Create a new object with explicit defaults\n return {\n ...opts,\n branch: 'main',\n gitProvider: 'github',\n }\n}\n\n/**\n * Creates and configures the Command Line Interface for DocPress\n *\n * @returns A configured Commander program instance\n */\nexport function getProgram() {\n const pm = new Command()\n .name('docpress')\n .description('Build your doc website faster than light ⚡️⚡️⚡️')\n .version(`${pkg.version}`)\n .action(async (opts, _cmd) => {\n const optsWithDefaults = addDefaults(opts)\n const parsedOpts = parseOptions('global', optsWithDefaults)\n await fetchFn(parsedOpts)\n await prepareFn(parsedOpts)\n await buildFn()\n })\n .configureHelp({\n sortSubcommands: true,\n sortOptions: true,\n showGlobalOptions: true,\n })\n .enablePositionalOptions()\n .passThroughOptions()\n .addCommand(fetchCmd)\n .addCommand(prepareCmd)\n .addCommand(buildCmd)\n\n addOptions(pm, [...fetchOpts, ...prepareOpts, ...globalOpts])\n\n return pm\n}\n\n/**\n * Entry point for the DocPress CLI\n * Initializes and runs the command parser\n */\nexport function main() {\n const pm = getProgram()\n pm.parseAsync(process.argv)\n}\n"],"names":["DOCPRESS_DIR","resolve","DOCS_DIR","INDEX_FILE","FORKS_FILE","VITEPRESS_CONFIG","VITEPRESS_THEME","VITEPRESS_USER_THEME","TEMPLATE_THEME","checkHttpStatus","url","axios","error","prettify","s","opts","u","createDir","directory","clean","existsSync","rimrafSync","mkdirSync","err","isDir","path","statSync","isFile","extractFiles","paths","readdirSync","file","join","getMdFiles","basename","prettifyEnum","arr","acc","cur","idx","getUserInfos","username","readFileSync","getUserRepos","deepMerge","objects","obj","key","accValue","objValue","isObject","val","loadConfigFile","configPath","fullPath","fileContents","splitByComma","getLogLevel","colorMap","log","msg","type","color","computedMsg","chalk","computedType","providers","configSchema","z","baseCliSchema","cliSchema","prepareConfigData","configData","validateFinalConfig","mergedConfig","globalOptsSchema","data","config","vitepressConfig","token","rest","preparedConfigData","buildOptsSchema","fetchOptsSchema","prepareOptsSchema","options","handleConfigFile","parsedConfig","parseOptions","cmd","configResult","res","errorMessage","fromError","addOptions","opt","getInfos","branch","octokit","Octokit","user","repos","getContributors","repository","message","repo","contributors","cloneRepo","name","projectDir","includes","git","simpleGit","item","appendFileSync","cpSync","rmSync","checkDoc","repoOwner","repoName","rootReadmeUrl","docsFolderUrl","docsReadmeUrl","rootReadmeStatus","docsFolderStatus","docsReadmeStatus","fetchDoc","reposFilter","generateInfos","getDoc","enhanceRepositories","enhancedRepos","computedBranch","projectPath","filtered","isRepoFiltered","getSparseCheckout","docsStatus","status","writeFileSync","hasOnlyExclusions","filter","isExcluded","isIncluded","isFiltered","globalOpts","createOption","cmdName","fetchOpts","fetchCmd","createCommand","parsedOpts","main","usernames","gitProvider","finalRF","rf","suppressVueWarnings","callback","originalWarn","args","buildCmd","_opts","vitepressBuild","generateFile","src","dest","content","dirname","replaceRelativePath","updatedContent","_match","p1","p2","replaceReadmePath","_p2","p3","defaultVitepressConfig","getVitepressConfig","sidebar","nav","prepareDoc","extraHeaderPages","extraPublicContent","extraTheme","forks","websiteTitle","websiteTagline","repositories","internals","clone_url","privateRepo","fork","docpress","websiteInfos","index","transformDoc","finalSB","finalIndex","actualConfig","parseVitepressConfig","actualIndex","parseVitepressIndex","a","b","pages","addExtraPages","p","addContent","processForks","generateVitepressFiles","addSources","repoUrl","outputPath","fileName","sourcesContent","generateIndex","features","login","bio","title","tagline","generateFeatures","description","generateSidebarProject","sidebarPages","generateSidebarItems","value","element","filename","renameSync","parse","buildTree","files","tree","first","flattenTree","subtree","prefix","v","moveSourcesLast","sourcesIdx","sources","projectFiles","sourceFile","projectTree","sidebarItems","dir","fn","absolutePath","formattedFile","addForkPage","separator","header","text","frontmatter","contributions","owner","html_url","stargazers_count","YAML","source","contributor","f","e","readFile","relativePath","prepareOpts","prepareCmd","addDefaults","getProgram","pm","Command","pkg","_cmd","optsWithDefaults","fetchFn","prepareFn","buildFn"],"mappings":"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"}
1
+ {"version":3,"file":"cli.js","sources":["../src/utils/const.ts","../src/utils/regex.ts","../src/utils/functions.ts","../src/utils/logger.ts","../src/schemas/global.ts","../src/schemas/build.ts","../src/schemas/fetch.ts","../src/schemas/prepare.ts","../src/utils/commands.ts","../src/lib/git.ts","../src/lib/fetch.ts","../src/commands/global.ts","../src/commands/fetch.ts","../src/commands/build.ts","../src/utils/templates.ts","../src/lib/vitepress.ts","../src/lib/prepare.ts","../src/commands/prepare.ts","../src/cli.ts"],"sourcesContent":["import { resolve } from 'node:path'\n\n/**\n * Main directory for DocPress files\n */\nexport const DOCPRESS_DIR = resolve(process.cwd(), 'docpress')\n\n/**\n * Path to repositories information JSON file\n */\nexport const USER_REPOS_INFOS = resolve(process.cwd(), 'docpress/repositories.json')\n\n/**\n * Path to user information JSON file\n */\nexport const USER_INFOS = resolve(process.cwd(), 'docpress/owner.json')\n\n/**\n * Directory for documentation files\n */\nexport const DOCS_DIR = resolve(process.cwd(), 'docpress/docs')\n\n/**\n * Path to the main index file\n */\nexport const INDEX_FILE = resolve(process.cwd(), 'docpress/docs/index.md')\n\n/**\n * Path to the forks documentation file\n */\nexport const FORKS_FILE = resolve(process.cwd(), 'docpress/docs/forks.md')\n\n/**\n * Path to VitePress configuration file\n */\nexport const VITEPRESS_CONFIG = resolve(process.cwd(), 'docpress/.vitepress/config.ts')\n\n/**\n * Directory for VitePress theme\n */\nexport const VITEPRESS_THEME = resolve(process.cwd(), 'docpress/.vitepress/theme')\n\n/**\n * Directory for user custom theme files\n */\nexport const VITEPRESS_USER_THEME = resolve(process.cwd(), 'docpress/.vitepress/theme/extras')\n\n/**\n * Path to template theme files\n */\n// eslint-disable-next-line dot-notation\nexport const TEMPLATE_THEME = process.env['NODE_ENV'] === 'development'\n ? resolve(import.meta.dirname, '../../public/templates/theme')\n : resolve(import.meta.dirname, './templates/theme')\n","export const relativePathRegex = /\\[([^\\]]+)\\]\\(\\.\\.\\/([^)]+)\\)/g\nexport const readmePathRegex = /\\[([^\\]]+)\\]\\((?!\\.?\\/docs\\/|docs\\/|http|#)(\\.\\/)?([^/][^)]+)\\)/g\nexport const readmeDocsPathRegex = /\\[([^\\]]+)\\]\\((\\.?\\/docs\\/|docs\\/)([^)]*)\\)/g\nexport const removeIdxRegex = /^\\d{2}-/\n","import { existsSync, mkdirSync, readdirSync, readFileSync, statSync, writeFileSync } from 'node:fs'\nimport { basename, join, resolve } from 'node:path'\nimport axios from 'axios'\nimport { rimrafSync } from 'rimraf'\nimport type { GlobalOpts } from '../schemas/global.js'\nimport type { EnhancedRepository } from '../lib/fetch.js'\nimport type { getInfos } from '../lib/git.js'\nimport { DOCPRESS_DIR } from './const.js'\nimport { readmeDocsPathRegex, readmePathRegex, relativePathRegex, removeIdxRegex } from './regex.js'\n\n/**\n * Checks the HTTP status code of a URL\n *\n * @param url - URL to check\n * @returns HTTP status code (404 if not found, 500 for errors)\n */\nexport async function checkHttpStatus(url: string): Promise<number> {\n try {\n const response = await axios.head(url)\n return response.status\n } catch (error) {\n return error.response?.status || error.status || 500\n }\n}\n\n/**\n * Options for prettifying strings\n */\ninterface PrettifyOpts {\n mode?: 'capitalize' | 'uppercase' | 'lowercase'\n replaceDash?: boolean\n removeIdx?: boolean\n removeDot?: boolean\n removeExt?: boolean\n}\n\n/**\n * Formats a string based on specified options\n *\n * @param s - Input string to format\n * @param opts - Formatting options\n * @returns Formatted string\n */\nexport function prettify(s: string, opts: PrettifyOpts) {\n let u: string = ''\n\n if (opts?.removeDot) {\n if (s.startsWith('.')) {\n u = s.slice(1)\n } else {\n u = s\n }\n // Replace all remaining dots with dashes to ensure consistency\n u = u.replaceAll('.', '-')\n }\n\n if (opts?.removeIdx) {\n u = (u || s).replace(removeIdxRegex, '')\n }\n\n if (opts?.removeExt) {\n u = (u || s).split('.')[0]\n }\n\n if (opts?.replaceDash) {\n u = (u || s).replaceAll('-', ' ')\n }\n\n if (opts?.mode === 'capitalize') {\n u = (u || s).slice(0, 1).toUpperCase() + (u || s).slice(1).toLowerCase()\n } else if (opts?.mode === 'lowercase') {\n u = (u || s).toLowerCase()\n } else if (opts?.mode === 'uppercase') {\n u = (u || s).toUpperCase()\n }\n\n return u || s\n}\n\n/**\n * Creates a directory, optionally cleaning it first\n *\n * @param directory - Path to the directory to create\n * @param options - Options object\n * @param options.clean - Whether to clean the directory before creating it\n */\nexport function createDir(directory: string, { clean }: { clean?: boolean } = { clean: false }) {\n try {\n if (clean && existsSync(directory)) {\n rimrafSync(`${directory}/*`, { glob: true })\n }\n if (!existsSync(directory)) {\n mkdirSync(directory, { recursive: true })\n }\n } catch (err) {\n console.error(err)\n }\n}\n\n/**\n * Checks if a path is a directory\n *\n * @param path - Path to check\n * @returns True if path is a directory, false otherwise\n */\nexport function isDir(path: string) {\n try {\n return statSync(path).isDirectory()\n } catch (_error) {\n return false\n }\n}\n\n/**\n * Checks if a path is a file\n *\n * @param path - Path to check\n * @returns True if path is a file, false otherwise\n */\nexport function isFile(path: string) {\n try {\n return statSync(path).isFile()\n } catch (_error) {\n return false\n }\n}\n\n/**\n * Extracts a list of file paths from directories and files\n *\n * @param paths - Path or array of paths to extract files from\n * @returns Array of file paths\n */\nexport function extractFiles(paths: string[] | string): string[] {\n return (Array.isArray(paths) ? paths : [paths]).flatMap((path) => {\n if (isFile(path)) {\n return [path]\n }\n if (isDir(path)) {\n return readdirSync(path).flatMap(file => extractFiles(join(path, file)))\n }\n return []\n })\n}\n\n/**\n * Gets all markdown files from specified paths\n *\n * @param path - Array of paths to search for markdown files\n * @returns Array of markdown file paths\n */\nexport function getMdFiles(path: string[]) {\n return extractFiles(path).filter(file => basename(file).endsWith('.md'))\n}\n\n/**\n * Formats an array of strings into a readable comma-separated list\n *\n * @param arr - Array of strings to format\n * @returns Formatted string (e.g., \"a\", \"b\" or \"c\")\n */\nexport function prettifyEnum(arr: readonly string[]) {\n return arr.reduce((acc, cur, idx, arr) => {\n if (!idx) {\n return `\"${cur}\"`\n } else if (idx === arr.length - 1) {\n return `${acc} or \"${cur}\"`\n } else {\n return `${acc}, \"${cur}\"`\n }\n }, '')\n}\n\n/**\n * Gets user information from cached JSON file\n *\n * @param username - GitHub username\n * @returns User information object\n */\nexport function getUserInfos(username: GlobalOpts['usernames'][number]) {\n return JSON.parse(readFileSync(`${DOCPRESS_DIR}/user-${username}.json`).toString()) as Awaited<ReturnType<typeof getInfos>>['user']\n}\n\n/**\n * Gets repository information from cached JSON file\n *\n * @param username - GitHub username\n * @returns Array of enhanced repository objects\n */\nexport function getUserRepos(username: GlobalOpts['usernames'][number]) {\n return JSON.parse(readFileSync(`${DOCPRESS_DIR}/repos-${username}.json`).toString()) as EnhancedRepository[]\n}\n\n/**\n * Deep merges multiple objects\n *\n * @param objects - Objects to merge\n * @returns Merged object\n */\nexport function deepMerge<T extends Record<string, any> | null>(...objects: T[]): T {\n return objects.reduce((acc, obj) => {\n if (obj === null) {\n return acc\n }\n\n Object.keys(obj).forEach((key) => {\n const accValue = acc ? acc[key] : null\n const objValue = obj[key]\n\n if (isObject(accValue) && isObject(objValue)) {\n (acc as Record<string, any>)[key] = deepMerge(accValue, objValue)\n } else {\n (acc as Record<string, any>)[key] = objValue\n }\n })\n return acc\n }, {} as T)\n}\n\n/**\n * Checks if a value is an object (not an array or null)\n *\n * @param val - Value to check\n * @returns True if value is an object, false otherwise\n */\nexport function isObject(val: any): val is object {\n return val && typeof val === 'object' && !Array.isArray(val)\n}\n\n/**\n * Loads and parses a JSON configuration file\n *\n * @param configPath - Path to the configuration file\n * @returns Parsed configuration object or empty object if file doesn't exist\n */\nexport function loadConfigFile(configPath?: string) {\n if (!configPath) {\n return {}\n }\n try {\n const fullPath = resolve(process.cwd(), configPath)\n const fileContents = readFileSync(fullPath, 'utf8')\n return JSON.parse(fileContents)\n } catch (_error) {\n return {}\n }\n}\n\n/**\n * Splits a comma-separated string into an array of strings\n *\n * @param s - Comma-separated string\n * @returns Array of strings\n */\nexport function splitByComma(s: string) {\n return s.split(',')\n}\n\n/**\n * Replaces relative paths in markdown links with absolute URLs\n *\n * @param file - Path to the markdown file to process\n * @param url - Base URL to use for absolute links\n */\nexport function replaceRelativePath(file: string, url: string) {\n const fileContent = readFileSync(file, 'utf8')\n const updatedContent = fileContent.replace(relativePathRegex, (_match, p1, p2) => {\n return `[${p1}](${url}/${p2})`\n })\n writeFileSync(file, updatedContent, 'utf8')\n}\n\n/**\n * Processes README files to fix various link formats\n *\n * @param file - Path to the README file to process\n * @param url - Base URL to use for absolute links\n */\nexport function replaceReadmePath(file: string, url: string) {\n const readmeContent = readFileSync(file, 'utf8')\n const updatedContent = readmeContent\n .replace(readmePathRegex, (_match, p1, _p2, p3) => {\n return `[${p1}](${url}/${p3})`\n })\n .replace(readmeDocsPathRegex, (_match, p1, _p2, p3) => {\n return `[${p1}](${p3})`\n })\n writeFileSync(file, updatedContent, 'utf8')\n}\n","/* eslint-disable dot-notation */\nimport type { ColorName } from 'chalk'\nimport chalk from 'chalk'\n\n/**\n * Log message types\n */\ntype LogType = keyof Pick<Console, 'info' | 'warn' | 'error' | 'debug' | 'trace'> | 'success'\n\n/**\n * Mapping of log types to colors and levels\n */\ntype ColorMap = {\n [K in LogType]: {\n color: ColorName\n level: number\n }\n}\n\n/**\n * Gets the current log level from environment variables\n *\n * @returns Log level number (default: 30)\n */\nfunction getLogLevel() {\n return typeof Number(process.env['LOG_LEVEL']) === 'number' && !Number.isNaN(Number(process.env['LOG_LEVEL']))\n ? Number(process.env['LOG_LEVEL'])\n : 30\n}\n\n/**\n * Color mapping configuration for different log types\n */\nconst colorMap: ColorMap = {\n error: { color: 'red', level: 10 },\n warn: { color: 'yellow', level: 20 },\n info: { color: 'white', level: 30 },\n success: { color: 'green', level: 30 },\n trace: { color: 'white', level: 40 },\n debug: { color: 'blue', level: 50 },\n}\n\n/**\n * Logs a message with color formatting based on type and level\n *\n * @param msg - Message to log\n * @param type - Type of log message (info, warn, error, debug, trace, success)\n * @param color - Optional specific color to use instead of the default for the type\n */\nexport function log(msg: string, type: LogType = 'info', color?: ColorName) {\n const computedMsg = color ? chalk[color](msg) : chalk[colorMap[type].color](msg)\n const computedType = type === 'success' ? 'info' : type\n\n if (getLogLevel() >= colorMap[type].level) {\n console[computedType](computedMsg)\n }\n}\n","import { z } from 'zod'\nimport { loadConfigFile, prettifyEnum, splitByComma } from '../utils/functions.js'\nimport { log } from '../utils/logger.js'\n\n/**\n * List of supported Git providers\n */\nconst providers = ['github'] as const\n\n/**\n * Schema for the DocPress configuration file\n * Defines the structure and validation rules for the configuration\n */\nexport const configSchema = z.object({\n // Global\n usernames: z.string()\n .array()\n .describe('List of comma separated Git provider usernames used to collect data.'),\n // Fetch\n branch: z.string()\n .describe('Branch used to collect Git provider data.')\n .default('main'),\n gitProvider: z.enum(providers)\n .describe(`Git provider used to retrieve data. Values should be ${prettifyEnum(providers)}.`)\n .default('github'),\n reposFilter: z.string()\n .array()\n .describe('List of comma separated repositories to retrieve from Git provider. Default to all user\\'s public repositories.'),\n // Prepare\n extraHeaderPages: z.string()\n .array()\n .describe('List of comma separated additional files or directories to process Vitepress header pages.'),\n extraPublicContent: z.string()\n .array()\n .describe('List of comma separated additional files or directories to process Vitepress public folder.'),\n extraTheme: z.string()\n .array()\n .describe('List of comma separated additional files or directories to use as Vitepress theme.'),\n forks: z.boolean()\n .describe('Whether or not to create the dedicated fork page that aggregate external contributions.')\n .default(false),\n vitepressConfig: z.any()\n .describe('Path to the vitepress configuration file.'),\n websiteTitle: z.string()\n .describe('Website title.'),\n websiteTagline: z.string()\n .describe('Website tagline.'),\n})\n\nexport type Config = z.infer<typeof configSchema>\n\n/**\n * Base CLI schema for parsing command line arguments\n * All fields are optional in this schema\n */\nexport const baseCliSchema = configSchema.partial().extend({\n config: z.string()\n .describe('Path to the docpress configuration file.')\n .optional(),\n token: z.string()\n .describe('Git provider token used to collect data.')\n .optional(),\n usernames: z.string()\n .describe(configSchema.shape.usernames.description || '')\n .optional(),\n reposFilter: z.string()\n .describe(configSchema.shape.reposFilter.description || '')\n .optional(),\n extraHeaderPages: z.string()\n .describe(configSchema.shape.extraHeaderPages.description || '')\n .optional(),\n extraPublicContent: z.string()\n .describe(configSchema.shape.extraPublicContent.description || '')\n .optional(),\n extraTheme: z.string()\n .describe(configSchema.shape.extraTheme.description || '')\n .optional(),\n vitepressConfig: z.string()\n .describe(configSchema.shape.vitepressConfig.description || '')\n .optional(),\n})\n\nexport type RawCli = z.infer<typeof baseCliSchema>\n\n/**\n * CLI schema with transformations applied to handle string-to-array conversions\n */\nexport const cliSchema = configSchema\n .partial()\n .extend({\n config: z.string()\n .describe('Path to the docpress configuration file.')\n .optional(),\n token: z.string()\n .describe('Git provider token used to collect data.')\n .optional(),\n usernames: z.string()\n .describe(configSchema.shape.usernames.description || '')\n .transform(splitByComma)\n .optional(),\n reposFilter: z.string()\n .describe(configSchema.shape.reposFilter.description || '')\n .transform(splitByComma)\n .optional(),\n extraHeaderPages: z.string()\n .describe(configSchema.shape.extraHeaderPages.description || '')\n .transform(splitByComma)\n .optional(),\n extraPublicContent: z.string()\n .describe(configSchema.shape.extraPublicContent.description || '')\n .transform(splitByComma)\n .optional(),\n extraTheme: z.string()\n .describe(configSchema.shape.extraTheme.description || '')\n .transform(splitByComma)\n .optional(),\n vitepressConfig: z.string()\n .describe(configSchema.shape.vitepressConfig.description || '')\n .optional(),\n })\n\nexport type Cli = z.infer<typeof cliSchema>\n\n// Helper functions to reduce complexity\n/**\n * Prepares configuration data by converting string values to arrays when needed\n *\n * @param configData - Raw configuration data to process\n * @returns Processed configuration data with proper array types\n */\nfunction prepareConfigData(configData: any) {\n if (!configData) return {}\n\n // Convert arrays that might be strings\n if (configData.usernames && typeof configData.usernames === 'string') {\n configData.usernames = [configData.usernames]\n }\n if (configData.reposFilter && typeof configData.reposFilter === 'string') {\n configData.reposFilter = [configData.reposFilter]\n }\n if (configData.extraHeaderPages && typeof configData.extraHeaderPages === 'string') {\n configData.extraHeaderPages = [configData.extraHeaderPages]\n }\n if (configData.extraPublicContent && typeof configData.extraPublicContent === 'string') {\n configData.extraPublicContent = [configData.extraPublicContent]\n }\n if (configData.extraTheme && typeof configData.extraTheme === 'string') {\n configData.extraTheme = [configData.extraTheme]\n }\n\n return configData\n}\n\n/**\n * Validates the final merged configuration to ensure required fields are present\n *\n * @param mergedConfig - The merged configuration to validate\n * @returns The validated configuration if it passes validation\n * @throws Error if required fields are missing\n */\nfunction validateFinalConfig(mergedConfig: any) {\n // Ensure usernames exists\n if (!mergedConfig.usernames?.length) {\n throw new Error('The usernames field is required')\n }\n\n return mergedConfig\n}\n\n/**\n * Schema for global options that combines CLI arguments and configuration files\n * Applies transformations to merge different config sources and validate the result\n */\nexport const globalOptsSchema = cliSchema\n .partial()\n .transform((data) => {\n try {\n const { config, vitepressConfig, token, ...rest } = data\n\n log(`Debug: Schema transform input: ${JSON.stringify(data)}`, 'debug')\n\n // Load configuration from file\n const configData = loadConfigFile(config)\n const preparedConfigData = prepareConfigData(configData)\n\n // Create final config\n const mergedConfig = {\n forks: false,\n ...preparedConfigData,\n ...rest,\n ...(vitepressConfig\n ? {\n vitepressConfig: {\n ...(loadConfigFile(vitepressConfig) || {}),\n ...(preparedConfigData.vitepressConfig || {}),\n },\n }\n : {}),\n }\n\n log(`Debug: Final merged config: ${JSON.stringify(mergedConfig)}`, 'debug')\n\n return validateFinalConfig({ ...mergedConfig, token })\n } catch (error) {\n // Handle errors gracefully\n log(` An error occurred while checking configuration.`, 'error')\n if (error instanceof Error) {\n log(` ${error.message}`, 'error')\n } else {\n log(` ${JSON.stringify(error, null, 2)}`, 'error')\n }\n process.exit(1)\n }\n })\n\nexport type GlobalOpts = Required<Pick<z.infer<typeof globalOptsSchema>, 'branch' | 'gitProvider'>>\n & Omit<z.infer<typeof globalOptsSchema>, 'branch' | 'gitProvider'>\n","import type { z } from 'zod'\nimport { cliSchema } from './global.js'\n\n/**\n * Schema for build command options\n * Currently empty as build doesn't require specific options\n */\nexport const buildOptsSchema = cliSchema\n .pick({})\n\nexport type BuildOpts = z.infer<typeof buildOptsSchema>\n","import { cliSchema } from './global.js'\nimport type { GlobalOpts } from './global.js'\n\n/**\n * Schema for fetch command options\n * Includes options related to Git repository fetching\n */\nexport const fetchOptsSchema = cliSchema\n .pick({\n branch: true,\n config: true,\n gitProvider: true,\n reposFilter: true,\n token: true,\n usernames: true,\n })\n\n/**\n * Type for fetch options\n */\nexport type FetchOpts = GlobalOpts\n\n/**\n * Type for fetch options with username instead of usernames array\n */\nexport type FetchOptsUser = Omit<FetchOpts, 'usernames'> & { username: FetchOpts['usernames'][number] }\n","import { cliSchema } from './global.js'\nimport type { GlobalOpts } from './global.js'\n\n/**\n * Schema for prepare command options\n * Includes options related to documentation preparation and customization\n */\nexport const prepareOptsSchema = cliSchema\n .pick({\n extraHeaderPages: true,\n extraPublicContent: true,\n extraTheme: true,\n config: true,\n gitProvider: true,\n reposFilter: true,\n token: true,\n usernames: true,\n vitepressConfig: true,\n })\n\n/**\n * Type for prepare options\n */\nexport type PrepareOpts = GlobalOpts\n","/* eslint-disable dot-notation */\nimport type { Command, Option } from 'commander'\nimport { fromError } from 'zod-validation-error'\nimport type { GlobalOpts } from '../schemas/global.js'\nimport { configSchema, globalOptsSchema } from '../schemas/global.js'\nimport type { BuildOpts } from '../schemas/build.js'\nimport { buildOptsSchema } from '../schemas/build.js'\nimport type { FetchOpts } from '../schemas/fetch.js'\nimport { fetchOptsSchema } from '../schemas/fetch.js'\nimport type { PrepareOpts } from '../schemas/prepare.js'\nimport { prepareOptsSchema } from '../schemas/prepare.js'\nimport { loadConfigFile } from './functions.js'\nimport { log } from './logger.js'\n\n/**\n * Type definition for command names\n */\ntype Cmd = 'fetch' | 'build' | 'prepare' | 'global'\n\n/**\n * Interface mapping command names to their option types\n */\ninterface Options {\n build: BuildOpts\n fetch: FetchOpts\n prepare: PrepareOpts\n global: GlobalOpts\n}\n\n/**\n * Mapping of command names to their schema validators\n */\nexport const options = {\n build: buildOptsSchema,\n fetch: fetchOptsSchema,\n prepare: prepareOptsSchema,\n global: globalOptsSchema,\n}\n\n/**\n * Handles loading and parsing of the configuration file\n *\n * @param configPath - Path to the configuration file\n * @param token - Optional GitHub token\n * @returns Parsed configuration data or null if loading/parsing failed\n */\nfunction handleConfigFile(configPath: string, token?: string) {\n const configData = loadConfigFile(configPath)\n if (!configData) return null\n\n // No need for a try/catch here since we're handling errors at a higher level\n const parsedConfig = configSchema.partial().safeParse(configData)\n if (parsedConfig.success) {\n return {\n ...parsedConfig.data,\n config: configPath,\n token: token || undefined,\n }\n }\n\n return null\n}\n\n/**\n * Parses and validates command options based on the command type\n *\n * @param cmd - The command name ('fetch', 'build', 'prepare', or 'global')\n * @param opts - Raw options from the command line\n * @returns Validated and processed options for the specified command\n */\nexport function parseOptions<T extends Cmd>(cmd: T, opts: Record<string, unknown>): Options[T] {\n log(`Initializing Docpress...`, 'info', 'blue')\n log(`\\n\\n-> Checking for required environment settings and configurations.`, 'info')\n log(` Debug info - opts: ${JSON.stringify(opts)}`, 'debug')\n log(` Debug info - options[cmd]: ${cmd}`, 'debug')\n\n try {\n // Special handling for config file\n if (cmd === 'global' && typeof opts['config'] === 'string') {\n const configResult = handleConfigFile(\n opts['config'],\n typeof opts['token'] === 'string' ? opts['token'] : undefined,\n )\n if (configResult) {\n // Force type assertion since we know the structure will match\n return configResult as unknown as Options[T]\n }\n }\n\n const res = options[cmd].safeParse(opts)\n if (!res.success) {\n try {\n const errorMessage = fromError(res.error).toString()\n log(` An error occurred while checking configuration.\\n ${errorMessage}`, 'error')\n } catch {\n // Fallback for incompatibility between zod-validation-error and Zod v4\n log(` An error occurred while checking configuration.\\n ${JSON.stringify(res.error, null, 2)}`, 'error')\n }\n process.exit(1)\n }\n log(' Setup complete! Ready to process your documentation.', 'info')\n return res.data as Options[T]\n } catch (error) {\n log(` An error occurred while processing options.`, 'error')\n if (error instanceof Error) {\n log(` ${error.message}`, 'error')\n } else {\n log(` ${JSON.stringify(error, null, 2)}`, 'error')\n }\n process.exit(1)\n }\n}\n\n/**\n * Adds option definitions to a Command instance\n *\n * @param cmd - The Commander Command instance\n * @param opts - Array of option definitions to add\n * @returns The Command instance with options added\n */\nexport function addOptions(cmd: Command, opts: Option[]) {\n for (const opt of opts) {\n cmd.addOption(opt)\n }\n return cmd\n}\n","import { appendFileSync, cpSync, rmSync } from 'node:fs'\nimport { resolve } from 'node:path'\nimport { Octokit } from '@octokit/rest'\nimport { simpleGit } from 'simple-git'\nimport type { GlobalOpts } from '../schemas/global.js'\nimport type { FetchOpts } from '../schemas/fetch.js'\nimport { createDir } from '../utils/functions.js'\nimport { log } from '../utils/logger.js'\nimport type { EnhancedRepository } from './fetch.js'\n\n/**\n * Fetches user and repository information from GitHub\n *\n * @param options - Options for retrieving GitHub data\n * @param options.username - GitHub username\n * @param options.token - GitHub API token\n * @param options.branch - Branch to use for documentation\n * @returns Object containing user information, repositories, and branch\n */\nexport async function getInfos({ username, token, branch }: Pick<FetchOpts, 'branch'> & Pick<GlobalOpts, 'token'> & { username: GlobalOpts['usernames'][number] }) {\n log(` Get infos for username '${username}'.`, 'info')\n const octokit = new Octokit({ auth: token })\n log(` Get user infos.`, 'debug')\n const { data: user } = await octokit.rest.users.getByUsername({ username })\n log(` Get repositories infos.`, 'debug')\n const { data: repos } = await octokit.rest.repos.listForUser({ username, sort: 'full_name', per_page: 500 })\n\n return { user, repos, branch }\n}\n\n/**\n * Gets contributors for a repository\n *\n * @param options - Options for retrieving contributors\n * @param options.repository - Repository information\n * @param options.token - GitHub API token\n * @returns Object with source repository and contributors list\n */\nexport async function getContributors({\n repository,\n token,\n}: {\n repository: EnhancedRepository\n token: GlobalOpts['token']\n}) {\n log(` Get contributors infos for repository '${repository.name}'.`, 'info')\n const octokit = new Octokit({\n auth: token,\n log: {\n debug: () => {},\n info: () => {},\n warn: (message) => {\n if (!message.includes('404')) console.warn(message)\n },\n error: (message) => {\n if (!message.includes('404')) console.error(message)\n },\n },\n })\n const { data: repo } = await octokit.rest.repos.get({\n owner: repository.owner.login,\n repo: repository.name,\n })\n if (!repo.source?.owner?.login) {\n return { source: repo.source, contributors: [] }\n }\n const contributors: Array<any> = []\n try {\n for await (const { data } of octokit.paginate.iterator(\n octokit.rest.repos.listContributors,\n {\n owner: repo.source.owner.login,\n repo: repo.parent?.name ?? repo.name,\n per_page: 500,\n },\n )) {\n contributors.push(...data)\n }\n } catch (error) {\n log(\n ` Failed to get contributors infos for repository '${repository.name}'. Error : ${error.message}`,\n 'warn',\n )\n return { source: repo.source, contributors: [] }\n }\n\n return { source: repo.source, contributors }\n}\n\n/**\n * Clones a repository with sparse checkout\n *\n * @param name - Repository name\n * @param url - Repository URL\n * @param projectDir - Directory to clone into\n * @param branch - Branch to clone\n * @param includes - Patterns to include in sparse checkout\n */\nexport async function cloneRepo(name: string, url: string, projectDir: string, branch: string, includes: string[]) {\n createDir(projectDir, { clean: true })\n\n try {\n const git = simpleGit({ baseDir: projectDir })\n await git.init()\n .addConfig('core.sparseCheckout', 'true', true, 'local')\n .addRemote('origin', url)\n\n for (const item of includes) {\n log(` Add '${item}' to '${name}' sparse-checkout file.`, 'debug')\n appendFileSync(resolve(projectDir, '.git/info/sparse-checkout'), `${item}\\n`, 'utf8')\n }\n\n log(` Clone repository '${name}'.`, 'info')\n await git.pull('origin', branch)\n\n if (includes.some(item => item.includes('docs'))) {\n cpSync(resolve(projectDir, 'docs'), projectDir, { recursive: true })\n rmSync(resolve(projectDir, 'docs'), { recursive: true })\n }\n rmSync(resolve(projectDir, '.git'), { recursive: true })\n } catch (error) {\n log(` Error when cloning repository: ${error}.`, 'error')\n }\n}\n","import { resolve } from 'node:path'\nimport { writeFileSync } from 'node:fs'\nimport type { GlobalOpts } from '../schemas/global.js'\nimport type { FetchOpts, FetchOptsUser } from '../schemas/fetch.js'\nimport { checkHttpStatus, prettify } from '../utils/functions.js'\nimport { DOCPRESS_DIR, DOCS_DIR } from '../utils/const.js'\nimport { log } from '../utils/logger.js'\nimport { cloneRepo, getInfos } from './git.js'\n\n/**\n * Enhanced repository type with DocPress-specific metadata\n */\nexport type EnhancedRepository = Awaited<ReturnType<typeof getInfos>>['repos'][number] & {\n docpress: {\n branch: string\n filtered: boolean\n includes: string[]\n projectPath: string\n raw_url: string\n replace_url: string\n }\n}\n\n/**\n * Checks for the existence of documentation files in a repository\n *\n * @param repoOwner - Owner of the repository (username)\n * @param repoName - Name of the repository\n * @param branch - Branch to check for documentation\n * @returns Object containing HTTP status codes for different documentation paths\n */\nexport async function checkDoc(repoOwner: GlobalOpts['usernames'][number], repoName: string, branch: FetchOpts['branch']) {\n const rootReadmeUrl = `https://github.com/${repoOwner}/${repoName}/tree/${branch}/README.md`\n const docsFolderUrl = `https://github.com/${repoOwner}/${repoName}/tree/${branch}/docs`\n const docsReadmeUrl = `https://github.com/${repoOwner}/${repoName}/tree/${branch}/docs/01-readme.md`\n\n const rootReadmeStatus = await checkHttpStatus(rootReadmeUrl)\n const docsFolderStatus = await checkHttpStatus(docsFolderUrl)\n const docsReadmeStatus = await checkHttpStatus(docsReadmeUrl)\n\n return {\n rootReadmeStatus,\n docsFolderStatus,\n docsReadmeStatus,\n }\n}\n\n/**\n * Fetches documentation from a user's repositories\n *\n * @param options - Options for fetching documentation\n * @param options.username - GitHub username\n * @param options.branch - Branch to use for documentation\n * @param options.reposFilter - Optional filter for repositories\n * @param options.token - GitHub API token\n */\nexport async function fetchDoc({ username, branch, reposFilter, token }: FetchOptsUser) {\n await getInfos({ username, token, branch })\n .then(async ({ user, repos, branch }) => generateInfos(user, repos, branch, reposFilter))\n .then(async ({ repos }) => getDoc(repos, reposFilter))\n}\n\n/**\n * Enhances repository information with DocPress metadata\n *\n * @param repos - List of repositories from Git provider\n * @param branch - Branch to use for documentation\n * @param reposFilter - Optional filter for repositories\n * @returns Array of enhanced repositories with DocPress metadata\n */\nexport async function enhanceRepositories(repos: Awaited<ReturnType<typeof getInfos>>['repos'], branch?: FetchOpts['branch'], reposFilter?: FetchOpts['reposFilter']) {\n const enhancedRepos: EnhancedRepository[] = []\n\n await Promise.all(\n repos.map(async (repo) => {\n const computedBranch = branch ?? repo.default_branch ?? 'main'\n const projectPath = resolve(DOCS_DIR, prettify(repo.name, { removeDot: true }))\n const filtered = isRepoFiltered(repo, reposFilter)\n let includes: string[] = []\n\n if (!repo.fork && !repo.private && !filtered) {\n includes = await getSparseCheckout(repo, computedBranch)\n }\n\n enhancedRepos.push({\n ...repo,\n docpress: {\n filtered,\n branch: computedBranch,\n includes,\n projectPath,\n raw_url: `https://raw.githubusercontent.com/${repo.owner.login}/${repo.name}/${computedBranch}`,\n replace_url: `https://github.com/${repo.owner.login}/${repo.name}/tree/${computedBranch}`,\n },\n })\n }),\n )\n\n return enhancedRepos\n}\n\n/**\n * Determines which files to include in the sparse checkout based on repository structure\n *\n * @param repo - Repository information\n * @param branch - Branch to check for documentation\n * @returns Array of file patterns to include in sparse checkout\n */\nexport async function getSparseCheckout(repo: Awaited<ReturnType<typeof getInfos>>['repos'][number], branch: FetchOpts['branch']) {\n const docsStatus = await checkDoc(repo.owner.login, repo.name, branch)\n\n const includes: string[] = []\n if (Object.values(docsStatus).every(status => status === 404) || !repo.size) {\n return []\n }\n if (docsStatus.docsFolderStatus !== 404) {\n includes.push('docs/*')\n }\n if (docsStatus.docsFolderStatus === 404 || docsStatus.docsReadmeStatus === 404) {\n includes.push('README.md', '!*/**/README.md')\n }\n return includes\n}\n\n/**\n * Generates and saves user and repository information\n *\n * @param user - User information from Git provider\n * @param repos - List of repositories from Git provider\n * @param branch - Branch to use for documentation\n * @param reposFilter - Optional filter for repositories\n * @returns Object containing user and enhanced repository information\n */\nexport async function generateInfos(user: Awaited<ReturnType<typeof getInfos>>['user'], repos: Awaited<ReturnType<typeof getInfos>>['repos'], branch?: FetchOpts['branch'], reposFilter?: FetchOpts['reposFilter']) {\n writeFileSync(`${DOCPRESS_DIR}/user-${user.login}.json`, JSON.stringify(user, null, 2))\n\n const enhancedRepos = await enhanceRepositories(repos, branch, reposFilter)\n writeFileSync(`${DOCPRESS_DIR}/repos-${user.login}.json`, JSON.stringify(enhancedRepos, null, 2))\n\n return { user, repos: enhancedRepos }\n}\n\n/**\n * Fetches documentation from repositories\n *\n * @param repos - List of enhanced repositories\n * @param reposFilter - Optional filter for repositories\n */\nexport async function getDoc(repos?: EnhancedRepository[], reposFilter?: FetchOpts['reposFilter']) {\n if (!repos) {\n log(` No repository respect docpress rules.`, 'warn')\n return\n }\n\n await Promise.all(\n repos\n .filter(repo => !isRepoFiltered(repo, reposFilter))\n .map(async (repo) => {\n await cloneRepo(repo.name, repo.clone_url as string, repo.docpress.projectPath, repo.docpress.branch, repo.docpress.includes)\n }),\n )\n}\n\n/**\n * Determines if a repository should be filtered out based on filter rules\n *\n * @param repo - Repository information\n * @param reposFilter - Optional filter for repositories\n * @returns True if the repository should be filtered out, false otherwise\n */\nexport function isRepoFiltered(repo: EnhancedRepository | Awaited<ReturnType<typeof getInfos>>['repos'][number], reposFilter?: FetchOpts['reposFilter']) {\n const hasOnlyExclusions = reposFilter?.every((filter: string) => filter.startsWith('!'))\n const isExcluded = reposFilter?.filter((filter: string) => filter.startsWith('!'))\n .some((filter: string) => repo.name === filter.substring(1))\n const isIncluded = !reposFilter\n || reposFilter?.filter((filter: string) => !filter.startsWith('!')).includes(repo.name)\n || (repo.fork && !isExcluded)\n || (hasOnlyExclusions && !isExcluded)\n\n const isFiltered = isExcluded || !isIncluded\n\n if ('docpress' in repo && !repo.docpress.includes.length) {\n return true\n }\n\n if (!!repo.clone_url && !repo.private && !isFiltered) {\n return false\n }\n return true\n}\n","import { createOption } from 'commander'\nimport { baseCliSchema } from '../schemas/global.js'\n\n/**\n * Global command line options shared across all commands\n */\nexport const globalOpts = [\n createOption('-C, --config <string>', baseCliSchema.shape.config.description),\n createOption('-T, --token <string>', baseCliSchema.shape.token.description),\n createOption('-U, --usernames <string>', baseCliSchema.shape.usernames.description),\n]\n","import { createCommand, createOption } from 'commander'\nimport { createDir } from '../utils/functions.js'\nimport { DOCPRESS_DIR } from '../utils/const.js'\nimport { log } from '../utils/logger.js'\nimport { addOptions, parseOptions } from '../utils/commands.js'\nimport type { FetchOpts } from '../schemas/fetch.js'\nimport { fetchDoc } from '../lib/fetch.js'\nimport { configSchema } from '../schemas/global.js'\nimport { globalOpts } from './global.js'\n\n/**\n * Command name for the fetch operation\n */\nconst cmdName = 'fetch'\n\n/**\n * Command line options specific to the fetch command\n */\nexport const fetchOpts = [\n createOption('-b, --branch <string>', configSchema.shape.branch.description)\n .default(configSchema.shape.branch.default),\n createOption('-g, --git-provider <string>', configSchema.shape.gitProvider.description)\n .default(configSchema.shape.gitProvider.default),\n createOption('-r, --repos-filter <string>', configSchema.shape.reposFilter.description),\n]\n\n/**\n * The fetch command definition for Commander\n */\nexport const fetchCmd = addOptions(createCommand(cmdName), [...fetchOpts, ...globalOpts])\n .description('Fetch docs with the given username(s) and git provider.')\n .action(async (opts) => {\n const parsedOpts = parseOptions(cmdName, opts)\n await main(parsedOpts)\n })\n\n/**\n * Main function to execute the fetch command\n *\n * @param opts - Validated fetch options\n */\nexport async function main(opts: FetchOpts) {\n const { usernames, reposFilter, token, branch, gitProvider } = opts\n log(`\\n-> Start fetching documentation files. This may take a moment, especially for larger repositories.`, 'info')\n\n createDir(DOCPRESS_DIR, { clean: true })\n for (const username of usernames) {\n const finalRF = usernames.length > 1\n ? reposFilter?.filter((rf: string) => rf.startsWith(`${username}/`)).map((rf: string) => rf.replace(`${username}/`, ''))\n : reposFilter\n await fetchDoc({ username, branch, reposFilter: finalRF, gitProvider, token })\n }\n}\n","import { build as vitepressBuild } from 'vitepress'\nimport { createCommand } from 'commander'\nimport { addOptions } from '../utils/commands.js'\nimport { DOCPRESS_DIR } from '../utils/const.js'\nimport { log } from '../utils/logger.js'\nimport { globalOpts } from './global.js'\n\n/**\n * Suppress specific Vue warnings during the build process\n *\n * @param callback - Function to execute while warnings are suppressed\n * @returns The result of the callback function\n */\nexport async function suppressVueWarnings<T>(callback: () => Promise<T>): Promise<T> {\n // Store the original console.warn\n const originalWarn = console.warn\n\n // Override console.warn to suppress specific Vue warnings\n console.warn = function (...args) {\n if (\n args.length > 0\n && typeof args[0] === 'string'\n && (args[0].includes('[Vue warn]: Invalid watch source:')\n || args[0].includes('{ open: false }'))\n ) {\n // Skip this warning\n return\n }\n // Pass other warnings to the original console.warn\n originalWarn.apply(console, args)\n }\n\n try {\n // Execute the callback with warnings suppressed\n return await callback()\n } finally {\n // Restore the original console.warn\n console.warn = originalWarn\n }\n}\n\n/**\n * Command name for the build operation\n */\nconst cmdName = 'build'\n\n/**\n * Command line options specific to the build command (none currently)\n */\nexport const buildOpts = []\n\n/**\n * The build command definition for Commander\n */\nexport const buildCmd = addOptions(createCommand(cmdName), globalOpts)\n .description('Build vitepress website.')\n .action(async (_opts) => {\n await main()\n })\n\n/**\n * Main function to execute the build command\n * Builds the VitePress static site\n */\nexport async function main() {\n log(`\\n-> Start building Vitepress website.\\n\\n`, 'info')\n\n try {\n // Build VitePress with Vue warnings suppressed\n await suppressVueWarnings(async () => {\n await vitepressBuild(DOCPRESS_DIR)\n })\n\n log(`\\n\\nDocpress build succedeed.`, 'success')\n } catch (error) {\n log(`\\n\\nDocpress build failed : ${error}`, 'error')\n process.exit(1)\n }\n}\n","import { readFileSync, writeFileSync } from 'node:fs'\nimport { dirname } from 'node:path'\nimport { createDir } from './functions.js'\n\n/**\n * Generates a file by copying content from source to destination\n *\n * @param src - Path to the source file\n * @param dest - Path to the destination file\n */\nexport function generateFile(src: string, dest: string) {\n const content = readFileSync(src, { encoding: 'utf8' })\n createDir(dirname(dest))\n writeFileSync(dest, content)\n}\n","import type { defineConfig } from 'vitepress'\nimport { deepMerge } from '../utils/functions.js'\nimport type { Page, SidebarProject } from './prepare.js'\n\n/**\n * Default VitePress configuration\n */\nconst defaultVitepressConfig: ReturnType<typeof defineConfig> = {\n base: '/',\n lang: 'en-US',\n vite: {\n publicDir: '../public',\n },\n title: 'Home',\n description: 'Docpress',\n srcDir: './docs',\n cleanUrls: false,\n ignoreDeadLinks: 'localhostLinks',\n themeConfig: {\n outline: [2, 3],\n search: {\n provider: 'local',\n options: {\n translations: {\n button: {\n buttonText: 'Search...',\n buttonAriaLabel: 'Search',\n },\n modal: {\n backButtonTitle: 'erase search',\n displayDetails: 'show details',\n noResultsText: 'No results for : ',\n resetButtonTitle: 'cancel search',\n footer: {\n selectText: 'go to',\n navigateText: 'navigate in results',\n closeText: 'close',\n },\n },\n },\n },\n },\n },\n}\n\n/**\n * Generates VitePress configuration by merging default and custom configs\n *\n * @param sidebar - Sidebar configuration\n * @param nav - Navigation configuration\n * @param vitepressConfig - Optional custom VitePress configuration\n * @returns Merged VitePress configuration\n */\nexport function getVitepressConfig(sidebar: SidebarProject[], nav: Page[], vitepressConfig?: ReturnType<typeof defineConfig>): Partial<ReturnType<typeof defineConfig>> {\n const config = vitepressConfig\n ? deepMerge(defaultVitepressConfig, vitepressConfig, { themeConfig: { sidebar, nav } })\n : deepMerge(defaultVitepressConfig, { themeConfig: { sidebar, nav } })\n return config\n}\n","import { basename, dirname, parse, resolve } from 'node:path'\nimport { appendFileSync, cpSync, existsSync, readdirSync, renameSync, statSync, writeFileSync } from 'node:fs'\nimport { readFile } from 'node:fs/promises'\nimport YAML from 'yaml'\nimport type { defineConfig } from 'vitepress'\nimport type { PrepareOpts } from '../schemas/prepare.js'\nimport { generateFile } from '../utils/templates.js'\nimport type { GlobalOpts } from '../schemas/global.js'\nimport { createDir, extractFiles, getMdFiles, getUserInfos, getUserRepos, prettify, replaceReadmePath, replaceRelativePath } from '../utils/functions.js'\nimport { DOCPRESS_DIR, DOCS_DIR, FORKS_FILE, INDEX_FILE, TEMPLATE_THEME, VITEPRESS_CONFIG, VITEPRESS_THEME, VITEPRESS_USER_THEME } from '../utils/const.js'\nimport { log } from '../utils/logger.js'\nimport type { EnhancedRepository } from './fetch.js'\nimport type { getInfos } from './git.js'\nimport { getContributors } from './git.js'\nimport { getVitepressConfig } from './vitepress.js'\n\n/**\n * Represents a navigation page item with text and link\n */\nexport interface Page {\n text: string\n link: string\n}\n\n/**\n * Represents a sidebar project with nested items\n */\nexport interface SidebarProject {\n text: string\n collapsed: boolean\n items: (Page | SidebarProject)[]\n}\n\n/**\n * Represents a feature to display on the index page\n */\nexport interface Feature {\n title: string\n details: string\n link: string\n}\n\n/**\n * Represents the structure of the VitePress index page\n */\nexport interface Index {\n layout: string\n hero: {\n name: string\n tagline?: string\n }\n /** List of features to display */\n features: Feature[]\n}\n\n/**\n * Prepares the documentation structure for a user's repositories\n *\n * @param options - Options for documentation preparation\n * @param options.extraHeaderPages - Array of paths to additional header pages\n * @param options.extraPublicContent - Array of paths to additional public content\n * @param options.extraTheme - Array of paths to additional theme files\n * @param options.vitepressConfig - Path to the VitePress configuration file\n * @param options.forks - Flag to include forked repositories\n * @param options.token - GitHub token for API access\n * @param options.username - GitHub username to fetch repositories for\n * @param options.websiteTitle - Custom title for the documentation website\n * @param options.websiteTagline - Custom tagline for the documentation website\n */\nexport async function prepareDoc({ extraHeaderPages, extraPublicContent, extraTheme, vitepressConfig, forks, token, username, websiteTitle, websiteTagline }: Omit<PrepareOpts, 'usernames' | 'branch' | 'gitProvider' | 'reposFilter'> & { username: PrepareOpts['usernames'][number] }) {\n const user = getUserInfos(username)\n const repositories = getUserRepos(username)\n .reduce(({ internals, forks }: { internals: EnhancedRepository[], forks: EnhancedRepository[] }, cur) => {\n const { clone_url, private: privateRepo, fork, docpress } = cur\n if (clone_url && !privateRepo && !docpress.filtered) {\n if (!fork && docpress.includes.length) {\n return { internals: [...internals, cur], forks }\n } else if (fork) {\n return { internals, forks: [...forks, cur] }\n }\n }\n return { internals, forks }\n }, { internals: [], forks: [] })\n\n const websiteInfos = { title: websiteTitle, tagline: websiteTagline }\n const { index, sidebar } = transformDoc(repositories.internals, user, websiteInfos)\n\n let finalSB\n let finalIndex\n if (existsSync(INDEX_FILE) && existsSync(VITEPRESS_CONFIG)) {\n const actualConfig = await parseVitepressConfig(VITEPRESS_CONFIG)\n const actualIndex = await parseVitepressIndex(INDEX_FILE)\n finalSB = [\n ...(actualConfig.themeConfig?.sidebar as SidebarProject[] ?? []),\n ...sidebar,\n ].sort((a, b) => a.text.localeCompare(b.text))\n finalIndex = {\n ...index,\n features: [\n ...actualIndex.features,\n ...index.features,\n ].sort((a, b) => a.title.localeCompare(b.title)),\n }\n } else {\n finalSB = sidebar\n finalIndex = index\n }\n const nav: Page[] = []\n\n if (extraHeaderPages) {\n const pages = addExtraPages(extraHeaderPages)\n if (forks) {\n nav.push(...pages.filter(p => p.link !== '/forks'))\n } else {\n nav.push(...pages)\n }\n }\n if (extraPublicContent) {\n log(` Add extras Vitepress public folder content.`, 'info')\n addContent(extraPublicContent, resolve(DOCPRESS_DIR, 'public'))\n }\n if (extraTheme) {\n log(` Add extras Vitepress theme files.`, 'info')\n addContent(extraTheme, resolve(VITEPRESS_USER_THEME))\n }\n if (forks && username.length) {\n log(` Add fork page to display external contributions.`, 'info')\n await processForks(repositories.forks, username, token)\n nav.push({ text: 'Forks', link: '/forks' })\n }\n\n const config = getVitepressConfig(finalSB, nav, vitepressConfig)\n\n generateVitepressFiles(config, finalIndex)\n}\n\n/**\n * Adds a source reference section to a markdown file\n *\n * @param repoUrl - URL of the GitHub repository\n * @param outputPath - Path to the markdown file where sources will be added\n */\nexport function addSources(repoUrl: string, outputPath: string) {\n const fileName = basename(outputPath)\n const title = prettify(fileName, { mode: 'lowercase', removeIdx: true }) === 'readme.md' ? '\\n## Sources' : '# Sources'\n\n const sourcesContent = `${title}\\n\\nTake a look at the [project sources](${repoUrl}).\\n`\n\n appendFileSync(outputPath, sourcesContent, 'utf8')\n}\n\n/**\n * Information about website title and tagline\n */\nexport interface WebsiteInfos {\n title?: string\n tagline?: string\n}\n\n/**\n * Generates the index page content for the documentation site\n *\n * @param features - Array of features to display on the homepage\n * @param user - User information retrieved from GitHub\n * @param websiteInfos - Custom title and tagline information\n * @returns An object with index page configuration\n */\nexport function generateIndex(features: Feature[], user: ReturnType<typeof getUserInfos>, websiteInfos: WebsiteInfos) {\n const { name, login, bio } = user\n const { title, tagline } = websiteInfos\n\n const hero = title\n ? { name: title, tagline }\n : { name: name ? `${name}'s projects` : `${login}'s projects`, tagline: bio ?? 'Robots are everywhere 🤖' }\n\n return {\n layout: 'home',\n hero,\n features,\n }\n}\n\n/**\n * Generates feature cards for the homepage\n *\n * @param repoName - Name of the repository\n * @param description - Description of the repository\n * @param features - Optional existing features to append to\n * @returns Array of feature objects for the homepage\n */\nexport function generateFeatures(repoName: string, description: string, features?: Feature[]) {\n const content = {\n title: prettify(repoName, { mode: 'capitalize', replaceDash: true }),\n details: description,\n link: `/${prettify(repoName, { removeDot: true })}/introduction`,\n }\n\n return features ? [...features, content] : [content]\n}\n\n/**\n * Generates a sidebar project entry for the documentation navigation\n *\n * @param repoName - Name of the repository\n * @param sidebarPages - Array of sidebar pages to include in this project\n * @returns A sidebar project configuration object\n */\nexport function generateSidebarProject(repoName: string, sidebarPages: (SidebarProject | Page)[]) {\n return {\n text: prettify(repoName, { mode: 'capitalize', replaceDash: true }),\n collapsed: true,\n items: sidebarPages,\n }\n}\n\n/**\n * Generates sidebar page entries for the documentation navigation\n *\n * @param repoName - Name of the repository\n * @param fileName - Name of the file\n * @param sidebarPages - Optional existing sidebar pages to append to\n * @returns Array of page objects for the sidebar\n */\nexport function generateSidebarPages(repoName: string, fileName: string, sidebarPages?: Page[]) {\n const content = {\n text: fileName === 'introduction' ? 'Introduction' : prettify(fileName, { mode: 'capitalize', replaceDash: true }),\n link: `/${prettify(repoName, { removeDot: true })}/${fileName}`,\n }\n\n return sidebarPages ? [...sidebarPages, content] : [content]\n}\n\n/**\n * Generates sidebar items from a repository's file structure\n *\n * @param repository - Repository information\n * @param obj - Object representing the file tree structure\n * @returns Array of sidebar items (projects and pages)\n */\nexport function generateSidebarItems(repository: EnhancedRepository, obj: any): (SidebarProject | Page)[] {\n return Object.entries(obj).flatMap(([key, value]): (SidebarProject | Page)[] => {\n if (key === '$') {\n if (Array.isArray(value)) {\n return value.map((element) => {\n const file = resolve(repository.docpress.projectPath, element)\n let filename = prettify(basename(file), { mode: 'lowercase', removeIdx: true })\n if (filename === 'readme.md') {\n filename = 'introduction.md'\n }\n if (filename !== basename(file)) {\n renameSync(file, resolve(dirname(file), filename))\n }\n\n return {\n text: parse(filename).name === 'introduction'\n ? 'Introduction'\n : prettify(filename, { mode: 'capitalize', replaceDash: true, removeExt: true }),\n link: `/${prettify(repository.name, { removeDot: true })}/${parse(filename).name}`,\n } as Page\n })\n }\n return []\n } else if (typeof value === 'object') {\n return [{\n text: prettify(key, { mode: 'capitalize', replaceDash: true }),\n collapsed: true,\n items: generateSidebarItems({ ...repository, name: `${repository.name}/${key}` }, value),\n } as SidebarProject]\n }\n\n return []\n })\n}\n\n/**\n * Builds a tree structure from an array of file paths\n *\n * @param files - Array of file paths to be organized into a tree\n * @returns A nested object representing the directory structure\n */\nexport function buildTree(files: string[]): any {\n return files.reduce((tree, file) => {\n const [first, ...rest] = file.split('/')\n if (!rest.length) {\n // eslint-disable-next-line dot-notation\n tree['$'] = [...(tree['$'] || []), first]\n } else {\n tree[first] = buildTree([\n ...(tree[first] ? flattenTree(tree[first], '') : []),\n rest.join('/'),\n ])\n }\n return tree\n }, {} as Record<string, any>)\n}\n\n/**\n * Flattens a nested tree structure into an array of file paths\n *\n * @param subtree - The tree object to flatten\n * @param prefix - Optional path prefix to prepend to each result\n * @returns An array of file paths\n */\nexport function flattenTree(subtree: any, prefix = ''): string[] {\n return Object.entries(subtree).flatMap(([key, value]) => {\n if (key === '$') {\n if (Array.isArray(value)) {\n return value.map((v: string) => (prefix ? `${prefix}/${v}` : v))\n } else {\n return []\n }\n }\n return flattenTree(value, prefix ? `${prefix}/${key}` : key)\n })\n}\n\n/**\n * Reorders sidebar items to ensure 'Sources' appears last\n *\n * @param arr - Array of sidebar items to reorder\n * @returns Reordered array with 'Sources' as the last item\n */\nfunction moveSourcesLast(arr: (SidebarProject | Page)[]) {\n if (!Array.isArray(arr)) {\n return arr\n }\n const sourcesIdx = arr.findIndex(item => item.text === 'Sources')\n if (sourcesIdx === -1) {\n return arr\n }\n const [sources] = arr.splice(sourcesIdx, 1)\n arr.push(sources)\n return arr\n}\n\n/**\n * Transforms repository data into documentation structure\n *\n * @param repositories - Array of enhanced repositories\n * @param user - User information retrieved from GitHub\n * @param websiteInfos - Custom title and tagline information\n * @returns Object containing sidebar and index page configurations\n */\nexport function transformDoc(repositories: EnhancedRepository[], user: ReturnType<typeof getUserInfos>, websiteInfos: WebsiteInfos) {\n const features: Feature[] = []\n const sidebar: SidebarProject[] = []\n\n for (const repository of repositories) {\n log(` Replace urls for repository '${repository.name}'.`, 'info')\n getMdFiles([repository.docpress.projectPath]).forEach((file) => {\n log(` Processing file '${basename(file)}' for repository '${repository.name}'.`, 'debug')\n replaceRelativePath(file, `https://github.com/${repository.owner.login}/${repository.name}/tree/${repository.docpress.branch}`)\n\n if (basename(file).toLowerCase() === 'readme.md') {\n replaceReadmePath(file, `https://github.com/${repository.owner.login}/${repository.name}/tree/${repository.docpress.branch}`)\n }\n })\n\n log(` Generate sidebar for repository '${repository.name}'.`, 'info')\n const projectFiles = readdirSync(repository.docpress.projectPath, { recursive: true })\n .filter((file) => {\n return statSync(resolve(repository.docpress.projectPath, file.toString())).isFile()\n && basename(resolve(repository.docpress.projectPath, file.toString())).endsWith('.md')\n }) as string[]\n\n log(` Add sources for repository '${repository.name}'.`, 'info')\n let sourceFile\n if (projectFiles.length > 1) {\n sourceFile = resolve(repository.docpress.projectPath, 'sources.md')\n projectFiles.push('sources.md')\n } else {\n sourceFile = resolve(repository.docpress.projectPath, projectFiles[0])\n }\n addSources(repository.html_url, sourceFile)\n\n const projectTree = buildTree(projectFiles)\n const sidebarItems = moveSourcesLast(generateSidebarItems(repository, projectTree))\n\n sidebar.push(generateSidebarProject(prettify(repository.name, { removeDot: true }), sidebarItems))\n features.push(...generateFeatures(prettify(repository.name, { removeDot: true }), repository.description || ''))\n }\n\n log(` Generate index content.`, 'info')\n const index = generateIndex(features.toSorted((a, b) => a.title.localeCompare(b.title)), user, websiteInfos)\n return {\n sidebar: sidebar.toSorted((a, b) => a.text.localeCompare(b.text)),\n index,\n }\n}\n\n/**\n * Adds extra pages to the documentation from specified paths\n *\n * @param paths - Array of paths to markdown files\n * @returns Array of navigation page objects\n */\nexport function addExtraPages(paths: string[]) {\n const files = getMdFiles(paths)\n const nav: Page[] = []\n\n log(` Add extras Vitepress headers pages.`, 'info')\n for (const file of files) {\n log(` Processing file '${file}'.`, 'debug')\n const src = resolve(process.cwd(), file)\n const dest = resolve(DOCS_DIR, prettify(basename(file), { mode: 'lowercase', removeIdx: true }))\n cpSync(src, dest)\n nav.push({\n text: prettify(parse(src).name, { replaceDash: true, removeIdx: true }),\n link: `/${prettify(parse(src).name, { removeIdx: true, mode: 'lowercase' })}`,\n })\n }\n return nav\n}\n\n/**\n * Adds content from specified paths to a target directory\n *\n * @param paths - String or array of paths to content\n * @param dir - Target directory to copy content to\n * @param fn - Optional callback function to execute for each file\n */\nexport function addContent(paths: string | string[], dir: string, fn?: () => void) {\n for (const path of Array.isArray(paths) ? paths : [paths]) {\n const absolutePath = resolve(process.cwd(), path)\n const files = extractFiles(absolutePath)\n\n for (const file of files) {\n const formattedFile = file.replace(absolutePath, '.')\n log(` Processing file '${formattedFile}' for entry '${path}'.`, 'debug')\n const src = resolve(process.cwd(), file)\n const dest = resolve(dir, formattedFile)\n if (fn) {\n fn()\n }\n cpSync(src, dest)\n }\n }\n}\n\n/**\n * Creates a fork page to display external contributions\n *\n * @param forks - Array of repositories and contribution counts\n */\nexport function addForkPage(forks: { repository: Awaited<ReturnType<typeof getInfos>>['repos'][number], contributions: number }[]) {\n const separator = '---\\n'\n const header = 'layout: fork-page\\nrepoList:\\n'\n const text = '\\n# External contributions\\n\\nThis gallery is a visual representation of the collaborative work done across a variety of open-source projects, each driven by a shared passion for innovation and community growth.\\n\\nEvery tile below represents a unique project where contributions have been made-ranging from code enhancements to documentation improvements. Each project includes a summary of its goals, features, and links to GitHub for direct access.\\n\\nThis page serves as both a portfolio of past work and a resource for revisiting projects that have made a meaningful impact.\\n'\n const frontmatter = forks.map(({ repository, contributions }) => {\n const { name, owner, html_url, description, stargazers_count } = repository\n return { name, owner: owner.login, html_url, description, stargazers_count, contributions }\n })\n log(` Generate forks page.`, 'info')\n writeFileSync(FORKS_FILE, separator + header + YAML.stringify(frontmatter) + separator + text)\n}\n\ntype Source = Required<Awaited<ReturnType<typeof getContributors>>['source']>\n\ntype AdaptedLicense = Omit<NonNullable<Source>['license'], 'spdx_id'> & { spdx_id?: string }\n\ntype AdaptedRepository = Omit<NonNullable<Source>, 'license'> & { license: AdaptedLicense }\n\n/**\n * Processes forked repositories to generate contribution information\n *\n * @param repositories - Array of enhanced repositories\n * @param username - GitHub username\n * @param token - Optional GitHub API token\n */\nexport async function processForks(repositories: EnhancedRepository[], username: GlobalOpts['usernames'][number], token?: GlobalOpts['token']) {\n const forks = await Promise.all(\n repositories.map(async (repository) => {\n const { source, contributors } = await getContributors({ repository, token })\n return {\n contributions: contributors?.find(contributor => contributor.login === username)?.contributions ?? 0,\n repository: source as AdaptedRepository,\n }\n }),\n ).then(f => f.filter(({ repository, contributions }) => !!repository && contributions))\n\n addForkPage(forks)\n}\n\n/**\n * Parses a VitePress configuration file\n *\n * @param path - Path to the VitePress config file\n * @returns The parsed configuration object\n */\nexport async function parseVitepressConfig(path: string): Promise<Partial<ReturnType<typeof defineConfig>>> {\n const { config } = await import(resolve(process.cwd(), path)).catch(e => e)\n return config\n}\n\n/**\n * Parses a VitePress index file\n *\n * @param path - Path to the index file\n * @returns The parsed index object\n */\nexport async function parseVitepressIndex(path: string): Promise<Index> {\n const index = (await readFile(resolve(process.cwd(), path))).toString()\n return YAML.parse(index)\n}\n\n/**\n * Generates VitePress configuration and index files\n *\n * @param vitepressConfig - VitePress configuration object\n * @param index - Index page configuration\n * @returns The list of theme files that were generated\n */\nexport function generateVitepressFiles(vitepressConfig: Partial<ReturnType<typeof defineConfig>>, index: Index) {\n const separator = '---\\n'\n createDir(dirname(VITEPRESS_CONFIG))\n\n log(` Generate Vitepress config.`, 'info')\n writeFileSync(VITEPRESS_CONFIG, `import { withMermaid } from 'vitepress-plugin-mermaid'\\n\\nexport const config = withMermaid(${JSON.stringify(vitepressConfig, null, 2)})\\n\\nexport default config\\n`)\n log(` Generate index file.`, 'info')\n writeFileSync(INDEX_FILE, separator + YAML.stringify(index))\n log(` Add Docpress theme files.`, 'info')\n return extractFiles(TEMPLATE_THEME).forEach((path) => {\n const relativePath = path.replace(`${TEMPLATE_THEME}/`, '')\n generateFile(path, resolve(VITEPRESS_THEME, relativePath))\n })\n}\n","import { dirname } from 'node:path'\nimport { createCommand, createOption } from 'commander'\nimport { configSchema } from '../schemas/global.js'\nimport { addOptions, parseOptions } from '../utils/commands.js'\nimport { prepareDoc } from '../lib/prepare.js'\nimport type { PrepareOpts } from '../schemas/prepare.js'\nimport { log } from '../utils/logger.js'\nimport { createDir } from '../utils/functions.js'\nimport { VITEPRESS_CONFIG } from '../utils/const.js'\nimport { globalOpts } from './global.js'\n\n/**\n * Command name for the prepare operation\n */\nconst cmdName = 'prepare'\n\n/**\n * Command line options specific to the prepare command\n */\nexport const prepareOpts = [\n createOption('-c, --extra-public-content <string>', configSchema.shape.extraPublicContent.description),\n createOption('-f, --forks', configSchema.shape.forks.description),\n createOption('-p, --extra-header-pages <string>', configSchema.shape.extraHeaderPages.description),\n createOption('-t, --extra-theme <string>', configSchema.shape.extraTheme.description),\n createOption('-v, --vitepress-config <string>', configSchema.shape.vitepressConfig.description),\n createOption('--website-title <string>', configSchema.shape.websiteTitle.description),\n createOption('--website-tagline <string>', configSchema.shape.websiteTagline.description),\n]\n\n/**\n * The prepare command definition for Commander\n */\nexport const prepareCmd = addOptions(createCommand(cmdName), [...prepareOpts, ...globalOpts])\n .description('Transform doc to the target vitepress format.')\n .action(async (opts) => {\n const parsedOpts = parseOptions(cmdName, opts)\n await main(parsedOpts)\n })\n\n/**\n * Main function to execute the prepare command\n *\n * @param opts - Validated prepare options\n */\nexport async function main(opts: PrepareOpts) {\n const { extraHeaderPages, extraPublicContent, extraTheme, vitepressConfig, forks, token, usernames, websiteTitle, websiteTagline } = opts\n log(`\\n-> Start transform files to prepare Vitepress build.`, 'info')\n\n createDir(dirname(VITEPRESS_CONFIG), { clean: true })\n for (const username of usernames) {\n await prepareDoc({ extraHeaderPages, extraPublicContent, extraTheme, vitepressConfig, forks, token, username, websiteTitle, websiteTagline })\n }\n}\n","import { Command } from 'commander'\nimport pkg from '../package.json' with { type: 'json' }\nimport { fetchCmd, main as fetchFn, fetchOpts } from './commands/fetch.js'\nimport { buildCmd, main as buildFn } from './commands/build.js'\nimport { prepareCmd, main as prepareFn, prepareOpts } from './commands/prepare.js'\nimport { addOptions, parseOptions } from './utils/commands.js'\nimport { globalOpts } from './commands/global.js'\n\n/**\n * Adds explicit defaults to options object for branch and gitProvider\n *\n * @param opts - Options object from Commander\n * @returns Options with defaults explicitly set\n */\nfunction addDefaults(opts: Record<string, unknown>): Record<string, unknown> {\n // Create a new object with explicit defaults\n return {\n ...opts,\n branch: 'main',\n gitProvider: 'github',\n }\n}\n\n/**\n * Creates and configures the Command Line Interface for DocPress\n *\n * @returns A configured Commander program instance\n */\nexport function getProgram() {\n const pm = new Command()\n .name('docpress')\n .description('Build your doc website faster than light ⚡️⚡️⚡️')\n .version(`${pkg.version}`)\n .action(async (opts, _cmd) => {\n const optsWithDefaults = addDefaults(opts)\n const parsedOpts = parseOptions('global', optsWithDefaults)\n await fetchFn(parsedOpts)\n await prepareFn(parsedOpts)\n await buildFn()\n })\n .configureHelp({\n sortSubcommands: true,\n sortOptions: true,\n showGlobalOptions: true,\n })\n .enablePositionalOptions()\n .passThroughOptions()\n .addCommand(fetchCmd)\n .addCommand(prepareCmd)\n .addCommand(buildCmd)\n\n addOptions(pm, [...fetchOpts, ...prepareOpts, ...globalOpts])\n\n return pm\n}\n\n/**\n * Entry point for the DocPress CLI\n * Initializes and runs the command parser\n */\nexport function main() {\n const pm = getProgram()\n pm.parseAsync(process.argv)\n}\n"],"names":["DOCPRESS_DIR","resolve","DOCS_DIR","INDEX_FILE","FORKS_FILE","VITEPRESS_CONFIG","VITEPRESS_THEME","VITEPRESS_USER_THEME","TEMPLATE_THEME","relativePathRegex","readmePathRegex","readmeDocsPathRegex","removeIdxRegex","checkHttpStatus","url","axios","error","prettify","s","opts","u","createDir","directory","clean","existsSync","rimrafSync","mkdirSync","err","isDir","path","statSync","isFile","extractFiles","paths","readdirSync","file","join","getMdFiles","basename","prettifyEnum","arr","acc","cur","idx","getUserInfos","username","readFileSync","getUserRepos","deepMerge","objects","obj","key","accValue","objValue","isObject","val","loadConfigFile","configPath","fullPath","fileContents","splitByComma","replaceRelativePath","updatedContent","_match","p1","p2","writeFileSync","replaceReadmePath","_p2","p3","getLogLevel","colorMap","log","msg","type","color","computedMsg","chalk","computedType","providers","configSchema","z","baseCliSchema","cliSchema","prepareConfigData","configData","validateFinalConfig","mergedConfig","globalOptsSchema","data","config","vitepressConfig","token","rest","preparedConfigData","buildOptsSchema","fetchOptsSchema","prepareOptsSchema","options","handleConfigFile","parsedConfig","parseOptions","cmd","configResult","res","errorMessage","fromError","addOptions","opt","getInfos","branch","octokit","Octokit","user","repos","getContributors","repository","message","repo","contributors","cloneRepo","name","projectDir","includes","git","simpleGit","item","appendFileSync","cpSync","rmSync","checkDoc","repoOwner","repoName","rootReadmeUrl","docsFolderUrl","docsReadmeUrl","rootReadmeStatus","docsFolderStatus","docsReadmeStatus","fetchDoc","reposFilter","generateInfos","getDoc","enhanceRepositories","enhancedRepos","computedBranch","projectPath","filtered","isRepoFiltered","getSparseCheckout","docsStatus","status","hasOnlyExclusions","filter","isExcluded","isIncluded","isFiltered","globalOpts","createOption","cmdName","fetchOpts","fetchCmd","createCommand","parsedOpts","main","usernames","gitProvider","finalRF","rf","suppressVueWarnings","callback","originalWarn","args","buildCmd","_opts","vitepressBuild","generateFile","src","dest","content","dirname","defaultVitepressConfig","getVitepressConfig","sidebar","nav","prepareDoc","extraHeaderPages","extraPublicContent","extraTheme","forks","websiteTitle","websiteTagline","repositories","internals","clone_url","privateRepo","fork","docpress","websiteInfos","index","transformDoc","finalSB","finalIndex","actualConfig","parseVitepressConfig","actualIndex","parseVitepressIndex","a","b","pages","addExtraPages","p","addContent","processForks","generateVitepressFiles","addSources","repoUrl","outputPath","fileName","sourcesContent","generateIndex","features","login","bio","title","tagline","generateFeatures","description","generateSidebarProject","sidebarPages","generateSidebarItems","value","element","filename","renameSync","parse","buildTree","files","tree","first","flattenTree","subtree","prefix","v","moveSourcesLast","sourcesIdx","sources","projectFiles","sourceFile","projectTree","sidebarItems","dir","fn","absolutePath","formattedFile","addForkPage","separator","header","text","frontmatter","contributions","owner","html_url","stargazers_count","YAML","source","contributor","f","e","readFile","relativePath","prepareOpts","prepareCmd","addDefaults","getProgram","pm","Command","pkg","_cmd","optsWithDefaults","fetchFn","prepareFn","buildFn"],"mappings":"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"}
@@ -6,6 +6,7 @@ import.meta.glob('./**/*.css', { eager: true })
6
6
 
7
7
  const userFiles = import.meta.glob('./extras/**/*', { eager: true })
8
8
  const processedFiles = new Set<string>()
9
+ const vuePathPrefixRegex = /^.*[\\/]/
9
10
 
10
11
  export default {
11
12
  enhanceApp({ app }) {
@@ -13,7 +14,7 @@ export default {
13
14
  if (!processedFiles.has(path)) {
14
15
  processedFiles.add(path)
15
16
  if (path.endsWith('.vue')) {
16
- const componentName = path.replace(/^.*[\\/]/, '').replace('.vue', '')
17
+ const componentName = path.replace(vuePathPrefixRegex, '').replace('.vue', '')
17
18
  app.component(componentName, (file as { default: any }).default)
18
19
  }
19
20
  }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@tobi-or-not/docpress",
3
3
  "type": "module",
4
- "version": "0.7.4",
4
+ "version": "0.8.0",
5
5
  "homepage": "https://this-is-tobi.com/docpress/introduction",
6
6
  "repository": {
7
7
  "type": "git",
@@ -21,35 +21,36 @@
21
21
  "node": ">=20"
22
22
  },
23
23
  "dependencies": {
24
- "@octokit/rest": "^22.0.0",
25
- "axios": "^1.11.0",
26
- "chalk": "^5.6.0",
27
- "commander": "^14.0.0",
28
- "octokit": "^5.0.3",
29
- "rimraf": "^6.0.1",
30
- "simple-git": "^3.28.0",
24
+ "@octokit/rest": "^22.0.1",
25
+ "axios": "^1.13.6",
26
+ "chalk": "^5.6.2",
27
+ "commander": "^14.0.3",
28
+ "octokit": "^5.0.5",
29
+ "rimraf": "^6.1.3",
30
+ "simple-git": "^3.33.0",
31
31
  "vitepress": "^1.6.4",
32
- "yaml": "^2.8.1",
33
- "zod": "^4.0.17",
34
- "zod-validation-error": "^4.0.1"
32
+ "vitepress-plugin-mermaid": "^2.0.17",
33
+ "yaml": "^2.8.2",
34
+ "zod": "^4.3.6",
35
+ "zod-validation-error": "^5.0.0"
35
36
  },
36
37
  "devDependencies": {
37
- "@antfu/eslint-config": "^5.2.1",
38
- "@commitlint/cli": "^19.8.1",
39
- "@commitlint/config-conventional": "^19.8.1",
40
- "@octokit/types": "^14.1.0",
41
- "@types/node": "^22.17.2",
42
- "@vitejs/plugin-vue": "^6.0.1",
43
- "@vitest/coverage-v8": "^3.2.4",
44
- "eslint": "^9.33.0",
38
+ "@antfu/eslint-config": "^7.7.0",
39
+ "@commitlint/cli": "^20.4.3",
40
+ "@commitlint/config-conventional": "^20.4.3",
41
+ "@octokit/types": "^16.0.0",
42
+ "@types/node": "^25.4.0",
43
+ "@vitejs/plugin-vue": "^6.0.4",
44
+ "@vitest/coverage-v8": "^4.0.18",
45
+ "eslint": "^10.0.3",
45
46
  "eslint-plugin-import": "^2.32.0",
46
47
  "husky": "^9.1.7",
47
- "lint-staged": "^16.1.5",
48
- "typescript": "^5.9.2",
49
- "vite": "^7.1.3",
50
- "vite-node": "^3.2.4",
51
- "vitest": "^3.2.4",
52
- "vue": "^3.5.18"
48
+ "lint-staged": "^16.3.3",
49
+ "typescript": "^5.9.3",
50
+ "vite": "^7.3.1",
51
+ "vite-node": "^5.3.0",
52
+ "vitest": "^4.0.18",
53
+ "vue": "^3.5.30"
53
54
  },
54
55
  "publishConfig": {
55
56
  "registry": "https://registry.npmjs.org/",