Home / Class/ GuideModelLoader Class — supabase Architecture

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)
  }
}

Analyze Your Own Codebase

Get architecture documentation, dependency graphs, and domain analysis for your codebase in minutes.

Try Supermodel Free