51 lines
1.5 KiB
TypeScript
51 lines
1.5 KiB
TypeScript
export const normalizeRepoSourceUrl = (sourceUrl: string): string => {
|
|
const trimmed = sourceUrl.trim().replace(/\/+$/, "");
|
|
return trimmed.endsWith(".git") ? trimmed.slice(0, -4) : trimmed;
|
|
};
|
|
|
|
export const repoBaseFromSkillSourceUrl = (
|
|
skillSourceUrl: string,
|
|
): string | null => {
|
|
try {
|
|
const parsed = new URL(skillSourceUrl);
|
|
const marker = "/tree/";
|
|
const markerIndex = parsed.pathname.indexOf(marker);
|
|
if (markerIndex <= 0) return null;
|
|
|
|
// Reject unexpected structures (e.g. multiple /tree/ markers).
|
|
if (parsed.pathname.indexOf(marker, markerIndex + marker.length) !== -1)
|
|
return null;
|
|
|
|
const repoPath = parsed.pathname.slice(0, markerIndex);
|
|
if (!repoPath || repoPath === "/") return null;
|
|
if (repoPath.endsWith("/tree")) return null;
|
|
|
|
return normalizeRepoSourceUrl(`${parsed.origin}${repoPath}`);
|
|
} catch {
|
|
return null;
|
|
}
|
|
};
|
|
|
|
export const packUrlFromSkillSourceUrl = (skillSourceUrl: string): string => {
|
|
const repoBase = repoBaseFromSkillSourceUrl(skillSourceUrl);
|
|
return repoBase ?? skillSourceUrl;
|
|
};
|
|
|
|
export const packLabelFromUrl = (packUrl: string): string => {
|
|
try {
|
|
const parsed = new URL(packUrl);
|
|
const segments = parsed.pathname.split("/").filter(Boolean);
|
|
if (segments.length >= 2) {
|
|
return `${segments[0]}/${segments[1]}`;
|
|
}
|
|
return parsed.host;
|
|
} catch {
|
|
return "Open pack";
|
|
}
|
|
};
|
|
|
|
export const packsHrefFromPackUrl = (packUrl: string): string => {
|
|
const params = new URLSearchParams({ source_url: packUrl });
|
|
return `/skills/packs?${params.toString()}`;
|
|
};
|