MCPcopy
hub / github.com/npmx-dev/npmx.dev / linkifyModuleSpecifiers

Function linkifyModuleSpecifiers

server/utils/code-highlight.ts:170–242  ·  view source on GitHub ↗
(html: string, options?: LinkifyOptions)

Source from the content-addressed store, hash-verified

168 * @param options - Dependencies map and optional relative import resolver
169 */
170export function linkifyModuleSpecifiers(html: string, options?: LinkifyOptions): string {
171 const { dependencies, resolveRelative } = options ?? {}
172
173 const getHref = (moduleSpecifier: string): string | null => {
174 const cleanSpec = moduleSpecifier.replace(/^['"]|['"]$/g, '').trim()
175
176 // Try relative import resolution first
177 if (cleanSpec.startsWith('.') && resolveRelative) {
178 return resolveRelative(moduleSpecifier)
179 }
180
181 // Not a relative import - check if it's an npm package
182 if (!isNpmPackage(moduleSpecifier)) {
183 return null
184 }
185
186 const packageName = getPackageName(moduleSpecifier)
187 const dep = dependencies?.[packageName]
188 if (dep) {
189 // Link to code browser with resolved version
190 return `/package-code/${packageName}/v/${dep.version}`
191 }
192 // Fall back to package page if not a known dependency
193 return `/package/${packageName}`
194 }
195
196 // Match: from keyword span followed by string span containing module specifier
197 // Pattern: <span style="...">from</span><span style="..."> 'module'</span>
198 let result = html.replace(
199 /(<span[^>]*> ?from<\/span>)(<span[^>]*>) (['"][^'"]+['"])<\/span>/g,
200 (match, fromSpan, stringSpanOpen, moduleSpecifier) => {
201 const href = getHref(moduleSpecifier)
202 if (!href) return match
203 return `${fromSpan}${stringSpanOpen} <a href="${href}" class="import-link">${moduleSpecifier}</a></span>`
204 },
205 )
206
207 // Match: side-effect imports like `import 'package'`
208 // Pattern: <span>import</span><span> 'module'</span>
209 // But NOT: import ... from, import(, or import {
210 result = result.replace(
211 /(<span[^>]*>import<\/span>)(<span[^>]*>) (['"][^'"]+['"])<\/span>/g,
212 (match, importSpan, stringSpanOpen, moduleSpecifier) => {
213 const href = getHref(moduleSpecifier)
214 if (!href) return match
215 return `${importSpan}${stringSpanOpen} <a href="${href}" class="import-link">${moduleSpecifier}</a></span>`
216 },
217 )
218
219 // Match: require( or import( followed by string
220 // Pattern: <span> require</span><span>(</span><span>'module'</span>
221 // or: <span>import</span><span>(</span><span>'module'</span>
222 // Note: require often has a leading space in the span from Shiki
223 result = result.replace(
224 /(<span[^>]*>)(\s*)(require|import)(<\/span>)(<span[^>]*>\(<\/span>)(<span[^>]*>)(['"][^'"]+['"])<\/span>/g,
225 (
226 match,
227 spanOpen,

Callers 2

highlightCodeFunction · 0.85

Calls 1

getHrefFunction · 0.85

Tested by

no test coverage detected