summaryrefslogtreecommitdiff
path: root/app/assets/javascripts/vue_shared/components/source_viewer/plugins/utils/package_json_linker.js
diff options
context:
space:
mode:
Diffstat (limited to 'app/assets/javascripts/vue_shared/components/source_viewer/plugins/utils/package_json_linker.js')
-rw-r--r--app/assets/javascripts/vue_shared/components/source_viewer/plugins/utils/package_json_linker.js46
1 files changed, 46 insertions, 0 deletions
diff --git a/app/assets/javascripts/vue_shared/components/source_viewer/plugins/utils/package_json_linker.js b/app/assets/javascripts/vue_shared/components/source_viewer/plugins/utils/package_json_linker.js
new file mode 100644
index 00000000000..d013d077ba3
--- /dev/null
+++ b/app/assets/javascripts/vue_shared/components/source_viewer/plugins/utils/package_json_linker.js
@@ -0,0 +1,46 @@
+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 href = joinPaths(NPM_URL, packageName);
+ const packageLink = createLink(href, packageName);
+ const versionLink = createLink(href, version);
+ const closeAndOpenTag = `${closeTag}: ${attrOpenTag}`;
+ const dependencyToLink = dependenciesToLink[packageName];
+
+ if (dependencyToLink && dependencyToLink === version) {
+ 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),
+ );
+};