mirror of
https://github.com/sourcebot-dev/sourcebot.git
synced 2025-12-12 04:15:30 +00:00
feat(metadata): Enhance metadata generation for repository browsing
feat(utils): Add parseRepoPath function to extract repository name and revision from URL path
This commit is contained in:
parent
c3fae1aaab
commit
bb66666ced
3 changed files with 91 additions and 3 deletions
|
|
@ -3,6 +3,36 @@ import { getBrowseParamsFromPathParam } from "../hooks/utils";
|
|||
import { CodePreviewPanel } from "./components/codePreviewPanel";
|
||||
import { Loader2 } from "lucide-react";
|
||||
import { TreePreviewPanel } from "./components/treePreviewPanel";
|
||||
import { Metadata } from "next";
|
||||
import { parseRepoPath } from "@/lib/utils";
|
||||
|
||||
type Props = {
|
||||
params: {
|
||||
domain: string;
|
||||
path: string[];
|
||||
};
|
||||
};
|
||||
|
||||
export async function generateMetadata({ params }: Props): Promise<Metadata> {
|
||||
let title = 'Browse'; // Current Default
|
||||
|
||||
try {
|
||||
const parsedInfo = parseRepoPath(params.path);
|
||||
|
||||
if (parsedInfo) {
|
||||
const { fullRepoName, revision } = parsedInfo;
|
||||
title = `${fullRepoName}${revision ? ` @ ${revision}` : ''}`;
|
||||
}
|
||||
} catch (error) {
|
||||
// Log the error for debugging, but don't crash the page render.
|
||||
console.error("Failed to generate metadata title from path:", params.path, error);
|
||||
}
|
||||
|
||||
return {
|
||||
title, // e.g., "sourcebot-dev/sourcebot @ HEAD"
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
interface BrowsePageProps {
|
||||
params: Promise<{
|
||||
|
|
|
|||
|
|
@ -11,9 +11,15 @@ import { PlanProvider } from "@/features/entitlements/planProvider";
|
|||
import { getEntitlements } from "@sourcebot/shared";
|
||||
|
||||
export const metadata: Metadata = {
|
||||
title: "Sourcebot",
|
||||
description: "Sourcebot is a self-hosted code understanding tool. Ask questions about your codebase and get rich Markdown answers with inline citations.",
|
||||
manifest: "/manifest.json",
|
||||
// Using the title.template will allow child pages to set the title
|
||||
// while keeping a consistent suffix.
|
||||
title: {
|
||||
default: "Sourcebot",
|
||||
template: "%s | Sourcebot",
|
||||
},
|
||||
description:
|
||||
"Sourcebot is a self-hosted code understanding tool. Ask questions about your codebase and get rich Markdown answers with inline citations.",
|
||||
manifest: "/manifest.json",
|
||||
};
|
||||
|
||||
export default function RootLayout({
|
||||
|
|
|
|||
|
|
@ -486,4 +486,56 @@ export const isHttpError = (error: unknown, status: number): boolean => {
|
|||
&& typeof error === 'object'
|
||||
&& 'status' in error
|
||||
&& error.status === status;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Parses a URL path array to extract the full repository name and revision.
|
||||
* This function assumes a URL structure like:
|
||||
* `.../[hostname]/[owner]/[repo@revision]/-/tree/...`
|
||||
* Or for nested groups (like GitLab):
|
||||
* `.../[hostname]/[group]/[subgroup]/[repo@revision]/-/tree/...`
|
||||
*
|
||||
* @param path The array of path segments from Next.js params.
|
||||
* @returns An object with fullRepoName and revision, or null if parsing fails.
|
||||
*/
|
||||
export const parseRepoPath = (path: string[]): { fullRepoName: string; revision: string } | null => {
|
||||
if (path.length < 2) {
|
||||
return null; // Not enough path segments to parse.
|
||||
}
|
||||
|
||||
// Find the index of the `-` delimiter which separates the repo info from the file tree info.
|
||||
const delimiterIndex = path.indexOf('-');
|
||||
|
||||
// If no delimiter is found, we can't reliably parse the path.
|
||||
if (delimiterIndex === -1) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// The repository parts are between the hostname (index 0) and the delimiter.
|
||||
// e.g., ["github.com", "sourcebot-dev", "sourcebot"] -> slice will be ["sourcebot-dev", "sourcebot"]
|
||||
const repoParts = path.slice(1, delimiterIndex);
|
||||
|
||||
if (repoParts.length === 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// The last part of the repo segment potentially contains the revision.
|
||||
const lastPart = repoParts[repoParts.length - 1];
|
||||
|
||||
// URL segments are encoded. Decode it to handle characters like '@' (%40).
|
||||
const decodedLastPart = decodeURIComponent(lastPart);
|
||||
|
||||
const [repoNamePart, revision = ''] = decodedLastPart.split('@');
|
||||
|
||||
// The preceding parts form the owner/group path.
|
||||
// e.g., ["sourcebot"] or ["my-group", "my-subgroup"]
|
||||
const ownerParts = repoParts.slice(0, repoParts.length - 1);
|
||||
|
||||
// Reconstruct the full repository name.
|
||||
// e.g., "sourcebot-dev" + "/" + "sourcebot"
|
||||
// e.g., "my-group/my-subgroup" + "/" + "my-repo"
|
||||
const fullRepoName = [...ownerParts, repoNamePart].join('/');
|
||||
|
||||
return { fullRepoName, revision };
|
||||
}
|
||||
Loading…
Reference in a new issue