summaryrefslogtreecommitdiff
path: root/app/assets/javascripts/vue_shared/components/source_viewer/plugins/utils/package_json_linker.js
blob: 3c6fc23c138cedb922f37ec5642401fa14b2d775 (plain)
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
import { unescape } from 'lodash';
import { joinPaths } from '~/lib/utils/url_utility';
import { NPM_URL } from '../../constants';
import { createLink, generateHLJSOpenTag } from './dependency_linker_util';

const attrOpenTag = generateHLJSOpenTag('attr');
const stringOpenTag = generateHLJSOpenTag('string');
const closeTag = '&quot;</span>';
const DEPENDENCY_REGEX = new RegExp(
  /*
   * Detects dependencies inside of content that is highlighted by Highlight.js
   * Example: <span class="hljs-attr">&quot;@babel/core&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-string">&quot;^7.18.5&quot;</span>
   * Group 1:  @babel/core
   * Group 2:  ^7.18.5
   */
  `${attrOpenTag}(.*)${closeTag}.*${stringOpenTag}(.*[0-9].*)(${closeTag})`,
  'gm',
);

const handleReplace = (original, packageName, version, dependenciesToLink) => {
  const unescapedPackageName = unescape(packageName);
  const unescapedVersion = unescape(version);
  const href = joinPaths(NPM_URL, unescapedPackageName);
  const packageLink = createLink(href, unescapedPackageName);
  const versionLink = createLink(href, unescapedVersion);
  const closeAndOpenTag = `${closeTag}: ${attrOpenTag}`;
  const dependencyToLink = dependenciesToLink[unescapedPackageName];

  if (dependencyToLink && dependencyToLink === unescapedVersion) {
    return `${attrOpenTag}${packageLink}${closeAndOpenTag}${versionLink}${closeTag}`;
  }

  return original;
};

export default (result, raw) => {
  const { dependencies, devDependencies, peerDependencies, optionalDependencies } = JSON.parse(raw);

  const dependenciesToLink = {
    ...dependencies,
    ...devDependencies,
    ...peerDependencies,
    ...optionalDependencies,
  };

  return result.value.replace(DEPENDENCY_REGEX, (original, packageName, version) =>
    handleReplace(original, packageName, version, dependenciesToLink),
  );
};