All files / services/workflow-service-worker/src/activities resolve-url.js

89.79% Statements 44/49
33.33% Branches 3/9
50% Functions 1/2
89.79% Lines 44/49

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 501x 1x 1x 1x 1x 1x 1x 3x 3x 3x 3x 3x 3x 3x 3x 3x 3x 3x 3x 3x 3x 3x   3x 3x 3x 3x 3x     3x 3x 3x 3x 3x     3x 3x 3x 3x 3x 3x 3x 3x 3x 3x 1x 1x  
/**
 * Resolve URL Activity
 * HEAD preflight to detect redirects, final content-type, and accessibility
 * Returns whether the URL points to a file or a web page
 */
const axios = require("axios");
 
async function resolveUrl({ url }) {
  const FILE_EXTENSIONS = ['.pdf', '.doc', '.docx', '.xls', '.xlsx', '.ppt', '.pptx', '.odt', '.ods'];
 
  let isFileByExtension = FILE_EXTENSIONS.some(ext => url.toLowerCase().endsWith(ext));
  var resolvedUrl = url;
  var resolvedStatus = null;
  var isFile = isFileByExtension;
 
  try {
    const headResp = await axios.head(url, {
      timeout: 10000,
      maxRedirects: 5,
      headers: { 'User-Agent': 'Mozilla/5.0' },
      validateStatus: () => true,
    });

    resolvedUrl = headResp.request?.res?.responseUrl || url;
    resolvedStatus = headResp.status;
    const contentType = (headResp.headers['content-type'] || '').toLowerCase();
 
    if (!isFileByExtension && (contentType.startsWith('application/') || contentType.startsWith('image/'))) {
      isFile = true;
    }
  } catch (e) {
    console.warn(`[resolveUrl] HEAD failed for ${url}: ${e.message}`);
  }
 
  if (url !== resolvedUrl) {
    console.log(`[resolveUrl] Resolved: ${url} → ${resolvedUrl} [${resolvedStatus}]`);
  }
 
  return {
    success: true,
    originalUrl: url,
    resolvedUrl,
    status: resolvedStatus,
    isFile,
    isWeb: !isFile,
  };
}
 
module.exports = { resolveUrl };