<commit_before>var parseUrlDocs = require('./parseUrlDocs.js');
var cache = {};

module.exports = (server, options) => {
  var attachHALObj = require('./attachHALObj.js')(options);

  var findLink = (method, urlWithoutQuery) => {
    for (var i = 0; i < server.router.routes[method].length; i++) {
      var route = server.router.routes[method][i];
      if (route.path.exec(urlWithoutQuery)) {

        var halObj = {
          // caching is done without the url query part, so we don't put the url in the cache
          // href: options.prefix + url,
          rel: route.name,
          method: method
        };
        // if (route.path.restifyParams) {
        //   halObj.templated = true;
        // }
        parseUrlDocs({
          chain: server.routes[route.name],
          halObj: halObj,
          name: route.name
        });
        return halObj;
      }
    }
  }

  return (halContainer, response) => {

    // this function is given to the developer
    return (method, url, customName) => {
      method = method.toUpperCase();
      var urlWithoutQuery = url.indexOf("?") == -1 ? url : url.substring(0, url.indexOf("?"));
      cache[method] = cache[method] || {};

      if (!cache[method][urlWithoutQuery]) {
        cache[method][urlWithoutQuery] = findLink(method, urlWithoutQuery)
      }

      var result = cache[method][urlWithoutQuery];
      result.href = options.prefix + url;
      if (customName) {
        result.rel = customName;
      }
      attachHALObj(result, halContainer);
    }

  }

}<commit_msg>call no longer fails when developer tries to link a nonexistent resource<commit_after>var parseUrlDocs = require('./parseUrlDocs.js');
var cache = {};

module.exports = (server, options) => {
  var attachHALObj = require('./attachHALObj.js')(options);

  var findLink = (method, urlWithoutQuery) => {
    for (var i = 0; i < server.router.routes[method].length; i++) {
      var route = server.router.routes[method][i];
      if (route.path.exec(urlWithoutQuery)) {

        var halObj = {
          // caching is done without the url query part, so we don't put the url in the cache
          // href: options.prefix + url,
          rel: route.name,
          method: method
        };
        // if (route.path.restifyParams) {
        //   halObj.templated = true;
        // }
        parseUrlDocs({
          chain: server.routes[route.name],
          halObj: halObj,
          name: route.name
        });
        return halObj;
      }
    }
  }

  return (halContainer, response) => {

    // this function is given to the developer
    return (method, url, customName) => {
      method = method.toUpperCase();
      var urlWithoutQuery = url.indexOf("?") == -1 ? url : url.substring(0, url.indexOf("?"));
      cache[method] = cache[method] || {};

      if (!cache[method][urlWithoutQuery]) {
        var cacheEntry = findLink(method, urlWithoutQuery);
        if (cacheEntry) {
          cache[method][urlWithoutQuery] = cacheEntry;
        } else {
          console.error(`addLink.js: no match was found for ${method} ${urlWithoutQuery}`);
          return;
        }
      }

      var result = cache[method][urlWithoutQuery];
      result.href = options.prefix + url;
      if (customName) {
        result.rel = customName;
      }
      attachHALObj(result, halContainer);
    }

  }

}
{'fraction_non_alphanumeric': 0.1373134328358209, 'fraction_numerical': 0.001791044776119403, 'mean_word_length': 2.2345559845559846, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 11, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3125959', 'n_tokens_mistral': 1000, 'n_tokens_neox': 984, 'n_words': 242}