RLS policies implementeren, Demo auth flow
This commit is contained in:
@@ -3,13 +3,19 @@
|
||||
*
|
||||
* Loads JSON content files from the content directory structure.
|
||||
* Supports server-side loading with TypeScript type safety.
|
||||
* Also supports loading and parsing markdown files.
|
||||
*
|
||||
* @example
|
||||
* ```ts
|
||||
* const manifesto = await getContent<ManifestoContent>('nl', 'manifesto')
|
||||
* const markdownSections = await getMarkdownContent('docs/manifesto.md')
|
||||
* ```
|
||||
*/
|
||||
|
||||
import { readFile } from 'fs/promises'
|
||||
import { join } from 'path'
|
||||
import { markdownToSections } from './markdown-parser'
|
||||
|
||||
export async function getContent<T>(
|
||||
locale: string = 'nl',
|
||||
file: string
|
||||
@@ -23,6 +29,27 @@ export async function getContent<T>(
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Load and parse markdown file to ManifestoSection format
|
||||
* Useful for converting manifesto.md to React components
|
||||
*/
|
||||
export async function getMarkdownContent(
|
||||
filePath: string
|
||||
): Promise<Array<{
|
||||
id: string
|
||||
type: 'paragraph'
|
||||
content: string
|
||||
}>> {
|
||||
try {
|
||||
const fullPath = join(process.cwd(), filePath)
|
||||
const markdown = await readFile(fullPath, 'utf-8')
|
||||
return markdownToSections(markdown)
|
||||
} catch (error) {
|
||||
console.error(`Failed to load markdown: ${filePath}`, error)
|
||||
throw new Error(`Markdown file not found: ${filePath}`)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Type-safe content loader with fallback
|
||||
*
|
||||
|
||||
62
lib/content/markdown-parser.ts
Normal file
62
lib/content/markdown-parser.ts
Normal file
@@ -0,0 +1,62 @@
|
||||
/**
|
||||
* Markdown Parser Utility
|
||||
*
|
||||
* Simple markdown parser for converting manifesto.md content
|
||||
* to React components with proper typography.
|
||||
*
|
||||
* This is a lightweight parser for basic markdown features:
|
||||
* - Paragraphs
|
||||
* - Line breaks
|
||||
* - Basic formatting (bold, italic)
|
||||
*/
|
||||
|
||||
export interface ParsedMarkdown {
|
||||
paragraphs: string[]
|
||||
metadata?: Record<string, string>
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse markdown content into structured format
|
||||
* Splits content by double line breaks into paragraphs
|
||||
*/
|
||||
export function parseMarkdown(markdown: string): ParsedMarkdown {
|
||||
// Split by double line breaks or single line breaks followed by empty line
|
||||
const paragraphs = markdown
|
||||
.split(/\n\s*\n/)
|
||||
.map((para) => para.trim())
|
||||
.filter((para) => para.length > 0)
|
||||
|
||||
return {
|
||||
paragraphs,
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert markdown paragraphs to ManifestoSection format
|
||||
* This allows markdown content to be used with existing components
|
||||
*/
|
||||
export function markdownToSections(markdown: string): Array<{
|
||||
id: string
|
||||
type: 'paragraph'
|
||||
content: string
|
||||
}> {
|
||||
const parsed = parseMarkdown(markdown)
|
||||
|
||||
return parsed.paragraphs.map((content, index) => ({
|
||||
id: `paragraph-${index + 1}`,
|
||||
type: 'paragraph' as const,
|
||||
content: content.trim(),
|
||||
}))
|
||||
}
|
||||
|
||||
/**
|
||||
* Simple markdown renderer for inline formatting
|
||||
* Converts **bold** and *italic* to HTML
|
||||
*/
|
||||
export function renderMarkdownInline(text: string): string {
|
||||
return text
|
||||
.replace(/\*\*(.+?)\*\*/g, '<strong>$1</strong>')
|
||||
.replace(/\*(.+?)\*/g, '<em>$1</em>')
|
||||
.replace(/`(.+?)`/g, '<code>$1</code>')
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user