All files / scripts/lib/docs urlResolver.js

93.75% Statements 30/32
90.62% Branches 29/32
100% Functions 2/2
100% Lines 27/27

Press n or j to go to the next uncovered block, b, p or k for the previous block.

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 59 60 61                      29x 29x 7x 6x 6x 4x 4x       2x 2x 2x 2x 2x     2x   22x 22x 22x 20x 1x   19x 19x 17x 17x       2x                     39x 39x 11x     5x  
/**
 * Converts a docs href to an absolute URL. When no GitHub token is present the
 * function prefers public GitHub Pages or blob URLs over raw.githubusercontent.com,
 * because raw URLs require authentication for private repos and trigger CORS issues
 * in the browser. When a token is available, raw URLs are always safe to use.
 *
 * @param {string} href - Link extracted from a README (may be relative)
 * @param {string} repoName - Repository name used to build absolute URLs
 * @returns {string} Absolute URL suitable for the current environment
 */
function toRawGithub(href, repoName) {
  Iif (!href) return href;
  if (/^https?:\/\//i.test(href)) {
    if (!(process.env.GITHUB_TOKEN || process.env.GH_PROJECTS_TOKEN)) {
      const rawMatch = String(href).match(/^https?:\/\/raw\.githubusercontent\.com\/keglev\/([^/]+)\/(?:main|master)\/(.+)$/i);
      if (rawMatch) {
        const [, repo, rest] = rawMatch;
        return /\.md$/i.test(rest)
          ? `https://github.com/keglev/${repo}/blob/main/${rest}`
          : `https://keglev.github.io/${repo}/${rest}`;
      }
      const blobMatch = String(href).match(/^https?:\/\/github\.com\/keglev\/([^/]+)\/blob\/(?:main|master)\/(.+)$/i);
      Eif (blobMatch) {
        const [, repo, rest] = blobMatch;
        const safe = /^(?:docs\/architecture\/.+\.(?:html|md)|docs\/.+\.(?:html|md)|src\/(?:main\/)?docs\/.+\.(?:html|md))$/i;
        if (safe.test(rest) && !/\.md$/i.test(rest)) return `https://keglev.github.io/${repo}/${rest}`;
      }
    }
    return href;
  }
  let p = String(href).trim().replace(/^<|>$/g, '').replace(/^\.\//, '').replace(/^\//, '');
  p = p.replace(/\.\.\//g, '');
  if (!repoName) return p;
  if (process.env.GITHUB_TOKEN || process.env.GH_PROJECTS_TOKEN) {
    return `https://raw.githubusercontent.com/keglev/${repoName}/main/${p}`;
  }
  const safe = /^(?:docs\/architecture\/.+\.(?:html|md)|docs\/.+\.(?:html|md)|src\/(?:main\/)?docs\/.+\.(?:html|md))$/i;
  if (safe.test(p)) {
    const cleaned = p.replace(/^\/*/, '');
    return /\.md$/i.test(cleaned)
      ? `https://github.com/keglev/${repoName}/blob/main/${cleaned}`
      : `https://keglev.github.io/${repoName}/${cleaned}`;
  }
  return p;
}
 
/**
 * Passes absolute URLs through unchanged; converts relative paths via toRawGithub.
 *
 * @param {string} href - Link to normalize
 * @param {string} repoName - Repository name for building absolute URLs
 * @returns {string} Absolute URL
 */
function normalizeIfRelative(href, repoName) {
  Iif (!href) return href;
  if (/^https?:\/\//i.test(href)) return href;
  return toRawGithub(href, repoName);
}
 
module.exports = { toRawGithub, normalizeIfRelative };