UNPKG

@nolebase/vitepress-plugin-git-changelog

Version:

A VitePress plugin that adds a changelog fetched from git to your documentation.

1 lines 44.2 kB
{"version":3,"file":"index.cjs","sources":["../../src/vite/helpers.ts","../../src/vite/git.ts","../../src/vite/markdownSection.ts"],"sourcesContent":["import type { Commit, CommitAuthor, Contributor, MergedRawCommit, RawCommit } from '../types'\nimport { basename, dirname, extname, posix, relative, sep, win32 } from 'node:path'\nimport { omit } from 'es-toolkit'\nimport { execa } from 'execa'\nimport { subtle } from 'uncrypto'\nimport { normalizePath } from 'vite'\n\nexport interface Helpers {\n /**\n * A helper function to help to determine whether the passed string parameter equals the\n * current transforming module ID with normalization of paths capabilities and\n * cross platform / OS compatibilities.\n *\n * @param equalsWith - String to equal with\n * @returns boolean\n */\n idEquals: (equalsWith: string) => boolean\n /**\n * A helper function to help to determine whether the passed string parameter startsWith the\n * current transforming module ID with normalization of paths capabilities and\n * cross platform / OS compatibilities.\n *\n * @param startsWith - String to start with\n * @returns boolean\n */\n idStartsWith: (startsWith: string) => boolean\n /**\n * A helper function to help to determine whether the passed string parameter endsWith the\n * current transforming module ID with normalization of paths capabilities and\n * cross platform / OS compatibilities.\n *\n * @param endsWith - String to end with\n * @returns boolean\n */\n idEndsWith: (endsWith: string) => boolean\n /**\n * A helper function to help to determine whether the passed first path parameter\n * equals the second passed string with normalization of paths capabilities and\n * cross platform / OS compatibilities.\n *\n * @param path - Path to be compared with\n * @param equalsWith - String to equal with\n * @returns boolean\n */\n pathEquals: (path: string, equalsWith: string) => boolean\n /**\n * A helper function to help to determine whether the passed first path parameter\n * startsWith the second passed string with normalization of paths capabilities and\n * cross platform / OS compatibilities.\n *\n * @param path - Path to be compared with\n * @param startsWith - String to start with\n * @returns boolean\n */\n pathStartsWith: (path: string, startsWith: string) => boolean\n /**\n * A helper function to help to determine whether the passed first path parameter\n * endsWith the second passed string with normalization of paths capabilities and\n * cross platform / OS compatibilities.\n *\n * @param path - Path to be compared with\n * @param endsWith - String to end with\n * @returns boolean\n */\n pathEndsWith: (path: string, endsWith: string) => boolean\n}\n\nexport function pathEquals(path: string, equals: string): boolean {\n return normalizePath(path) === (normalizePath(equals))\n}\n\nexport function pathStartsWith(path: string, startsWith: string): boolean {\n return normalizePath(path).startsWith(normalizePath(startsWith))\n}\n\nexport function pathEndsWith(path: string, startsWith: string): boolean {\n return normalizePath(path).endsWith(normalizePath(startsWith))\n}\n\nexport function createHelpers(root: string, id: string): Helpers {\n const relativeId = relative(root, id)\n\n return {\n pathStartsWith,\n pathEquals,\n pathEndsWith,\n idEndsWith(endsWith: string) {\n return pathEndsWith(relativeId, endsWith)\n },\n idEquals(equals: string) {\n return pathEquals(relativeId, equals)\n },\n idStartsWith(startsWith: string) {\n return pathStartsWith(relativeId, startsWith)\n },\n }\n}\n\n/**\n * Hashes a string using SHA-256\n *\n * Official example by MDN: https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto/digest\n * @param {string} message - The message to be hashed\n * @returns {Promise<string>} - The SHA-256 hash of the message\n */\nexport async function digestStringAsSHA256(message: string) {\n const msgUint8 = new TextEncoder().encode(message) // encode as (utf-8) Uint8Array\n const hashBuffer = await subtle.digest('SHA-256', msgUint8) // hash the message\n const hashArray = Array.from(new Uint8Array(hashBuffer)) // convert buffer to byte array\n const hashHex = hashArray\n .map(b => b.toString(16).padStart(2, '0'))\n .join('') // convert bytes to hex string\n return hashHex\n}\n\nexport function normalizeGitLogPath(path: string[][]) {\n // normalize paths\n for (const [index, files] of path.entries()) {\n if (files[1])\n path[index][1] = normalizePath(files[1])\n\n if (files[2])\n path[index][2] = normalizePath(files[2])\n }\n\n return path\n}\n\nexport type CommitToStringHandler = (commit: Commit) => string | Promise<string> | null | undefined\nexport type CommitToStringsHandler = (commit: Commit) => string[] | Promise<string[]> | null | undefined\nexport type CommitAndPathToStringHandler = (commit: Commit, path: string) => string | Promise<string> | null | undefined\nexport interface RewritePathsBy { handler?: CommitAndPathToStringHandler }\n\nexport const defaultCommitURLHandler = (commit: Commit) => `${commit.repo_url}/commit/${commit.hash}`\nexport const defaultReleaseTagURLHandler = (commit: Commit) => `${commit.repo_url}/releases/tag/${commit.tag}`\nexport const defaultReleaseTagsURLHandler = (commit: Commit) => commit.tags?.map(tag => `${commit.repo_url}/releases/tag/${tag}`)\n\nexport async function returnOrResolvePromise<T>(val: T | Promise<T>) {\n if (!(val instanceof Promise))\n return val\n\n return await val\n}\n\nexport function rewritePaths(path: string, rewritePaths: Record<string, string>) {\n // rewrite paths\n for (const [key, value] of Object.entries(rewritePaths))\n path = path.replace(key, value)\n\n return path\n}\n\nexport async function rewritePathsByPatterns(commit: Commit, path: string, patterns?: RewritePathsBy): Promise<string> {\n if (typeof patterns === 'undefined' || patterns === null)\n return path\n\n if ('handler' in patterns && typeof patterns.handler === 'function') {\n const resolvedPath = await returnOrResolvePromise(patterns.handler(commit, path))\n if (!resolvedPath)\n return path\n\n return resolvedPath\n }\n\n return path\n}\n\n/**\n * A rewritePathsBy.handler handler that rewrites paths by rewriting the extension.\n *\n * @example\n *\n * ```typescript\n * import { GitChangelog, rewritePathsByRewritingExtension } from '@nolebase/vitepress-plugin-git-changelog/vite'\n *\n * GitChangelog({\n * rewritePathsBy: {\n * // to rewrite `example.md` to `example.html`\n * handler: rewritePathsByRewritingExtension('.md', '.html')\n * }\n * })\n * ```\n *\n * @param from - The extension to rewrite from.\n * @param to - The extension to rewrite to.\n * @returns A handler that rewrites paths by rewriting the extension.\n */\nexport function rewritePathsByRewritingExtension(from: string, to: string) {\n return (_: Commit, path: string) => {\n const ext = extname(path)\n if (ext !== from)\n return path\n\n return path.replace(new RegExp(`${from}$`), to)\n }\n}\n\nexport function parseGitLogRefsAsTags(refs?: string): string[] {\n if (!refs)\n return []\n\n const refsArray = refs.split(', ').map(ref => ref.trim())\n const tags = refsArray.filter(ref => ref.startsWith('tag: '))\n if (!tags)\n return []\n\n return tags.map(tag => tag.replace('tag: ', '').trim())\n}\n\n/**\n * Generate RegExp for filtering out paths of commits.\n *\n * It follows the rules that:\n * - includes is not set, it is /^.+.md$/\n * - includeDirs is set, it is /^(${includeDirs.join('|')})\\/.+.md$/\n * - includeExtensions is set, it is /^.+(${includeExtensions.join('|')})$/\n * - in another word, /^(includeDir1|includeDir2)\\/.+(includeExtension1|includeExtensions2)$/\n *\n * @deprecated\n */\nexport function generateCommitPathsRegExp(includeDirs: string[], includeExtensions: `.${string}`[]): RegExp {\n return new RegExp(`^${includeDirs.length > 0 ? `(${includeDirs.join('|')})${sep === win32.sep ? win32.sep : `\\\\${posix.sep}`}` : ''}.+${includeExtensions.length > 0 ? `(${includeExtensions.join('|')})` : '.md'}$`)\n}\n\nexport function getRelativePath(file: string, srcDir: string, cwd: string) {\n cwd = normalizePath(cwd)\n return file.replace(srcDir, '').replace(cwd, '').replace(/^\\//, '')\n}\n\nexport async function getRawCommitLogs(file: string, maxGitLogCount?: number) {\n const fileDir = dirname(file)\n const fileName = basename(file)\n /**\n * The format of git log.\n *\n * ${commit_hash} ${author_name} ${author_email} ${author_date} ${subject} ${ref} ${body}\n *\n * @see {@link https://git-scm.com/docs/pretty-formats | documentation} for details.\n *\n * Note: Make sure that `body` is in last position, as `\\n` or `|` in body may breaks subsequent processing.\n *\n * @example stdout\n *\n * ```bash\n * $ git log --format=\"%H|%an|%ae|%ad|%s|%d|%b[GIT_LOG_COMMIT_END]\" --follow docs/pages/en/integrations/index.md\n * 62ef7ed8f54ea1faeacf6f6c574df491814ec1b1|Neko Ayaka|neko@ayaka.moe|Wed Apr 24 14:24:44 2024 +0800|docs: fix english integrations list||Signed-off-by: Neko Ayaka <neko@ayaka.moe>\n * [GIT_LOG_COMMIT_END]\n * 34357cc0956db77d1fc597327ba880d7eebf67ce|Rizumu Ayaka|rizumu@ayaka.moe|Mon Apr 22 22:51:24 2024 +0800|release: pre-release v2.0.0-rc10| (tag: v2.0.0-rc10)|Signed-off-by: Rizumu Ayaka <rizumu@ayaka.moe>\n * [GIT_LOG_COMMIT_END]\n * (END)\n * ```\n */\n const format = '%H|%an|%ae|%ad|%s|%d|%b'\n const { stdout } = await execa('git', ['log', `--max-count=${maxGitLogCount ?? -1}`, `--format=${format}[GIT_LOG_COMMIT_END]`, '--follow', '--', fileName], { cwd: fileDir })\n // remove \"[GIT_LOG_COMMIT_END]\" in last line: split stdout into lines and avoid empty strings\n return stdout.replace(/\\[GIT_LOG_COMMIT_END\\]$/, '').split('[GIT_LOG_COMMIT_END]\\n')\n}\n\nexport function parseRawCommitLogs(\n path: string,\n rawLogs: string[],\n): RawCommit[] {\n return rawLogs\n .filter(log => !!log)\n .map((raw) => {\n const [hash, author_name, author_email, date, message, refs, body] = raw.split('|').map(v => v.trim())\n return {\n path,\n hash,\n date,\n message,\n body,\n refs,\n author_name,\n author_email,\n }\n })\n}\n\nexport function mergeRawCommits(rawCommits: RawCommit[]): MergedRawCommit[] {\n const commitMap = new Map<string, MergedRawCommit>()\n\n rawCommits.forEach((commit) => {\n const _commit = commitMap.get(commit.hash)\n if (_commit)\n _commit.paths.push(commit.path)\n else\n commitMap.set(commit.hash, { paths: [commit.path], ...omit(commit, ['path']) })\n })\n\n return Array.from(commitMap.values())\n}\n\nexport async function parseCommits(\n rawCommits: MergedRawCommit[],\n getRepoURL: CommitToStringHandler,\n getCommitURL: CommitToStringHandler,\n getReleaseTagURL: CommitToStringHandler,\n getReleaseTagsURL: CommitToStringsHandler,\n mapContributors?: Contributor[],\n optsRewritePathsBy?: RewritePathsBy,\n): Promise<{ commits: Commit[], authors: CommitAuthor[] }> {\n const allAuthors = new Map<string, CommitAuthor>()\n const resolvedCommits = await Promise.all(rawCommits.map(async (rawCommit) => {\n const { paths, hash, date, refs, message } = rawCommit\n\n const resolvedCommit: Commit = {\n paths,\n hash,\n date_timestamp: new Date(date).getTime(),\n message,\n authors: [],\n }\n\n // rewrite path\n // Ensure that paths are processed first, as users may generate other properties based on this one.\n if (typeof optsRewritePathsBy !== 'undefined')\n await Promise.all(rawCommit.paths.map(async p => await rewritePathsByPatterns(resolvedCommit, p, optsRewritePathsBy)))\n\n // repo url\n resolvedCommit.repo_url = (await returnOrResolvePromise(getRepoURL(resolvedCommit))) ?? 'https://github.com/example/example'\n // hash url\n resolvedCommit.hash_url = (await returnOrResolvePromise(getCommitURL(resolvedCommit))) ?? defaultCommitURLHandler(resolvedCommit)\n\n // remove `()` in refs, e.g. ` (tag: v2.0.0-rc7)`\n const tags = parseGitLogRefsAsTags(refs?.replace(/[()]/g, ''))\n\n // release logs\n if (tags && tags.length > 0) {\n resolvedCommit.tags = tags\n resolvedCommit.tag = resolvedCommit.tags?.[0] || undefined\n resolvedCommit.release_tag_url = (await returnOrResolvePromise(getReleaseTagURL(resolvedCommit))) ?? defaultReleaseTagURLHandler(resolvedCommit)\n resolvedCommit.release_tags_url = (await returnOrResolvePromise(getReleaseTagsURL(resolvedCommit))) ?? defaultReleaseTagsURLHandler(resolvedCommit)\n }\n\n // authors\n const authors = await parseCommitAuthors(rawCommit, mapContributors)\n authors.forEach(a => allAuthors.set(a.name, omit(a, ['email'])))\n resolvedCommit.authors = authors.map(a => a.name)\n\n // generate author avatar based on md5 hash of email (gravatar style)\n // resolvedCommit.author_avatar = await digestStringAsSHA256(rawCommit.author_email)\n\n return resolvedCommit\n }))\n\n return { commits: resolvedCommits, authors: [...allAuthors.values()] }\n}\n\nexport async function parseCommitAuthors(commit: MergedRawCommit, mapContributors?: Contributor[]): Promise<CommitAuthor[]> {\n const { author_name, author_email, body } = commit\n\n const commitAuthor: CommitAuthor = {\n name: author_name,\n email: author_email,\n }\n const coAuthors = getCoAuthors(body)\n\n return await Promise.all([commitAuthor, ...coAuthors]\n // exclude bot users\n .filter(v => !(v.name.match(/\\[bot\\]/i) || v.email?.match(/\\[bot\\]/i)))\n // map authors\n .map(async (author) => {\n const targetCreatorByName = findMapAuthorByName(mapContributors, author.name)\n if (targetCreatorByName) {\n author.name = targetCreatorByName.name ?? author.name\n author.i18n = findMapAuthorI18n(targetCreatorByName)\n author.url = findMapAuthorLink(targetCreatorByName)\n author.avatarUrl = await newAvatarForAuthor(targetCreatorByName, author.email!)\n return author\n }\n const targetCreatorByEmail = author.email && findMapAuthorByEmail(mapContributors, author.email)\n if (targetCreatorByEmail) {\n author.name = targetCreatorByEmail.name ?? author.name\n author.i18n = findMapAuthorI18n(targetCreatorByEmail)\n author.url = findMapAuthorLink(targetCreatorByEmail)\n author.avatarUrl = await newAvatarForAuthor(targetCreatorByEmail, author.email!)\n return author\n }\n const targetCreatorByGitHub = findMapAuthorByGitHub(mapContributors, author.name, author.email!)\n if (targetCreatorByGitHub) {\n author.name = targetCreatorByGitHub.name ?? author.name\n author.i18n = findMapAuthorI18n(targetCreatorByGitHub)\n author.url = findMapAuthorLink(targetCreatorByGitHub)\n author.avatarUrl = await newAvatarForAuthor(targetCreatorByGitHub, author.email!)\n return author\n }\n author.avatarUrl = await newAvatarForAuthor(undefined, author.email!)\n return author\n }))\n}\n\n/**\n * This regular expression is used to match and parse commit messages that contain multiple author information.\n *\n * @see {@link https://regex101.com/r/q5YB8m/1 | Regexp demo}\n * @see {@link https://en.wikipedia.org/wiki/Email_address#Local-part | Email address}\n * @see {@link https://docs.github.com/en/pull-requests/committing-changes-to-your-project/creating-and-editing-commits/creating-a-commit-with-multiple-authors | Creating a commit with multiple authors in GitHub}\n */\nconst multipleAuthorsRegex = /^ *Co-authored-by: ?([^<]*)<([^>]*)> */gim\n\n// This function handles multiple authors in a commit.\n// It uses the regular expression to extract the name and email of each author from the commit message.\n// About the docs: https://docs.github.com/en/pull-requests/committing-changes-to-your-project/creating-and-editing-commits/creating-a-commit-with-multiple-authors\nexport function getCoAuthors(body?: string): CommitAuthor[] {\n if (!body)\n return []\n\n return [...body.matchAll(multipleAuthorsRegex)].map((result) => {\n const [, name, email] = result\n return {\n name: name.trim(),\n email: email.trim(),\n }\n }).filter(v => !!v)\n}\n\nexport function findMapAuthorByName(mapContributors: Contributor[] | undefined, author_name: string) {\n return mapContributors?.find((item) => {\n const res = (item.mapByNameAliases && Array.isArray(item.mapByNameAliases) && item.mapByNameAliases.includes(author_name)) || item.name === author_name || item.username === author_name\n if (res)\n return true\n\n // This is a fallback for the old version of the configuration.\n return item.nameAliases && Array.isArray(item.nameAliases) && item.nameAliases.includes(author_name)\n })\n}\n\nexport function findMapAuthorByEmail(mapContributors: Contributor[] | undefined, author_email: string) {\n return mapContributors?.find((item) => {\n const res = item.mapByEmailAliases && Array.isArray(item.mapByEmailAliases) && item.mapByEmailAliases.includes(author_email)\n if (res)\n return true\n\n // This is a fallback for the old version of the configuration.\n return item.emailAliases && Array.isArray(item.emailAliases) && item.emailAliases.includes(author_email)\n })\n}\n\nexport function findMapAuthorByGitHub(mapContributors: Contributor[] | undefined, author_name: string, author_email: string) {\n const github = getGitHubUserNameFromNoreplyAddress(author_email)\n if (github && github.userName) {\n const mappedByName = findMapAuthorByName(mapContributors, github.userName)\n if (mappedByName && mappedByName.username) {\n mappedByName.username ||= github.userName\n return mappedByName\n }\n return {\n name: author_name,\n username: github.userName,\n }\n }\n}\n\nexport function findMapAuthorLink(creator: Contributor): string | undefined {\n if (!creator.links && !!creator.username)\n return `https://github.com/${creator.username}`\n\n if (typeof creator.links === 'string' && !!creator.links)\n return creator.links\n if (!Array.isArray(creator.links))\n return\n\n const priority = ['github', 'twitter']\n for (const p of priority) {\n const matchedEntry = creator.links?.find(l => l.type === p)\n if (matchedEntry)\n return matchedEntry.link\n }\n\n return creator.links?.[0]?.link\n}\n\nexport function findMapAuthorI18n(mappedAuthor: Contributor): Record<string, string> | undefined {\n if (mappedAuthor && mappedAuthor.i18n) {\n return mappedAuthor.i18n\n }\n return undefined\n}\n\n// based on https://github.com/nolebase/integrations/issues/277#issuecomment-2254111802\nexport function getGitHubUserNameFromNoreplyAddress(email: string) {\n const match = email.match(/^(?:(?<userId>\\d+)\\+)?(?<userName>[a-zA-Z\\d-]{1,39})@users.noreply.github.com$/)\n if (!match || !match.groups)\n return undefined\n\n const { userName, userId } = match.groups\n return { userId, userName }\n}\n\nexport async function newAvatarForAuthor(mappedAuthor: Contributor | undefined, email: string): Promise<string> {\n if (mappedAuthor) {\n if (mappedAuthor.avatar)\n return mappedAuthor.avatar\n if (mappedAuthor.username)\n return `https://github.com/${mappedAuthor.username}.png`\n }\n\n return `https://gravatar.com/avatar/${await digestStringAsSHA256(email)}?d=retro`\n}\n","import type { Plugin, ResolvedConfig } from 'vite'\nimport type { SiteConfig } from 'vitepress'\nimport type { Author, Changelog } from '../types'\n\nimport type { CommitToStringHandler, CommitToStringsHandler, RewritePathsBy } from './helpers'\nimport type { GitChangelogOptions } from './types'\nimport { join } from 'node:path'\nimport { cwd as _cwd } from 'node:process'\nimport { cyan, gray } from 'colorette'\nimport { execa } from 'execa'\nimport { globby } from 'globby'\n\nimport { normalizePath } from 'vite'\nimport {\n\n defaultCommitURLHandler,\n defaultReleaseTagsURLHandler,\n defaultReleaseTagURLHandler,\n getRawCommitLogs,\n getRelativePath,\n mergeRawCommits,\n parseCommits,\n parseRawCommitLogs,\n\n rewritePathsByRewritingExtension,\n} from './helpers'\n\nexport type {\n Author,\n CommitToStringHandler,\n CommitToStringsHandler,\n RewritePathsBy,\n}\n\nexport {\n rewritePathsByRewritingExtension,\n}\n\ninterface VitePressConfig extends ResolvedConfig {\n vitepress: SiteConfig\n}\n\nconst VirtualModuleID = 'virtual:nolebase-git-changelog'\nconst ResolvedVirtualModuleId = `\\0${VirtualModuleID}`\n\nconst logModulePrefix = `${cyan(`@nolebase/vitepress-plugin-git-changelog`)}${gray(':')}`\nconst logger = console\n\nexport function GitChangelog(options: GitChangelogOptions = {}): Plugin {\n if (!options)\n options = {}\n\n const {\n cwd = _cwd(),\n maxGitLogCount,\n include = ['**/*.md', '!node_modules'],\n mapAuthors,\n repoURL = 'https://github.com/example/example',\n getReleaseTagURL = defaultReleaseTagURLHandler,\n getReleaseTagsURL = defaultReleaseTagsURLHandler,\n getCommitURL = defaultCommitURLHandler,\n rewritePathsBy,\n } = options\n\n const getRepoURL = typeof repoURL === 'function' ? repoURL : () => repoURL\n\n const changelog: Changelog = { commits: [], authors: [] }\n const hotModuleReloadCachedCommits = new Map<string, Changelog>()\n let srcDir = ''\n let config: VitePressConfig\n\n const commitFromPath = async (paths: string[]) => {\n const rawCommits = (await Promise.all(paths.map(async (path) => {\n const rawLogs = await getRawCommitLogs(path, maxGitLogCount)\n const relativePath = getRelativePath(path, srcDir, cwd)\n const rawCommits = parseRawCommitLogs(relativePath, rawLogs)\n return rawCommits\n }))).flat()\n const mergedRawCommits = mergeRawCommits(rawCommits)\n const resolvedCommits = parseCommits(\n mergedRawCommits,\n getRepoURL,\n getCommitURL,\n getReleaseTagURL,\n getReleaseTagsURL,\n mapAuthors,\n rewritePathsBy,\n )\n return resolvedCommits\n }\n\n return {\n name: '@nolebase/vitepress-plugin-git-changelog',\n config: () => ({\n optimizeDeps: {\n exclude: [\n '@nolebase/vitepress-plugin-git-changelog/client',\n ],\n },\n ssr: {\n noExternal: [\n '@nolebase/vitepress-plugin-git-changelog',\n // @nolebase/ui required here as noExternal to avoid the following error:\n // TypeError [ERR_UNKNOWN_FILE_EXTENSION]: Unknown file extension \".vue\" for ...\n // Read more here: https://github.com/vuejs/vitepress/issues/2915\n // And here: https://stackblitz.com/edit/vite-gjz9zf?file=docs%2F.vitepress%2Fconfig.ts\n '@nolebase/ui',\n ],\n },\n }),\n configResolved(_config) {\n config = _config as VitePressConfig\n srcDir = config.vitepress.srcDir\n },\n async buildStart() {\n if (config.command !== 'build')\n return\n\n const startsAt = Date.now()\n logger.info(`${logModulePrefix} Prepare to gather git logs...`)\n\n if (changelog.commits.length > 0)\n return\n\n // configure so that the git log messages can contain correct CJK characters\n await execa('git', ['config', '--local', 'core.quotepath', 'false'])\n\n const paths = await globby(include, {\n gitignore: true,\n cwd,\n absolute: true,\n })\n\n Object.assign(changelog, await commitFromPath(paths))\n\n const elapsed = Date.now() - startsAt\n logger.info(`${logModulePrefix} Done. ${gray(`(${elapsed}ms)`)}`)\n },\n resolveId(source) {\n if (source.startsWith(VirtualModuleID))\n return `\\0${source}`\n },\n load(id) {\n if (!id.startsWith(ResolvedVirtualModuleId))\n return null\n\n return `export default ${JSON.stringify(changelog, null, config.isProduction ? 0 : 2)}`\n },\n configureServer(server) {\n compatibleConfigureServer(server, (_, env) => {\n env.hot.on('nolebase-git-changelog:client-mounted', async (data) => {\n if (!data || typeof data !== 'object')\n return\n if (!('page' in data && 'filePath' in data.page))\n return\n\n let result = hotModuleReloadCachedCommits.get(data.page.filePath)\n if (!result) {\n const path = normalizePath(join(srcDir, data.page.filePath))\n result = await commitFromPath([path])\n hotModuleReloadCachedCommits.set(data.page.filePath, result)\n }\n\n Object.assign(changelog, result)\n\n if (!result!.commits.length)\n return\n\n const virtualModule = env.moduleGraph.getModuleById(ResolvedVirtualModuleId)\n if (!virtualModule)\n return\n\n env.moduleGraph.invalidateModule(virtualModule)\n env.hot.send({\n type: 'custom',\n event: 'nolebase-git-changelog:updated',\n data: changelog,\n })\n })\n })\n },\n }\n}\n\ninterface Environment {\n hot: {\n on: (event: string, handler: (data: any) => void) => void\n send: (data: any) => void\n }\n moduleGraph: {\n getModuleById: (id: string) => any\n invalidateModule: (module: any) => void\n }\n}\n\nfunction compatibleConfigureServer<E extends Environment>(server: E, registerHandler: (name: string, env: E) => void | Promise<void>) {\n// Temporary workaround for Vite 5, both register for environments and server\n // When VitePress is upgraded to Vite 6, this can be removed\n if ('environments' in server && typeof server.environments === 'object' && server.environments != null) {\n Object.entries(server.environments).forEach(([name, env]) => registerHandler(name, env))\n }\n else {\n registerHandler('server', server)\n }\n}\n","import type { Plugin } from 'vite'\nimport type { Context, GitChangelogMarkdownSectionOptions } from './types'\nimport { relative } from 'node:path'\n\nimport GrayMatter from 'gray-matter'\nimport { createHelpers } from './helpers'\n\nexport type {\n Context,\n GitChangelogMarkdownSectionOptions,\n}\n\nexport function GitChangelogMarkdownSection(options?: GitChangelogMarkdownSectionOptions): Plugin {\n const {\n excludes = ['index.md'],\n exclude = () => false,\n } = options ?? {}\n\n let root = ''\n\n return {\n name: '@nolebase/vitepress-plugin-git-changelog-markdown-section',\n // May set to 'pre' since end user may use vitepress wrapped vite plugin to\n // specify the plugins, which may cause this plugin to be executed after\n // vitepress or the other markdown processing plugins.\n enforce: 'pre',\n configResolved(config) {\n root = config.root ?? ''\n },\n transform(code, id) {\n if (!id.endsWith('.md'))\n return null\n\n const helpers = createHelpers(root, id)\n\n if (excludes.includes(relative(root, id)))\n return null\n if (exclude(id, { helpers }))\n return null\n\n const parsedMarkdownContent = GrayMatter(code)\n\n if ('nolebase' in parsedMarkdownContent.data && 'gitChangelog' in parsedMarkdownContent.data.nolebase && !parsedMarkdownContent.data.nolebase.gitChangelog)\n return null\n if ('gitChangelog' in parsedMarkdownContent.data && !parsedMarkdownContent.data.gitChangelog)\n return null\n\n if (!options?.sections?.disableContributors)\n code = TemplateContributors(code)\n if (!options?.sections?.disableChangelog)\n code = TemplateChangelog(code)\n\n return code\n },\n }\n}\n\nfunction TemplateContributors(code: string) {\n return `${code}\n\n<NolebaseGitContributors />\n`\n}\n\nfunction TemplateChangelog(code: string) {\n return `${code}\n\n<NolebaseGitChangelog />\n`\n}\n"],"names":["normalizePath","relative","subtle","extname","dirname","basename","execa","omit","cyan","gray","_cwd","rawCommits","globby","join","GrayMatter"],"mappings":"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"}