Files
supabase/apps/docs/scripts/search/sources/markdown.ts
T
Charis e46ab9c1a2 refactor: reading markdown docs files (#37774)
* refactor: reading markdown docs files

Refactor how Markdown docs files are read:
- Reuses the same logic across search index generation & page generation
- Improves the indexed content for search:
  - Stops removing MDX components, which often contain useful
    information like Admonitions
  - Denormalizes Partials and CodeSamples for more complete content

This is a prerequisite step for implementing the "Copy docs as Markdown"
functionality.

Only touches regular guides for now, not federated ones.

* fix: tailwind build error (#37728)

We changed to default to ESM imports a while ago, which means local
builds are now breaking because the Tailwind uses a require. Changed to
CJS for Tailwind config file. (I have no idea how this has been working
on Vercel all this time.)

* style: prettier
2025-08-13 11:37:14 -04:00

76 lines
1.9 KiB
TypeScript

import { SubsectionModel } from '../../../resources/guide/guideModel.js'
import { GuideModelLoader } from '../../../resources/guide/guideModelLoader.js'
import { BaseLoader, BaseSource } from './base.js'
export class MarkdownLoader extends BaseLoader {
type = 'markdown' as const
constructor(
source: string,
public filePath: string,
public options?: { yaml?: boolean }
) {
const path = filePath.replace(/^(pages|content)/, '').replace(/\.mdx?$/, '')
super(source, path)
}
async load() {
const guide = (
await GuideModelLoader.fromFs(this.filePath.replace(/^content\/guides/, ''))
).unwrap()
return [
new MarkdownSource(
this.source,
this.path,
guide.content ?? '',
{
checksum: guide.checksum,
meta: guide.metadata,
sections: guide.subsections,
},
this.options
),
]
}
}
export class MarkdownSource extends BaseSource {
type = 'markdown' as const
constructor(
source: string,
path: string,
public contents: string,
{
checksum,
meta,
sections,
}: { checksum?: string; meta?: Record<string, unknown>; sections: Array<SubsectionModel> },
public options?: { yaml?: boolean }
) {
super(source, path)
this.checksum = checksum
this.meta = meta ?? {}
this.sections = sections.map((section) => ({
content: section.content ?? '',
heading: section.title,
slug: section.href,
}))
}
async process() {
return {
checksum: this.checksum ?? '',
meta: this.meta,
sections: this.sections ?? [],
}
}
extractIndexedContent(): string {
const sections = this.sections ?? []
const sectionText = sections.map(({ content }) => content).join('\n\n')
return `# ${this.meta?.title ?? ''}\n\n${this.meta?.subtitle ?? ''}\n\n${sectionText}`
}
}