Files
posthog.com/gatsby/snippetUtils.ts
Eli Kinsey 8cd20fcc15 Add "Copy as Markdown" button (#11588)
* add copy as markdown button

* remove frontmatter

* add copy as markdown button (#11719)

Co-authored-by: Eli Kinsey <eli@ekinsey.dev>

* resolving snippet imports within snippets (#11797)

* resolving snippet imports within snippets

* idk where this came from

* Update gatsby/snippetUtils.ts

Co-authored-by: Vincent (Wen Yu) Ge <29069505+gewenyu99@users.noreply.github.com>

* remove snippet restriction

---------

Co-authored-by: Eli Kinsey <eli@ekinsey.dev>
Co-authored-by: Vincent (Wen Yu) Ge <29069505+gewenyu99@users.noreply.github.com>

* remove rawBody query

* Hoist recursion logic for clean code that makes uncle bob proud (#11808)

Co-authored-by: Vincent (Wen Yu) Ge <29069505+gewenyu99@users.noreply.github.com>
Co-authored-by: edwinyjlim <edwinyjlim@gmail.com>
Co-authored-by: Eli Kinsey <eli@ekinsey.dev>

---------

Co-authored-by: Vincent (Wen Yu) Ge <29069505+gewenyu99@users.noreply.github.com>
Co-authored-by: Edwin Lim <edwin@posthog.com>
Co-authored-by: edwinyjlim <edwinyjlim@gmail.com>
2025-06-11 11:14:52 -07:00

67 lines
2.4 KiB
TypeScript

import fs from 'fs'
import path from 'path'
type Snippet = {
component: string
path: string
snippet: string | undefined
}
export const resolveSnippets = (body: string, filePath: string, depth: number = 0): string => {
const imports: Snippet[] = resolveSnippetImports(body, filePath)
imports.forEach((snippet) => {
if (snippet && snippet.snippet) {
// Recursively resolve nested imports using the snippet's own file path
const cleanPath = path.resolve(path.dirname(filePath), snippet.path)
const resolvedSnippet = resolveSnippets(snippet.snippet, cleanPath, depth + 1)
snippet.snippet = resolvedSnippet
}
})
return replaceSnippetImports(body, imports)
}
export const resolveSnippetImports = (body: string, filePath: string): Snippet[] => {
const regex = /import\s+(.*?)\s+from\s+['"](.*?\.(md|mdx))['"]/g
const imports: Snippet[] = []
let match
while ((match = regex.exec(body)) !== null) {
const snippetPath = match[2]
const cleanPath = path.resolve(path.dirname(filePath), snippetPath)
if (fs.existsSync(cleanPath)) {
let snippet = fs.readFileSync(cleanPath, 'utf8').trimEnd()
// Recursively resolve nested imports using the snippet's own file path (for relative imports)
const nestedImports = resolveSnippetImports(snippet, cleanPath)
if (nestedImports.length > 0) {
snippet = replaceSnippetImports(snippet, nestedImports)
}
imports.push({
component: match[1],
path: match[2],
snippet,
})
}
}
return imports
}
export const replaceSnippetImports = (body: string, imports: Snippet[]): string => {
let result = body
imports.forEach(({ component, path, snippet }) => {
if (snippet) {
// Replace the component with the snippet
const componentRegex = new RegExp(`<${component}\\s*/>`, 'g')
result = result.replace(componentRegex, snippet)
// Remove the import from the file
const importRegex = new RegExp(
`import\\s+${component}\\s+from\\s+['"]${path.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')}['"]\\s*\\n?`,
'g'
)
result = result.replace(importRegex, '')
}
})
return result
}