All files / scripts/lib/docs extractProductionUrl.js

91.89% Statements 34/37
69.35% Branches 43/62
100% Functions 7/7
93.54% Lines 29/31

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 62 63 64 65 66 67 68 69 70 715x 5x     51x         26x 17x 26x 13x 13x 3x     14x       17x 19x 19x 19x 3x       14x       23x 49x 36x 19x 4x       19x                         29x 29x 29x 61x   61x     23x             5x  
const DEBUG_FETCH = process.env.DEBUG_FETCH === '1' || process.env.DEBUG_FETCH === 'true';
const PROD_PREFIX_RE = /^[•\-*.\s📁📚🏗️🎯🚀📌]*\s*/i;
 
function isProductionLabel(label, paraText) {
  return /^Production\s+URL\b/i.test((label || '').replace(PROD_PREFIX_RE, '').trim())
    || /Production\s+URL\b/i.test(paraText || '');
}
 
function findProductionInParagraph(nn, ctx) {
  const paraText = (nn.children || []).map(c => c.value || '').join(' ').trim();
  for (const ch of (nn.children || [])) {
    if (ch.type !== 'link' || !ch.url) continue;
    const label = (ch.children || []).map(c => c.value || '').join('').trim();
    if (isProductionLabel(label, paraText)) {
      return { title: label || 'Production URL', link: ch.url, description: ctx.strip(paraText) };
    }
  }
  return null;
}
 
function findProductionInList(nn, ctx) {
  for (const li of (nn.children || [])) {
    const flat = ctx.parseReadme.flattenNodeText(li || '').replace(/\r?\n/g, ' ');
    for (const m of flat.matchAll(/\[([^\]]+)\]\(([^)]+)\)/ig)) {
      if (isProductionLabel((m[1] || '').trim(), flat)) {
        return { title: (m[1] || '').trim(), link: (m[2] || '').trim(), description: '' };
      }
    }
  }
  return null;
}
 
function findProductionInText(readmeText) {
  for (const line of readmeText.split(/\r?\n/)) {
    if (/^\s*#{1,6}\s/.test(line)) continue;
    for (const m of line.matchAll(/\[([^\]]+)\]\(([^)]+)\)/ig)) {
      if (isProductionLabel((m[1] || '').trim(), '')) {
        return { title: (m[1] || '').trim(), link: (m[2] || '').trim(), description: '' };
      }
    }
  }
  return null;
}
 
/**
 * Finds a "Production URL" link in the README. Scans AST paragraph and list nodes,
 * then falls back to a line-by-line text scan. Returns the first match or null.
 *
 * @param {object} ast - Parsed README AST
 * @param {string} readmeText - Raw README string (fallback)
 * @param {object} ctx - Shared context: { toRawGithub, parseReadme, strip }
 * @returns {{ title: string, link: string, description: string }|null}
 */
function extractProductionUrl(ast, readmeText, ctx) {
  try {
    Eif (ast && Array.isArray(ast.children)) {
      for (const n of ast.children) {
        const found = n.type === 'paragraph' ? findProductionInParagraph(n, ctx)
          : n.type === 'list' ? findProductionInList(n, ctx) : null;
        if (found) return found;
      }
    }
    return findProductionInText(readmeText);
  } catch (e) {
    if (DEBUG_FETCH) console.log('extractProductionUrl error', e && e.message);
    return null;
  }
}
 
module.exports = { extractProductionUrl };