File size: 1,300 Bytes
aa1ee73
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
import { Project } from "@/types/resume";

const ABSOLUTE_PROTOCOL_REGEX = /^[a-z][a-z\d+\-.]*:/i;
const SAFE_PROTOCOL_REGEX = /^https?:/i;

export const getProjectLinkHref = (link?: string) => {
  const value = link?.trim();
  if (!value) return null;

  if (SAFE_PROTOCOL_REGEX.test(value)) {
    return value;
  }

  if (ABSOLUTE_PROTOCOL_REGEX.test(value)) {
    return null;
  }

  return `https://${value}`;
};

export const getProjectLinkLabel = (
  project: Pick<Project, "link" | "linkLabel">,
  options?: { preferFullUrl?: boolean }
) => {
  const customLabel = project.linkLabel?.trim();
  if (customLabel) return customLabel;

  const originalLink = project.link?.trim();
  if (!originalLink) return "";

  if (options?.preferFullUrl) {
    return originalLink;
  }

  const href = getProjectLinkHref(originalLink);
  if (!href) return originalLink;

  try {
    return new URL(href).hostname.replace(/^www\./, "");
  } catch {
    return originalLink;
  }
};

export const getProjectLinkMeta = (
  project: Pick<Project, "link" | "linkLabel">,
  options?: { preferFullUrl?: boolean }
) => {
  const href = getProjectLinkHref(project.link);
  if (!href) return null;

  return {
    href,
    label: getProjectLinkLabel(project, options),
    title: project.link?.trim() || href,
  };
};