GuideModelLoader Class — supabase Architecture
Architecture documentation for the GuideModelLoader class in guideModelLoader.ts from the supabase codebase.
Entity Profile
Relationship Graph
Source Code
apps/docs/resources/guide/guideModelLoader.ts lines 88–223
export class GuideModelLoader {
/**
* Creates a GuideModel instance by loading and processing a markdown file from the filesystem.
*
* @param relPath - Relative path to the markdown file within the guides directory (e.g., "auth/users.mdx")
* @returns A Result containing either the processed GuideModel or an error message
*
* @example
* ```typescript
* const result = await GuideModelLoader.fromFs('auth/users.mdx')
* result.match(
* (guide) => console.log(guide.title, guide.subsections.length),
* (error) => console.error(error)
* )
* ```
*/
static async fromFs(relPath: string): Promise<Result<GuideModel, Error>> {
return Result.tryCatch(
async () => {
// Read the markdown file from the guides directory
const filePath = join(GUIDES_DIRECTORY, relPath)
const fileContent = await fs.readFile(filePath, 'utf-8')
// Parse frontmatter using gray-matter
const { data: metadata, content: rawContent } = matter(fileContent)
// Replace partials and code samples using directives
const processedContent = await preprocessMdxWithDefaults(rawContent)
// Process MDX to get chunked sections for embedding
const { sections } = await processMdx(processedContent)
// Create subsections from the chunked sections
const subsections = sections.map((section) => ({
title: section.heading,
href: section.slug,
content: section.content,
}))
// Extract title from metadata or first heading
const title = metadata.title || sections.find((s) => s.heading)?.heading
// Create href from relative path (remove .mdx extension)
const href = `https://supabase.com/docs/guides/${relPath.replace(/\.mdx?$/, '')}`
return new GuideModel({
title,
href,
content: processedContent,
metadata,
subsections,
})
},
(error) => {
if (error instanceof Error && 'code' in error && error.code === 'ENOENT') {
return new FileNotFoundError('', error)
}
return new Error(
`Failed to load guide from ${relPath}: ${extractMessageFromAnyError(error)}`,
{
cause: error,
}
)
}
)
}
/**
* Loads GuideModels from a list of file paths in parallel, collecting any
* errors without stopping.
*/
private static async loadGuides(
filePaths: Array<string>,
multiError: { current: MultiError | null }
): Promise<Array<GuideModel>> {
const loadPromises = filePaths.map(async (filePath) => {
const relPath = relative(GUIDES_DIRECTORY, filePath)
return this.fromFs(relPath)
})
const results = await Promise.all(loadPromises)
const guides: Array<GuideModel> = []
results.forEach((result, index) => {
const relPath = relative(GUIDES_DIRECTORY, filePaths[index])
result.match(
(guide) => guides.push(guide),
(error) => {
;(multiError.current ??= new MultiError('Failed to load some guides:')).appendError(
`Failed to load ${relPath}: ${extractMessageFromAnyError(error)}`,
error
)
}
)
})
return guides
}
/**
* Loads all guide models from the filesystem by walking the content directory.
*
* This method recursively walks the guides directory (or a specific section
* subdirectory) and loads all non-hidden .mdx files.
*
* If errors occur while loading individual files, they are collected but
* don't prevent other files from loading.
*
* @param section - Optional section name to limit walking to a specific
* subdirectory (e.g., "database", "auth")
* @returns A Both containing [successful GuideModels, MultiError with all
* failures or null if no errors]
*
* @example
* ```typescript
* // Load all guides
* const guides = (await GuideModelLoader.allFromFs()).unwrapLeft()
*
* // Load only database guides
* const dbGuides = (await GuideModelLoader.allFromFs('database')).unwrapLeft()
* ```
*/
static async allFromFs(section?: string): Promise<Both<Array<GuideModel>, MultiError | null>> {
const searchDir = section ? join(GUIDES_DIRECTORY, section) : GUIDES_DIRECTORY
const multiError = { current: null as MultiError | null }
// Get all .mdx files in the search directory
const mdxFiles = await walkMdxFiles(searchDir, multiError)
// Load each file and collect results
const guides = await this.loadGuides(mdxFiles, multiError)
return new Both(guides, multiError.current)
}
}
Domain
Source
Analyze Your Own Codebase
Get architecture documentation, dependency graphs, and domain analysis for your codebase in minutes.
Try Supermodel Free